Metal 2:MetalKit (MTKView) 和 SceneKit 的互操作性
Metal 2: MetalKit (MTKView) and SceneKit interoperability
我正在使用 MetalKit 并且有一个复杂的渲染管道。结果呈现到 MTKView 中。
现在我想将 MTKView 的内容提供给 SCNScene 并使用 SCNCamera 执行 post-处理效果,如 HDR。
这怎么可能?
我不想要一般的方向。如果可能的话,我想要具体的电话。
您应该理想地执行您的 post-process 作为 Metal 渲染管道的一部分。您建议的过程需要不必要的资源,因为您将在 SceneKit 中以 3D 形式渲染 2D 平面只是为了应用一些 HDR 效果。
不过,您可以通过将 Metal 管道输出渲染到纹理然后简单地将其应用到 SceneKit 中的平面来实现您想要的效果。
首先指定你的纹理:
plane.materials.first?.diffuse.contents = offscreenTexture
然后将 SceneKit 渲染覆盖到 Metal 渲染循环:
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
doRender()
}
然后以纹理为目标执行 Metal 渲染,完成后渲染 SceneKit 场景:
func doRender() {
//rendering to a MTLTexture, so the viewport is the size of this texture
let viewport = CGRect(x: 0, y: 0, width: CGFloat(textureSizeX), height: CGFloat(textureSizeY))
//write to offscreenTexture, clear the texture before rendering using green, store the result
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = offscreenTexture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 0, 1.0); //green
renderPassDescriptor.colorAttachments[0].storeAction = .store
let commandBuffer = commandQueue.makeCommandBuffer()
// reuse scene1 and the current point of view
renderer.scene = scene1
renderer.pointOfView = scnView1.pointOfView
renderer.render(atTime: 0, viewport: viewport, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)
commandBuffer.commit()
}`
完整示例项目:
我正在使用 MetalKit 并且有一个复杂的渲染管道。结果呈现到 MTKView 中。
现在我想将 MTKView 的内容提供给 SCNScene 并使用 SCNCamera 执行 post-处理效果,如 HDR。
这怎么可能?
我不想要一般的方向。如果可能的话,我想要具体的电话。
您应该理想地执行您的 post-process 作为 Metal 渲染管道的一部分。您建议的过程需要不必要的资源,因为您将在 SceneKit 中以 3D 形式渲染 2D 平面只是为了应用一些 HDR 效果。
不过,您可以通过将 Metal 管道输出渲染到纹理然后简单地将其应用到 SceneKit 中的平面来实现您想要的效果。
首先指定你的纹理:
plane.materials.first?.diffuse.contents = offscreenTexture
然后将 SceneKit 渲染覆盖到 Metal 渲染循环:
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
doRender()
}
然后以纹理为目标执行 Metal 渲染,完成后渲染 SceneKit 场景:
func doRender() {
//rendering to a MTLTexture, so the viewport is the size of this texture
let viewport = CGRect(x: 0, y: 0, width: CGFloat(textureSizeX), height: CGFloat(textureSizeY))
//write to offscreenTexture, clear the texture before rendering using green, store the result
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = offscreenTexture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 0, 1.0); //green
renderPassDescriptor.colorAttachments[0].storeAction = .store
let commandBuffer = commandQueue.makeCommandBuffer()
// reuse scene1 and the current point of view
renderer.scene = scene1
renderer.pointOfView = scnView1.pointOfView
renderer.render(atTime: 0, viewport: viewport, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)
commandBuffer.commit()
}`
完整示例项目: