首页 > 解决方案 > 为自定义 Scenekit 渲染匹配 ARSCNView 转换?

问题描述

TL:博士

我正在尝试SCNRenderer在 a中渲染一个,MTKView因此我对颜色/深度缓冲区进行了处理-并且我正在尝试匹配ARSCNView通过执行的转换,ARKit因此我的SCNRenderer行为类似于 ARSCNView。

有没有人通过ARFrame/ARCamera和提供的信息匹配 ARSCNViews 世界和面部跟踪配置的示例ARKit- 并适当地修改转换SCNSCamera

更长

由于各种原因(无法访问MTLPassDescriptorfor ARSCNView/SCNView并且有其自身奇怪的限制)SCNTechnique,我正在尝试自己重新实现一些ARSCNViewvia MTKView++ ,这使我可以更好地控制渲染管道。我的代码基于 Apples ARKit + Metal 示例。ARKitSCNRenderer

我想匹配ARKit正在做的事情 - 但是当我尝试使用ARFrame/ARCamera信息来修改我的SCNSceneSCNCamera如下所示时,我的场景会移动,但与相机ARSCNView或带有 Metal 演示的 ARKit 的方式不同.

我不知道从 ARKit 错误地传递到我的场景的内容。

我的场景:

self.sceneKitRenderer = SCNRenderer(device: self.device, options: nil)

self.sceneKitRenderer?.delegate = self as SCNSceneRendererDelegate


let scene = SCNScene()
scene.background.contents = nil

let sphere = SCNSphere(radius: 1.0)
sphere.firstMaterial?.diffuse.contents = UIColor.red
sphere.firstMaterial?.isDoubleSided = true
let sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3(0, 0.0, -5)
scene.rootNode.addChildNode(sphereNode)


let camera = SCNCamera()
let cameraNode = SCNNode()
cameraNode.camera = camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
cameraNode.look(at: scene.rootNode.worldPosition)
scene.rootNode.addChildNode(cameraNode)

self.sceneKitRenderer?.scene = scene
self.sceneKitRenderer?.pointOfView = cameraNode

当我收到更新的 ARFrame 时,我正在更新场景的视点及其投影矩阵,如下所示:

// Match clipping
self.sceneKitRenderer?.pointOfView?.camera?.zNear = 0.001
self.sceneKitRenderer?.pointOfView?.camera?.zFar = 1000

// Match projection
let projection = SCNMatrix4( frame.camera.projectionMatrix(for: .landscapeRight, viewportSize: viewportSize, zNear: 0.001, zFar: 1000))
self.sceneKitRenderer?.pointOfView?.camera?.projectionTransform = projection

// Match transform
self.sceneKitRenderer?.pointOfView?.simdTransform = frame.camera.transform

虽然这似乎有所作为,但它与 ARKits 输出不匹配。

问题:

从相机的翻译中分配simdTransformSCNRenderer's是否正确?pointOfView

我需要对我的场景做些什么来设置正确的坐标系(即根节点比例吗?)

任何指导表示赞赏!

标签: iosswiftscenekitaugmented-realityarkit

解决方案


我做了两件事来让它工作。首先,您需要从 ARKit 的场景中获取相机节点,并使用它来设置相机节点transformprojectionTransform其他场景中的相机:

// get the first node that has a camera attached
if let arkitCameraNode = arkitScene.rootNode.childNodes(passingTest: { (node, stop) -> Bool in
     return node.camera != nil
}).first {
     // SCNNode
     otherSceneCameraNode.transform = arkitCameraNode.transform
     // SCNCamera
     otherSceneCamera.projectionTransform = arkitCameraNode.camera!.projectionTransform
}

在此之后,您需要通过获取相应的ARAnchor变换来同步其他场景中的克隆节点:

if let anchor = arkitSceneView.anchor(for: nodeFromARKitScene) {
     clonedNodeInOtherScene.simdTransform = anchor.transform
}

希望这可以帮助!


推荐阅读