如何在SceneKit中使用SCNBufferBindingBlock?

Chr*_*ris 8 shader scenekit swift metal

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

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

有没有人有一个如何工作的例子?

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

    }
Run Code Online (Sandbox Code Playgroud)

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

ARG*_*Geo 3

.handleBinding(ofBufferNamed:frequency:handler:)方法注册一个块,供 SceneKit 在渲染时调用,以将 Metal 缓冲区绑定到着色器程序。此方法只能与基于 Metal 或 OpenGL 着色语言的程序一起使用。SCNProgram对象有助于执行此自定义渲染。程序对象包含一个顶点着色器和一个片段着色器。使用程序对象完全取代 SceneKit\xe2\x80\x99s 渲染。您的着色器从 SceneKit 获取输入,并负责您想要产生的所有变换、照明和着色效果。使用.handleBinding()方法将块与 Metal 着色器程序关联起来,以处理该着色器中使用的缓冲区的设置。

\n\n
\n

这是有关SCNProgram 类的开发人员文档的链接。

\n
\n\n

此外,您还需要一个实例方法writeBytes(_:count:),将所有必需的数据字节复制到底层 Metal 缓冲区中,以供着色器使用。

\n\n

SCNTechnique专门用于使用自定义 Metal 或 OpenGL 着色器的附加绘图通道对场景进行后处理 SceneKit 渲染的类。使用SCNTechnique它您可以创建颜色分级或位移、运动模糊和渲染环境光遮挡以及其他渲染通道等效果。

\n\n

以下是如何正确使用 .handleBinding() 方法的第一个代码摘录:

\n\n
func useTheseAPIs(shadable: SCNShadable,\n                  bufferStream: SCNBufferStream\n                  voidPtr: UnsafeMutableRawPointer,\n                  bindingBlock: @escaping SCNBindingBlock, \n                  bufferFrequency: SCNBufferFrequency,\n                  bufferBindingBlock: @escaping SCNBufferBindingBlock,\n                  program: SCNProgram) {\n\n    bufferStream.writeBytes(voidPtr, count: 4) \n\n    shadable.handleBinding!(ofSymbol: "symbol", handler: bindingBlock)\n    shadable.handleUnbinding!(ofSymbol: "symbol", handler: bindingBlock)\n\n    program.handleBinding(ofBufferNamed: "pass", \n                          frequency: bufferFrequency,\n                          handler: bufferBindingBlock)\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是第二个代码的摘录:

\n\n
let program = SCNProgram()\nprogram.delegate = self as? SCNProgramDelegate\nprogram.vertexShader = NextLevelGLContextYUVVertexShader\nprogram.fragmentShader = NextLevelGLContextYUVFragmentShader\n\nprogram.setSemantic(\n    SCNGeometrySource.Semantic.vertex.rawValue, \n    forSymbol: NextLevelGLContextAttributeVertex, \n    options: nil)\n\nprogram.setSemantic(\n    SCNGeometrySource.Semantic.texcoord.rawValue, \n    forSymbol: NextLevelGLContextAttributeTextureCoord, \n    options: nil)\n\nif let material = self._material {\n    material.program = program\n\n    material.handleBinding(ofSymbol: NextLevelGLContextUniformTextureSamplerY, handler: { \n        (programId: UInt32, location: UInt32, node: SCNNode?, renderer: SCNRenderer) in\n            glUniform1i(GLint(location), 0);\n    }) \n    material.handleBinding(ofSymbol: NextLevelGLContextUniformTextureSamplerUV, handler: { \n        (programId: UInt32, location: UInt32, node: SCNNode?, renderer: SCNRenderer) in\n            glUniform1i(GLint(location), 1);\n    })\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

另外,请查看在 SceneKit\n SO 帖子中模拟折射。

\n
\n