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 не должны произойти, если вы делите на правильный делитель. Действительно, нет необходимости зажимать вообще.

Другие вопросы по тегам