WWDC Quick Look 💓 By SwiftGGTeam
Optimize your 3D assets for spatial computing

Optimize your 3D assets for spatial computing

观看原视频

Highlight

Apple Vision Pro 上 GPU 只负责你实际渲染的像素,不负责透视视频(passthrough video)。GPU 工作负载随 app 在用户视野中的面积缩放——沉浸式场景每帧多渲染数百万像素,共享空间的应用则快得多。


核心内容

做一个 Apple Vision Pro 的 3D 场景,打开 Blender 建完模型,导出 USD,拖进 Reality Composer Pro——资产旋转了、材质没了、纹理没压缩。这些「小问题」每一个都会拖慢你的迭代速度,而 Apple Vision Pro 的性能预算比传统平台更紧。

Apple 的方案是给出一套端到端的优化工作流:从建模阶段控制多边形数量,到导出时处理坐标系统,再到纹理打包和材质选择,最后到 sky dome 和 IBL 的配置。每一步都有具体的数值指标可以参考——沉浸式场景不超过 50 万三角形,共享空间不超过 25 万,同时可见三角形控制在 10 万左右就有充足的性能余量。

这套工作流的核心逻辑是:Apple Vision Pro 的 GPU 只渲染 app 自身的像素,透视视频由另一条管线处理。所以你的 app 在视野中占的面积直接决定了 GPU 负载。沉浸式 app 占满全屏,每帧渲染数百万像素;共享空间的小窗口,负载就低得多。理解了这一点,你就知道为什么三角形预算、纹理压缩、材质选择这些优化在空间计算平台上格外重要。

详细内容

多边形预算与场景分割

Apple 给出了明确的三档指标:沉浸式场景 50 万三角形,共享空间 25 万,同时可见三角形 10 万。大型物体(如地形)应该分块处理,离屏时引擎可以整块剔除。一个实用技巧是在场景中放置一个 1.5 米高的相机,用来预判用户视角下物体的大小比例(03:44)。

USD 格式选择与坐标系统

USD 有三种格式:USDA(纯文本,适合协作和版本管理)、USDC(二进制,适合存储几何体)、USDZ(打包格式,适合分发)。RealityKit 使用 Y 轴向上、-Z 轴向前的坐标系统,Blender 则是 Z 轴向上、Y 轴向前,导出时需要对 X 轴做 -90 度旋转修正(05:38)。RealityKit 使用米作为单位,其他工具如果单位不同也会导致缩放问题。

色彩空间:传递函数 vs 色域

Reality Composer Pro 中色彩空间用两个词表示,如 sRGB - Display P3。第一项是传递函数:sRGB 用于感知类纹理(基色、自发光),Linear 用于数据类或 HDR 纹理。第二项是色域:Vision Pro 原生使用 Display P3,其他色域的纹理在 Xcode 构建时自动转换(07:05)。

纹理打包(Texture Packing)

灰度纹理(roughness、metallic、ambient occlusion)单独使用时不会压缩,构建后的 app 体积更大。解决方案是把三个灰度纹理分别放进一张 RGB 图像的 R、G、B 通道。打包后这张 RGB 纹理会被压缩,整个 PBR 资产体积最多减少 40%(09:02)。

在 Shader Graph 中,打包纹理的节点类型要选 vector3,这样 shader 知道这是数据纹理,不会做色彩空间转换。然后用 Separate3 节点把 RGB 拆回独立通道:

// Shader Graph 节点连接逻辑(非代码,描述连接关系)
PackedTexture(vector3) -> Separate3
  .r -> Roughness
  .g -> Metallic
  .b -> Ambient Occlusion
  • vector3 类型确保不触发色彩空间转换
  • Separate3 将 RGB 三通道拆分为独立 float 输出
  • 每个通道分别连接到 PBR 材质对应的输入

法线贴图的格式与范围

RealityKit 使用 OpenGL 格式的法线贴图,DirectX 格式的绿通道是反的。此外,图像存储的值范围是 0-1,但材质期望 -1 到 1。需要做 value * 2 - 1 的范围映射。Shader Graph 提供了 Normal Map Decode 节点一步完成这个转换(10:58)。注意 NormalMap 节点不做范围转换,和 Blender 同名节点行为不同。

Material Instances 复用材质

在 Shader Graph 中把文件引用 Promote to Input 后,可以右键材质选 Create Instance,实例可以替换纹理但共享底层 shader graph。引擎不需要加载重复的 shader,既省时间又省性能(11:24)。

Unlit 材质 + 烘焙 vs 动态光照

实时灯光在 RealityKit 中有性能开销,Apple 建议尽量烘焙。示例场景全部使用 Unlit 材质,每个资产只有一张烘焙纹理。纹理分辨率根据距离缩放——超过一半的纹理分辨率分配给了用户周围 5-10 米的区域(13:54)。

透明材质的代价

透明材质触发 overdraw,GPU 对同一像素需要多次计算。建议用几何体替代透明纹理——示例中的草叶用的是实际几何体而非透明贴图,灌木则用不透明核心加少量透明卡片边缘。用更多三角形换更少透明像素,在三角形预算内几乎总是值得的(15:03)。

Sky Dome 与 IBL 配置

Sky dome 用大尺寸低动态范围纹理(建议 8K 水平分辨率)+ Unlit 材质,裁剪掉用户看不到的部分。IBL 用小尺寸 HDR 纹理(Lat/Long 格式),没有镜面反射的场景 512px 就够。要让 IBL 生效,需要在场景中添加 Image Based Light 组件和 Image Based Light Receiver 组件,并建立引用关系(16:29)。

EnvironmentRadiance 节点

介于 Unlit 和 PBR 之间的选择:用 EnvironmentRadiance 节点在 Unlit 材质中获取 IBL 的高光反射,性能比完整 PBR 低,但比纯 Unlit 多了视角相关的金属反射效果(18:42)。

核心启发

  1. 纹理打包工具:自动扫描项目中的灰度纹理,按 R/G/B 通道打包为单张图像,并生成对应的 Shader Graph 节点配置。为什么值得做:手动打包容易出错(通道错位、色彩空间选错),自动化后每个 PBR 资产体积最多减 40%。怎么开始:写一个脚本遍历 Reality Composer Pro 项目中的纹理文件,识别同名资产下的 roughness/metallic/ao 三件套,用 ImageMagick 合成,输出 vector3 类型的打包纹理。

  2. 场景多边形预算看板:在 Reality Composer Pro 的 Statistics Panel 基础上,做一个实时显示当前场景三角形占比的工具,当接近 10 万可见三角形阈值时发出警告。为什么值得做:Apple 给出了明确的三角形预算,但没有自动化的预算监控,很多团队直到性能出问题才回头优化。怎么开始:解析 Reality Composer Pro 导出的 USDA 场景文件,统计每个 entity 的三角形数和包围盒,计算可见三角形估算值,输出 HTML 报告。

  3. 法线贴图自动修正管线:检测法线贴图是 OpenGL 还是 DirectX 格式,自动翻转绿通道;检测值范围是否为 0-1,自动插入 Normal Map Decode 节点。为什么值得做:法线贴图格式和范围问题是最常见的视觉 bug 之一,手动排查耗时。怎么开始:在资产导入环节加一步脚本,分析法线贴图绿通道方向和像素值范围,标记需要修正的贴图并生成修复建议。

关联 Session

评论

GitHub Issues · utterances