ios - 为自定义 Scenekit 渲染匹配 ARSCNView 转换?
问题描述
TL:博士
我正在尝试SCNRenderer
在 a中渲染一个,MTKView
因此我对颜色/深度缓冲区进行了处理-并且我正在尝试匹配ARSCNView
通过执行的转换,ARKit
因此我的SCNRenderer
行为类似于 ARSCNView。
有没有人通过ARFrame
/ARCamera
和提供的信息匹配 ARSCNViews 世界和面部跟踪配置的示例ARKit
- 并适当地修改转换SCNSCamera
?
更长
由于各种原因(无法访问MTLPassDescriptor
for ARSCNView
/SCNView
并且有其自身奇怪的限制)SCNTechnique
,我正在尝试自己重新实现一些ARSCNView
via MTKView
++ ,这使我可以更好地控制渲染管道。我的代码基于 Apples ARKit + Metal 示例。ARKit
SCNRenderer
我想匹配ARKit
正在做的事情 - 但是当我尝试使用ARFrame
/ARCamera
信息来修改我的SCNScene
和SCNCamera
如下所示时,我的场景会移动,但与相机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 输出不匹配。
问题:
从相机的翻译中分配simdTransform
或SCNRenderer
's是否正确?pointOfView
我需要对我的场景做些什么来设置正确的坐标系(即根节点比例吗?)
任何指导表示赞赏!
解决方案
我做了两件事来让它工作。首先,您需要从 ARKit 的场景中获取相机节点,并使用它来设置相机节点transform
和projectionTransform
其他场景中的相机:
// 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
}
希望这可以帮助!
推荐阅读
- amazon-web-services - 如何使用 Terraform 在 AWS SSM 参数中存储三元素元组?
- spring - 获取 RabbitListener 服务监听的队列列表
- wordpress - 翻译 svg 图像的内容
- java - 使用 aws-serverless-java-container 和 Spring Boot 2 时如何提供 zip 文件?
- laravel - 如何配置我的 Laravel 应用程序以通过 DreamHost 网络邮件接收邮件?
- grafana - 选择总 cpu 收集多个主机
- typescript - Stack.Screen 选项上的 Typescript 迁移引发错误
- r - 在 R 中分配数据框时,为什么会出现错误“'closure' 类型的对象不是子集”?
- python - 如何按块播放包含音频信号的numpy数组?
- python - Dockerize Angular 应用程序,它使用 Python 和 Oracle 作为后端