使用 USD 构建 3D 工作流
Create 3D workflows with USD
2021年6月10日
一句话判断
苹果在 USD(Universal Scene Description)生态上持续加注 —— 从 Pixar 开源格式到 AR 体验的标准管道,USD 正在成为苹果 3D 内容的”PDF 格式”,但你得花时间理解它的分层组合架构。
这场 Session 讲了什么
Session 系统讲解了 USD 格式在苹果生态中的定位和工作流。USD(Universal Scene Description)是 Pixar 开发的开源 3D 场景描述格式,苹果从 iOS 12 开始支持 USDZ(USD 的无压缩移动友好子集)用于 AR Quick Look。
这次更新扩展了整个 USD 工具链:新的 Reality Composer 支持 USD 原生导入导出、Xcode 的 USD 工具(usdcat、usdchecker)可以直接在命令行验证和转换 USD 文件、AR Quick Look 对 USDZ 的渲染能力增强(支持动画、自定义材质、音频)。
Session 重点讲解了 USD 的分层(Layering)和组合(Composition)机制 —— 这是 USD 区别于 glTF 等格式的核心能力。多个 USD 文件可以叠加修改,像 Git 一样管理 3D 资产的版本和变体。
值得深挖的点
USD 的分层组合如何降低 3D 资产管理成本。USD 的 composition arc 机制允许你定义一个基础模型(比如一把椅子),然后在不同的 layer 中只存储差异部分(颜色变体、材质变体)。运行时 USD 引擎会自动合并所有 layer。这意味着你不需要为每个产品颜色变体存一个完整的 3D 文件,一个 base + N 个 delta layer 就够了。
USDZ 的限制和优化。USDZ 是 USD 的子集,不支持纹理压缩(只有 PNG/JPEG)、不支持自定义 shader、不支持骨骼动画。如果你的 3D 内容需要这些特性,在 AR Quick Look 中无法使用。但 USDZ 的优势是零依赖 —— 任何苹果设备都能打开,不需要安装查看器。
代码片段
使用 USD 工具验证文件:
# 检查 USD/USDZ 文件是否有效
usdchecker model.usdz
# 查看 USD 文件的结构层级
usdcat model.usdz --flatten
# 转换格式:USD 到 USDZ
usdcat input.usd -o output.usdz
# 提取 USDZ 中的纹理
usdextract model.usdz outputDirectory/
在 Xcode 中创建 USDZ 被引用资产:
import RealityKit
// 加载 USDZ 模型并访问其层级结构
func loadAndInspectUSDZ() {
let url = Bundle.main.url(forResource: "chair", withExtension: "usdz")!
Entity.loadAsync(contentsOf: url)
.sink { completion in
// 处理加载结果
} receiveValue: { rootEntity in
// 遍历 USD 场景图
for child in rootEntity.children {
print("实体名称: \(child.name)")
if let model = child as? ModelEntity {
print("网格数: \(model.model?.mesh.contents.count ?? 0)")
}
}
// 动态替换材质(利用 USD 的分层特性)
if let seat = rootEntity.findEntity(named: "seat") as? ModelEntity {
var newMaterial = SimpleMaterial()
newMaterial.color = .init(tint: .red, texture: nil)
seat.model?.materials = [newMaterial]
}
}
}
RealityKit 中组合多个 USD 层:
import RealityKit
func composeMultiLayerScene() {
// 加载基础场景
let baseScene = try! Entity.loadModel(named: "room_base")
// 加载变体层(不同家具配置)
let variantA = try! Entity.loadModel(named: "room_variant_A")
// 将变体内容添加到基础场景
for child in variantA.children {
baseScene.addChild(child.clone(recursive: true))
}
arView.scene.anchors.append(baseScene)
}
最佳实践
- USDZ 文件大小控制在 10MB 以内。AR Quick Look 通过网络分享时,大文件加载体验很差。使用
usdzip压缩纹理、减少多边形数量(目标 5 万三角面以内)。 - 在 USD 工作流中使用引用(references)而非内联。把可复用的部件(螺丝、按钮)存为独立 USD 文件,主场景通过引用方式组合,修改一个文件所有场景自动更新。
- 用
usdchecker作为 CI/CD 的验证步骤。每次构建时自动检查 USDZ 文件的合法性,避免无效文件上线。
还有什么值得关注
- Reality Composer(macOS 版)现在可以直接编辑 USD 文件,支持添加交互和动画后导出。
USDFiles框架在 macOS 上提供了程序化操作 USD 的 Swift API。- 苹果的 3D 模型库(Reality Composer 对象库)中的所有资产都是 USDZ 格式。