Posts

Post not yet marked as solved
0 Replies
550 Views
In the last few weeks in my spare time I've tried to convert a `CIFilter` with a custom color kernel from a string to a metal written kernel.The purpose of this filter is to pixellate an image and then apply a custom palette of colors. Pixellation is made by CI Pixellate and then I apply this shader.float4 eight_bit_buffer(sampler image, constant simd_float3 palette[], float paletteSize, destination dest) { float4 color = image.sample(image.transform(dest.coord())); float dist = distance(color.rgb, palette[0]); float3 returnColor = palette[0]; for (int i = 1; i < floor(paletteSize); ++i) { float tempDist = distance(color.rgb, palette[i]); if (tempDist < dist) { dist = tempDist; returnColor = palette[i]; } } return float4(returnColor, 1); }The first argument is the image the second is an array of float3 that makes the palette of color.Since iOS13 there was written this in the change note:Metal CIKernel instances support arguments with arbitrarily structured data but I couldn't find any reference in the the documentation or videos.I've tried to do my myself basically trying to create an Data object and pass it to the shader function. At a first try I simply created a Data object and appended SIM3<Double> to it, but it wasn't working so I tought it could be an issue with memory allignment and I came up with this, but it won't work either.func toSIMD3() -> SIMD3<Float> { return [Float(r) / 255.0, Float(g) / 255.0, Float(b) / 255.0] } static func SIMD3Palette(_ palette: [RGB]) -> [SIMD3<Float>] { return palette.map{ $0.toSIMD3() } } static func toSIMD3Buffer(from palette: [RGB]) -> Data { var simd3Palette = SIMD3Palette(palette) let size = MemoryLayout<SIMD3<Float>>.size let count = palette.count let palettePointer = UnsafeMutableRawPointer.allocate( byteCount: count * MemoryLayout<SIMD3<Float>>.stride, alignment: MemoryLayout<SIMD3<Float>>.alignment) let simd3Pointer = simd3Palette.withUnsafeMutableBufferPointer { (buffer) -> UnsafeMutablePointer<SIMD3<Float>> in let p = palettePointer.initializeMemory(as: SIMD3<Float>.self, from: buffer.baseAddress!, count: buffer.count) return p } let data = Data(bytesNoCopy: simd3Pointer, count: count * MemoryLayout<simd3>.stride, deallocator: .free) return data }Have anyone discovered how to pass arbitrarily structured data to a CIKernel?Best,Andrea
Posted
by DrAma.
Last updated
.