设备端 AI 与空间计算为什么重要

把模型放在设备上跑,换来三件事:低延迟、离线可用、数据不出设备。对增强现实来说这几乎是硬要求——摄像头每帧都要推理,若走网络请求,画面延迟立刻就能被用户感知。ARKit 负责理解空间,Core ML 负责理解内容,Vision 把两者串起来。

AR 体验的分水岭不在特效,而在「稳不稳」:追踪抖动、锚点漂移、推理掉帧,任何一项都会让沉浸感瞬间消失。
能力分工
  • ARSession融合摄像头与传感器数据,输出设备位姿与世界锚点。
  • RealityKit渲染虚拟内容,处理遮挡、阴影与光照估计。
  • Vision + Core ML在帧上做检测与分类,把结果回填进 AR 空间。
  • LiDAR提供深度信息,让平面检测与人物遮挡更可靠。
ARKit 与 Core ML 配图:透视空间网格与发光的机器学习节点几何体
网格是空间坐标系,发光节点是模型输出:AR 给位置,ML 给语义。

ARSession 与世界追踪

AR 应用的起点是一段配置正确的会话:调用 ARSession.run 并传入合适的 ARWorldTrackingConfiguration,会话就会持续输出帧(ARFrame)与锚点(ARAnchor)。

世界追踪配置以设备的初始位置为原点建立坐标系,后续所有虚拟物体都挂在这个坐标系下,因此追踪一旦漂移,所有内容都会跟着偏。开启水平与垂直平面检测,能让系统在扫描阶段同时识别地面与墙面;锚点与会话同生命周期,新增锚点时通过 ARSessionDelegate 的回调接收通知,即可据此提示用户「已识别到可用表面」。追踪质量高度依赖环境:光照均匀、纹理丰富、移动平缓时最稳,纯白墙面、镜面地面与快速旋转都会导致追踪降级。调试时打开 ARView.debugOptions = [.showFeaturePoints],能直观看到特征点是否充足。

平面检测与射线拾取

把虚拟物体放到真实桌面上,需要把屏幕上的二维坐标转换到三维空间。射线检测从触点发射一条射线,与已识别的平面或场景几何求交,返回世界坐标与表面法线;有了法线,就能让物体贴合表面朝向摆放,而不是歪斜地插进桌子里。

func handleTap(_ location: CGPoint, in arView: ARView) {
    guard let hit = arView.raycast(from: location,
                                   allowing: .estimatedPlane,
                                   alignment: .horizontal).first else { return }
    let box = ModelEntity(mesh: .generateBox(size: 0.12),
                          materials: [SimpleMaterial(color: .systemBlue)])
    let anchor = AnchorEntity(world: hit.worldTransform)
    anchor.addChild(box)
    arView.scene.addAnchor(anchor)
}

.estimatedPlane 表示「还没完全识别,先按估计平面放置」,视觉上要配合引导动画,等平面真正识别后再吸附到位;.existingPlaneGeometry 只接受已确认的平面,更稳但要求用户多扫一会儿。两种策略按场景选择,室内家具摆放适合前者,需要精确贴合的场景适合后者。

Core ML:把模型跑在设备上

Core ML 接受 .mlpackage 格式的模型,可以直接从主流训练框架导出。模型加载后配合 Vision 的请求对象,就能在摄像头帧上做分类或检测,得到带置信度的结构化结果。整个推理过程在设备上完成,用户画面与数据都不会离开手机。

func classify(_ buffer: CVPixelBuffer, model: MLModel) -> String? {
    guard let mlModel = try? VNCoreMLModel(for: model) else { return nil }
    let request = VNCoreMLRequest(model: mlModel)
    let handler = VNImageRequestHandler(cvPixelBuffer: buffer, orientation: .up)
    try? handler.perform([request])
    let top = (request.results as? [VNClassificationObservation])?.first
    return top.map { "\($0.identifier) \(Int($0.confidence * 100))%" }
}

模型大小直接影响启动时间,请把它放在后台队列加载,并用 MLModelConfiguration 指定计算单元。推理频率也要控制,没必要每帧都跑,隔几帧采样一次通常足够,还能省下可观的电量与发热。

AR 与 ML 的组合场景

把两块能力接起来能做出不少实用的东西:识别货架上的商品并在其上方浮动标签、识别家具类型后按真实尺寸摆放在地面上、或者识别文字并即时翻译贴在原位。它们共同的技术套路是「Vision 给出二维检测框 → 用相机参数反投影到三维空间 → 生成跟随目标的锚点」。

体验设计要点
  • 给引导首次进入先用一句提示告诉用户如何移动设备完成扫描。
  • 给反馈平面识别进度与放置成功都要有即时的视觉反馈。
  • 给退路追踪受限时提示「光线不足,请缓慢移动」,而不是黑屏。