Is iOS metal 3d texture sample method trilinear?

371 Views Asked by At

I am using a color lookup table to create a 3d texture, and use input color to find output color. but I found output color has some interrupt layer. Is this sampler sample 3d texture by using trilinear?

This is my code for creating 3d texture

the lutData is an array of r, g, b, a, r, g, b, a, ....

lutSize is the lookup table size, it's 32 or 64.

func create3DTextureFromLutData(lutData: [Float], lutSize: Int) -> MTLTexture? {
    let desc = MTLTextureDescriptor()
    desc.textureType = .type3D
    desc.pixelFormat = .rgba32Float
    desc.width = lutSize
    desc.height = lutSize
    desc.depth = lutSize
    desc.usage = .shaderRead
     
    guard let texture = _device.makeTexture(descriptor: desc) else { return nil}
     
    texture.replace(region: MTLRegion(origin: .init(x: 0, y: 0, z: 0), size: .init(width: lutSize, height: lutSize, depth: lutSize)), mipmapLevel: 0, slice: 0, withBytes: lutData, bytesPerRow: lutSize * MemoryLayout<Float>.size * 4, bytesPerImage: lutSize * lutSize * MemoryLayout<Float>.size * 4)
     
    return texture
  }

And in my shader, I just want to sample it like this.

constexpr sampler textureSampler = sampler(mag_filter::linear, min_filter::linear, mip_filter::linear, address::clamp_to_edge);
half4 lutWith3dTexture(half4 inputColor, short lutSize, half lutStrength, texture3d<float, access::sample> lut3dTexture, sampler textureSampler) {
  half4 originColor = inputColor;
  float3 coor = float3(((inputColor.rgb * (lutSize - 1)) + 0.5) / lutSize);
  half4 resultColor = half4(lut3dTexture.sample(textureSampler, coor));
   
  return mix(originColor, resultColor, lutStrength);
}

I am trying a different filter::xxxx didn't help anything.

This is a good result, the interpolation is very smooth.

Imgur

And this is the bad result with 3d texture sample.

Imgur

1

There are 1 best solutions below

0
On

In general - yes, trilinear interpolation is supported by Metal on iOS, but only on some pixel formats. Looking at the feature set table you can see filtering is not supported on RGBA32Float (or generally on any Float32 texture). Changing to a RGBA16Float or RGBA8Unorm should solve your issue.