首页 > 解决方案 > 如何在 SceneKit 中使用 SCNBufferBindingBlock?

问题描述

我正在查看带有 SCNBufferBindingBlock 回调的 SceneKit 的句柄绑定方法,如下所述:

https://developer.apple.com/documentation/scenekit/scnbufferbindingblock

有没有人有一个例子说明这是如何工作的?

    let program = SCNProgram()
    program.handleBinding(ofBufferNamed: "", frequency: .perFrame) { (steam, theNode, theShadable, theRenderer) in

    }

对我来说,它读起来就像我可以在 SCNNode 上使用 *.metal 着色器,而不必经历 SCNTechniques 的麻烦......任何接受者?

标签: swiftshaderscenekitmetal

解决方案


只是发布这个以防其他人来这里寻找一个简洁的例子。以下是SCNProgram'shandleBinding()方法如何与Metal一起使用:

.metal首先在着色器文件中定义一个数据结构:

struct MyShaderUniforms {
    float myFloatParam;
    float2 myFloat2Param;
};

然后将此作为参数传递给着色器函数:

fragment half4 myFragmentFunction(MyVertex vertexIn [[stage_in]], 
                                  constant MyShaderUniforms& shaderUniforms [[buffer(0)]]) {
    ...
}

接下来,在Swift文件中定义相同的数据结构:

struct MyShaderUniforms {
    var myFloatParam: Float = 1.0
    var myFloat2Param = simd_float2()
}

现在创建此数据结构的实例,更改其值并定义SCNBufferBindingBlock

var myUniforms = MyShaderUniforms()
myUniforms.myFloatParam = 3.0

...

program.handleBinding(ofBufferNamed: "shaderUniforms", frequency: .perFrame) { (bufferStream, node, shadable, renderer) in
    bufferStream.writeBytes(&myUniforms, count: MemoryLayout<MyShaderUniforms>.stride)
}

这里,传递给的字符串ofBufferNamed:对应于片段函数中的参数名称。然后块的bufferStream属性包含用户定义的数据类型MyShaderUniforms,然后可以使用更新的值写入该数据类型。


推荐阅读