Create 3D models with Object Capture
Augmented Reality 进阶 26m

使用 Object Capture 创建 3D 模型

Create 3D models with Object Capture

2021年6月10日

在 Apple 官方观看视频

一句话判断

Object Capture 是 WWDC 2021 对 AR 生态最有实际价值的新功能 —— 用 iPhone 拍一圈照片就能生成生产级 3D 模型,把建模成本从几千美元降到零,但只支持带 LiDAR 的设备做扫描端。

这场 Session 讲了什么

Object Capture 是一个全新的框架(框架名为 ObjectCapture,属于 RealityKit 生态),让开发者能够通过 iPhone/iPad 的摄像头拍摄真实物体,然后在 Mac 上自动生成高质量的 3D 模型(USDZ 格式)。

工作流程分两阶段:第一阶段是 iOS 端的数据采集,用户围绕物体拍摄多张照片,系统实时提供引导(告诉用户拍够了没有);第二阶段是 Mac 端的重建处理,PhotogrammetrySession API 接收照片序列,通过摄影测量算法生成带纹理的 3D 网格。

Session 展示了从拍摄到最终 AR 展示的完整流程,并详细讲解了如何优化拍摄质量以获得最佳重建结果。

值得深挖的点

拍摄引导的质量直接影响模型质量。Object Capture 在 iOS 端提供 ObjectCaptureSession,它通过 ARKit 的平面检测和 LiDAR 深度数据来引导用户围绕物体拍摄。系统会提示”需要更多角度”、“请靠近物体”等指导。如果跳过引导直接用相册照片,重建质量会显著下降 —— 因为系统需要传感器数据来估算相机位姿。

Mac 端的三种输出质量PhotogrammetrySession 提供 reconstruct 方法,支持 preview(快速预览,几分钟)、medium(中等质量,适合 Web 展示)、high(高质量,适合 AR/3D 打印)三种输出。高质量模式下,一个中等大小的物体(如鞋子)大约需要 20-30 分钟处理时间。输出格式支持 USDZ,直接兼容 RealityKit 和 AR Quick Look。

代码片段

iOS 端扫描引导

import ObjectCapture

func startScanningSession() {
    let session = ObjectCaptureSession()
    // 配置扫描参数
    let config = ObjectCaptureSession.Configuration()
    config.checkpointDirectory = getDocumentsDirectory()
    // 开始扫描
    session.start(config)
    // 监听扫描状态
    session.stateChangedHandler = { state in
        switch state {
        case .initializing:
            print("正在初始化,请对准物体")
        case .capturing:
            print("正在采集,请围绕物体移动")
        case .finishing:
            print("采集即将完成")
        case .completed:
            print("采集完成,可以开始重建")
        default:
            break
        }
    }
}

Mac 端 3D 重建

import RealityKit
import Photogrammetry  // macOS 专用

func reconstructModel(from imagesFolder: URL) {
    // 创建摄影测量会话
    let session = try! PhotogrammetrySession(
        input: imagesFolder,
        configuration: PhotogrammetrySession.Configuration()
    )
    // 请求高质量重建
    let outputURL = getOutputDirectory().appendingPathComponent("model.usdz")
    try! session.process(requests: [
        .modelFile(url: outputURL, detail: .high)
    ])
    // 监听进度
    session.output.sink { output in
        switch output {
        case .processingComplete:
            print("3D 模型重建完成: \(outputURL)")
        case .inputProcessingComplete:
            print("输入图片处理完成,开始重建...")
        case .requestProgress(let request, let fraction):
            print("重建进度: \(Int(fraction * 100))%")
        default:
            break
        }
    }
}

在 AR 场景中加载重建模型

import RealityKit

func loadCapturedModel() {
    let modelURL = getOutputDirectory().appendingPathComponent("model.usdz")
    // 异步加载 USDZ 模型
    ModelEntity.loadModelAsync(contentsOf: modelURL)
        .sink { completion in
            if case .failure(let error) = completion {
                print("加载失败: \(error)")
            }
        } receiveValue: { modelEntity in
            // 放置到 AR 场景中
            modelEntity.scale = SIMD3<Float>(repeating: 0.3)
            self.arView.scene.anchors[0].addChild(modelEntity)
        }
}

最佳实践

  1. 拍摄时保证光照均匀、避免强烈阴影和高光。反光表面(如玻璃、金属)和透明物体会严重干扰重建,必要时喷消光喷雾。
  2. 拍摄角度要完整覆盖物体顶部和底部。很多人只拍侧面,导致底部缺失。Object Capture 的引导会提醒你,但最终还是要靠拍摄者的耐心。
  3. 先用 preview 质量验证重建是否成功,再用 high 正式输出。preview 只需几分钟,如果 preview 模型有明显问题,说明输入照片质量不够,重新拍摄比等 30 分钟出废品划算。

还有什么值得关注

  • Object Capture 的 Mac 端需要 Apple silicon(M1 或以上)才能获得合理速度。
  • 生成的 USDZ 模型可以在 AR Quick Look 中直接预览,不需要额外处理。
  • 苹果推荐最少拍摄 20 张照片,但实际效果好的重建通常需要 50-100 张。
WWDC 2021