You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何设置SCNNode.look后ARSCNFaceGeometry节点会不可见?

问题分析与解决方案

首先,你遇到的问题核心在于**look(at:)方法会破坏ARSCNFaceGeometry原本的姿态绑定**,导致面部网格被旋转到相机无法正常捕捉的角度。

为什么调用look(at:)后模型几乎不可见?

ARSCNFaceGeometry是专门为ARFaceTracking设计的,它的默认坐标系和ARFaceAnchor的姿态完全匹配:面部网格的正面默认朝向相机(也就是用户的方向),而ARFaceAnchor的transform属性已经包含了头部所有的旋转、位移信息。

当你调用maskNode?.look(at:)时,这个方法会强制将节点的**-Z轴指向目标点**,相当于完全覆盖了ARFaceAnchor原本给面部网格设定的姿态。比如用户头部左右转动时,lookAtPoint的位置变化会让maskNode的朝向被强行扭转,导致面部网格的背面朝向相机,自然只能看到鼻子、脸颊这类边缘部位。

正确的实现方式:利用ARFaceAnchor的Transform

你不需要手动调用look(at:)来实现头部跟随,ARFaceAnchor已经帮你处理好了所有姿态信息。只需要在更新面部几何的同时,将maskNode的transform与faceAnchor的transform绑定即可:

修改后的完整代码:

class ViewController: UIViewController, ARSessionDelegate {
    let session = ARSession()
    var maskNode: SCNNode?
    var sceneView = SCNView(frame: UIScreen.main.bounds)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(sceneView)
        self.sceneView.backgroundColor = .clear
        self.sceneView.scene = SCNScene()
        self.sceneView.rendersContinuously = true
        
        if let device = MTLCreateSystemDefaultDevice(), let geo = ARSCNFaceGeometry(device: device) {
            self.maskNode = SCNNode(geometry: geo)
            self.maskNode?.geometry?.firstMaterial?.fillMode = .lines
            // 移除初始的look(at:)调用
            self.maskNode?.position = SCNVector3(x: 0.0, y: 0.0, z: 0.0)
            self.sceneView.scene?.rootNode.addChildNode(self.maskNode!)
        }
        
        let config = ARFaceTrackingConfiguration()
        session.delegate = self
        session.run(config, options: [])
    }
    
    var currentFaceAnchor: ARFaceAnchor?
    
    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
        guard let faceAnchor = anchors.first as? ARFaceAnchor else { return }
        self.currentFaceAnchor = faceAnchor
        let faceGeometry = self.maskNode?.geometry as! ARSCNFaceGeometry
        faceGeometry.update(from: faceAnchor.geometry)
        // 替换look(at:)为绑定faceAnchor的transform
        self.maskNode?.transform = SCNMatrix4(faceAnchor.transform)
    }
}

额外说明

  • ARFaceAnchor的transform包含了头部的位置、旋转、缩放所有姿态数据,绑定后面部网格会完全跟随头部的所有动作(左右转动、上下抬头、前后移动)。
  • 如果之后需要调整面部网格的偏移(比如稍微上移一点),可以在maskNode下添加一个子节点,把面部网格放在子节点里,然后调整子节点的position,这样不会破坏主节点的transform绑定。

内容的提问来源于stack exchange,提问作者Roan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:37:23