MTLTexture из выпуска MTLBuffer
У меня есть результаты вычислений шейдеров, хранящихся в MTLBuffer. Каждый элемент MTLBuffer - это UInt16. Я пытаюсь передать результаты фрагментному шейдеру, который отображает результат, интерпретируя элементы MTLBuffer как интенсивность цвета от 0 до 255. Я создаю MTLTexture из этого MTLBuffer, используя следующий код, и передаю текстуру в шейдер. Но я думаю, что что-то не так в процессе, поскольку вывод не является правильным. Я не уверен, что это проблема формата пикселей и / или преобразования формата.
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 до 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
<= 0.0, 0.0 будет между luma
и 1.0 и будут возвращены без изменений. Если 0.0 < luma
<= 1.0, то 0.0 ниже диапазона, поэтому clamp()
вернет нижнюю границу диапазона, который luma
, Проблема возникает, если luma
> 1.0. В этом случае результаты clamp()
не определены, согласно документации.
Теперь значения больше 1,0 не должны произойти, если вы делите на правильный делитель. Действительно, нет необходимости зажимать вообще.