1

我将计算着色器的结果存储在 MTLBuffer 中。MTLBuffer 的每个元素都是一个 UInt16。我试图将结果传递给片段着色器,该着色器通过将 MTLBuffer 的元素解释为 0 到 255 之间的颜色强度来显示结果。我使用以下代码从这个 MTLBuffer 创建一个 MTLTexture 并将纹理传递给着色器。但我认为在这个过程中有些地方是不正确的,因为输出不正确。我不确定这是否是像素格式和/或格式转换的问题。

    let textureDescriptor = MTLTextureDescriptor()
    textureDescriptor.textureType = .type2D
    textureDescriptor.pixelFormat = .r16Uint
    textureDescriptor.width = bufferWidth
    textureDescriptor.height = 256
    textureDescriptor.usage = [.shaderRead, .shaderWrite]


    let texture = buffer?.makeTexture(descriptor: textureDescriptor, offset: 0, bytesPerRow: bufferWidth*MemoryLayout<UInt16>.stride)

这是片段着色器代码,

   fragment half4 fragmentShaderDisplay (MappedVertex in [[ stage_in ]],
                                              texture2d<ushort, access::sample> lumaTexture  [[ texture(0) ]]
                                              )
{
    constexpr sampler s(t_address::clamp_to_edge, r_address::clamp_to_edge, min_filter::linear, mag_filter::linear);

    float luma = lumaTexture.sample(s, in.textureCoordinate).r/255.0;

    luma = clamp(0.0, luma, 1.0);

   return half4(luma, luma, luma, 1.h);
}
4

1 回答 1

1

您想在什么意义上将缓冲区值解释为 0 到 255 之间?它们的固有范围是 0 到 65535,浮点组件的范围通常是 0.0 到 1.0。这些都不是 0 到 255。

如果你简单地除以 65535.0 而不是 255.0,你会得到你想要的,一个介于 0.0 和 1.0 之间的值。

此外,您的呼叫clamp()似乎是错误的。鉴于您编写的参数的顺序,您将常数值 0.0 限制在luma1.0 和 1.0 之间。我认为您希望将其限制luma在 0.0 和 1.0 之间。

碰巧的是,你写东西的方式大多会奏效。如果luma是 <= 0.0,0.0 将介于luma和 1.0 之间,并且将不加修改地返回。如果 0.0 < luma<= 1.0,则 0.0 低于范围,因此clamp()将返回范围的下限,即luma. 如果luma> 1.0,问题就来了。在这种情况下,clamp()根据文档,结果是未定义的。

现在,如果您除以适当的除数,则不应出现大于 1.0 的值。确实,根本不需要夹。

于 2018-05-13T21:31:07.210 回答