0

我正在使用颜色查找表来创建 3d 纹理,并使用输入颜色来查找输出颜色。但我发现输出颜色有一些中断层。这个采样器是否使用三线性采样 3d 纹理?

这是我创建 3d 纹理的代码

lutData是一个由 r、g、b、a、r、g、b、a、...组成的数组。

lutSize是查找表的大小,它是 32 或 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
  }

在我的着色器中,我只想像这样对其进行采样。

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);
}

我正在尝试不同的 filter::xxxx 没有任何帮助。

这是一个很好的结果,插值非常平滑。

伊姆古尔

这是 3d 纹理样本的不良结果。

伊姆古尔

4

1 回答 1

1

一般来说 - 是的,iOS 上的 Metal 支持三线性插值,但仅限于某些像素格式。查看功能集表,您可以看到 RGBA32Float(或通常在任何 Float32 纹理上)不支持过滤。更改为 RGBA16Float 或 RGBA8Unorm 应该可以解决您的问题。

于 2021-05-06T14:54:37.167 回答