0

色の値を配列としてシェーダーに渡す必要があります。今、私はそれを構造体 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 / 3C++ の float データ型は 4 バイトですが、simd の float3 は 16 バイトであるため、コードに値 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。誰かが私に提案できますか?

編集:

float3 から MTLBuffer を作成する方法に関する解決策を見つけました。コードは次のとおりです。

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)
}

このコードは完全に正常に動作します。しかし、コードでは、コードを機能させるには長さを2let bufferCreated = device.makeBuffer(length: MemoryLayout.size(ofValue: valueBuffer[0]) * 2 * valueBuffer.count , options: [])倍にする必要があることがわかります。

なぜそれを機能させるために乗数が必要なのですか? 私はこれを理解していません。誰かが私に提案できますか?

4

0 に答える 0