来自MTLBuffer问题的MTLTexture

时间:2018-05-13 19:35:38

标签: ios fragment-shader metal metalkit mtlbuffer

我有计算着色器的结果存储在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);
}

1 个答案:

答案 0 :(得分:1)

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

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

此外,您对clamp()的来电似乎有误。根据您编写的参数顺序,您将常数值0.0钳位在luma和1.0之间。我想你想把luma钳在0.0到1.0之间。

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

现在,如果你除以适当的除数,那么大于1.0的值就不会发生。实际上,根本不需要钳制。