Метод .handleBinding(ofBufferNamed:frequency:handler:)
регистрирует блок для вызова SceneKit во время рендеринга для привязки металлического буфера к шейдерной программе. Этот метод может использоваться только с программами на основе языка затенения Metal или OpenGL. SCNProgram
объект помогает выполнить этот пользовательский рендеринг. Программный объект содержит вершинный шейдер и фрагментный шейдер. Использование программного объекта полностью заменяет рендеринг SceneKit. Ваши шейдеры получают информацию от SceneKit и отвечают за все эффекты преобразования, освещения и затенения, которые вы хотите создать. Используйте метод .handleBinding()
, чтобы связать блок с программой Metal shader для обработки настройки буфера, используемого в этом шейдере.
Вот ссылка на Документация разработчика в классе SCNProgram.
Также вам нужен метод экземпляра writeBytes(_:count:)
, который копирует все необходимые байты данных в базовый буфер Metal для использования шейдером.
SCNTechnique
класс, специально созданный для пост-обработки рендеринга сцены SceneKit с использованием дополнительных проходов рисования с помощью пользовательских шейдеров Metal или OpenGL. Используя SCNTechnique
, вы можете создавать такие эффекты, как градация цвета или смещение, размытие движения и визуализация окклюзии окружающей среды, а также другие проходы рендеринга.
Вот первая выдержка из кода, как правильно использовать метод .handleBinding ():
func useTheseAPIs(shadable: SCNShadable,
bufferStream: SCNBufferStream
voidPtr: UnsafeMutableRawPointer,
bindingBlock: @escaping SCNBindingBlock,
bufferFrequency: SCNBufferFrequency,
bufferBindingBlock: @escaping SCNBufferBindingBlock,
program: SCNProgram) {
bufferStream.writeBytes(voidPtr, count: 4)
shadable.handleBinding!(ofSymbol: "symbol", handler: bindingBlock)
shadable.handleUnbinding!(ofSymbol: "symbol", handler: bindingBlock)
program.handleBinding(ofBufferNamed: "pass",
frequency: bufferFrequency,
handler: bufferBindingBlock)
}
А вот вторая выдержка из кода:
let program = SCNProgram()
program.delegate = self as? SCNProgramDelegate
program.vertexShader = NextLevelGLContextYUVVertexShader
program.fragmentShader = NextLevelGLContextYUVFragmentShader
program.setSemantic(
SCNGeometrySource.Semantic.vertex.rawValue,
forSymbol: NextLevelGLContextAttributeVertex,
options: nil)
program.setSemantic(
SCNGeometrySource.Semantic.texcoord.rawValue,
forSymbol: NextLevelGLContextAttributeTextureCoord,
options: nil)
if let material = self._material {
material.program = program
material.handleBinding(ofSymbol: NextLevelGLContextUniformTextureSamplerY, handler: {
(programId: UInt32, location: UInt32, node: SCNNode?, renderer: SCNRenderer) in
glUniform1i(GLint(location), 0);
})
material.handleBinding(ofSymbol: NextLevelGLContextUniformTextureSamplerUV, handler: {
(programId: UInt32, location: UInt32, node: SCNNode?, renderer: SCNRenderer) in
glUniform1i(GLint(location), 1);
})
}
Также посмотрите на Имитация рефракции в SceneKit.
ТАК сообщение.