Как передать массив значений float3 из CPU в GPU в Metal?

У меня есть требование передать значения цвета в шейдер в виде массива. Прямо сейчас я передаю его как структуру RGBColors и получаю как структуру, и она работает нормально.

Но я хочу получить его как значение float3 в шейдере. Но как только я изменяю его на float3, он ведет себя странно и начинает мерцать, он не дает мне правильного цвета.

Вот код, который я использовал для установки буфера фрагмента,

func setFragmentBuffer(_ values: [Float], at index: Int) {
     let bufferValues = values
     let datasize = 16 * values.count / 3

     let colorBuffer = device.makeBuffer(bytes: bufferValues, length: datasize, options: [])
     renderEncoder.setFragmentBuffer(colorBuffer, offset: 0, at: index)
}

Вот структура для RGBColors

struct RGBColors {
    var r: Float
    var g: Float
    var b: Float

    func floatBuffers() -> [Float] {
        return [r,g,b]
    }
}

Из этой структуры я создам массив Float значения и установите его для буфера фрагмента.

Код let datasize = 16 * values.count / 3 Я дал значение 16, потому что хотя тип данных с плавающей точкой в ​​C++ составляет 4 байта, float3 в simd составляет 16 байтов.

И в шейдере я реализую метод

fragment float4
singleShader(RasterizerData in [[stage_in]],
                   texture2d<half> sourceTexture [[ texture(0) ]],
                   const device float3 &rgbColor [[ buffer(1) ]]
{
    constexpr sampler textureSampler (mag_filter::linear,
                                      min_filter::linear);

    // Sample the texture and return the color to colorSample
    const half4 colorSample = sourceTexture.sample (textureSampler, in.textureCoordinate);

    float4 outputColor;


    float red = colorSample.r * rgbColor.r;
    float green = colorSample.g * rgbColor.g;
    float blue =  colorSample.b * rgbColor.b;

    outputColor = float4(red, green,blue, colorSample.a);
    outputColor = float4((outputColor.rgb * param1 + param2) / 4, colorSample.a);
    return outputColor;
}

Наконец я не получаю правильный цвет на выходе.

Как соответствовать float3 simd тип данных для swift Float тип данных. Может ли кто-нибудь предложить мне?

Редактировать:

Я нашел решение о том, как создать MTLBuffer из float3, и вот код:

func setFragmentBuffer(_ values: [float3], at index: Int) {
    var valueBuffer = values

    let bufferCreated = device.makeBuffer(length: MemoryLayout.size(ofValue: valueBuffer[0]) * 2 * valueBuffer.count , options: [])
    let bufferPointer = bufferCreated.contents()

    memcpy(bufferPointer, &valueBuffer, 16 * valueBuffer.count)
    renderEncoder.setFragmentBuffer(bufferCreated, offset: 0, at: index)
}

Этот код работает отлично. Но все еще в коде let bufferCreated = device.makeBuffer(length: MemoryLayout.size(ofValue: valueBuffer[0]) * 2 * valueBuffer.count , options: []) Вы можете видеть, что длина должна быть умножена на коэффициент 2, чтобы код работал.

Зачем нужен множитель, чтобы он работал? Я не понимаю этого. Может ли кто-нибудь предложить мне?

0 ответов

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