我将计算着色器的结果存储在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);
}
最佳答案
您想从什么意义上将缓冲区值解释为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
luma和1.0之间,并且将不做任何修改就返回。如果0.0 <luma
clamp()将返回范围的下限,即luma
。如果luma
> 1.0,就会出现问题。在这种情况下,根据文档,clamp()
的结果是不确定的。
现在,如果要除以适当的除数,则不应出现大于1.0的值。确实,根本不需要夹紧。