Explore rendering for spatial computing
Spatial Computing 进阶 20m

探索空间计算的渲染技术

Explore rendering for spatial computing

2023年6月5日

在 Apple 官方观看视频

一句话判断

RealityKit 在空间计算平台上新增了自定义 IBL、Grounding Shadow、ShaderGraphMaterial 和可开关的 Tone Mapping——如果你要做 3D 内容渲染,这些是你控制视觉质量的关键工具。

这场 Session 讲了什么

Session 聚焦 RealityKit 在空间计算平台上的渲染能力,分为四个部分:

1. 光照与阴影

  • Image-Based Lighting(IBL):由 ARKit 提供的环境探针纹理 + 系统 IBL 纹理组合而成。系统 IBL 确保内容在任何环境下都好看。
  • 自定义 IBL:新增 ImageBasedLightComponentImageBasedLightReceiverComponent,可以替换系统 IBL 用自定义环境光照亮 3D 内容。
  • Grounding Shadow:让物体投射阴影到表面和物理环境上,帮助理解物体的空间位置。通过 GroundingShadowComponent 并设置 castsShadow = true 启用。

2. 材质

  • 延续 iOS/macOS 的材质体系:PhysicallyBasedMaterial、SimpleMaterial、UnlitMaterial、VideoMaterial。
  • 新增 ShaderGraphMaterial:在 Reality Composer Pro 中创作或从 MaterialX 文件加载。
  • Tone Mapping:默认启用,将超过 1.0 的颜色值重新映射到可见范围,在高亮区域保留更多细节。
  • 关闭 Tone Mapping:新增 applyPostProcessToneMap 参数,设为 false 可以显示精确颜色——适合需要颜色与 SwiftUI UI 元素精确匹配的场景(如红绿灯 App)。

3. 光栅化率映射(Rasterization Rate Maps)

  • 系统级性能优化,自动调整渲染分辨率。
  • 根据用户注视的区域分配更多渲染资源。
  • 开发者需要理解这个优化存在,确保内容在不同分辨率下都看起来好。

4. 动态内容缩放(Dynamic Content Scaling)

  • 确保 UI 始终清晰锐利的技术。

值得深挖的点

Tone Mapping 的开关场景是一个容易忽略但很重要的选择。默认开启的 Tone Mapping 让材质在高亮区域保留更多细节——适合大多数 3D 场景。但如果你需要让 3D 内容的颜色与 SwiftUI UI 元素精确匹配(比如红绿灯的颜色要和按钮一致),Tone Mapping 会导致微小偏差。通过 applyPostProcessToneMap = false 关闭后,UnlitMaterial 的颜色输出与 SwiftUI 的颜色值完全一致。

Grounding Shadow 的价值在空间计算中比在 2D 屏幕上大得多。在 2D 屏幕上,物体的空间关系由透视和遮挡暗示。在空间计算中,一个浮在空中的 3D 物体如果没有阴影,用户很难判断它离桌面有多远。Grounding Shadow 提供了这个关键的深度线索——它投射在 3D 表面和真实物理环境上。

ShaderGraphMaterial 的引入让 RealityKit 的材质创作能力迈了一个台阶。之前只能通过代码参数控制材质,现在可以在 Reality Composer Pro 中用节点图的方式设计复杂材质。这对设计师和艺术家来说更友好——他们不需要写代码就能创建高级视觉效果。

代码片段

自定义 IBL 光照:

import RealityKit

// 加载 3D 模型和环境资源
let satellite = try await Entity(named: "satellite")
let sunEnvironment = try await EnvironmentResource(
    named: "Sunlight"  // 包含太阳和星空的环境贴图
)

// 创建自定义 IBL 组件
let iblComponent = ImageBasedLightComponent(
    source: sunEnvironment
)

// 将 IBL 应用到实体
satellite.components.set(iblComponent)

// 让其他实体也使用同一个 IBL
let iblReceiver = ImageBasedLightReceiverComponent(
    imageBasedLight: iblComponent
)
satellite.components.set(iblReceiver)

添加 Grounding Shadow:

// 加载模型
let vase = try await Entity(named: "flower_tulip")

// 添加投射阴影组件
var shadowComponent = GroundingShadowComponent()
shadowComponent.castsShadow = true  // 启用阴影投射
vase.components.set(shadowComponent)

// 阴影会投射到 3D 表面和真实物理环境上
// 帮助用户理解物体在空间中的位置

关闭 Tone Mapping 以精确匹配颜色:

// 加载红绿灯模型
let trafficLight = try await Entity(named: "traffic_light")

// 找到红灯实体
let redLight = trafficLight.findEntity(named: "red_light")!

// 获取模型组件
var modelComponent = redLight.components[ModelComponent.self]!

// 创建关闭 Tone Mapping 的 UnlitMaterial
var material = UnlitMaterial(
    color: .red,
    applyPostProcessToneMap: false  // 关键:关闭 tone mapping
)

// 应用材质——现在颜色与 SwiftUI 按钮精确匹配
modelComponent.materials = [material]
redLight.components[ModelComponent.self] = modelComponent

最佳实践

  • 大多数场景使用系统 IBL 就足够了——只在需要特定光照氛围时才自定义 IBL。
  • 放置在表面上的 3D 物体一定要加 Grounding Shadow,否则用户无法判断物体高度。
  • 需要与 SwiftUI UI 颜色精确匹配的 3D 元素,用 UnlitMaterial + 关闭 Tone Mapping。
  • ShaderGraphMaterial 在 Reality Composer Pro 中创作,不要试图纯代码构建复杂材质。
  • 了解光栅化率映射的存在,确保内容在降低分辨率的区域仍然可读。
  • 测试 3D 内容在不同光照环境下的表现——环境探针会影响材质的外观。

还有什么值得关注

  • “Explore Materials in Reality Composer Pro” Session 详细介绍 ShaderGraphMaterial 的创作流程。
  • Tone Mapping 对所有材质类型都默认开启,不只是 UnlitMaterial。
  • 自定义 IBL 的环境资源可以用 HDR 照片或专用工具生成。
  • 空间计算平台的渲染管线针对性能做了大量优化,开发者通常不需要手动管理渲染预算。
  • PhysicallyBasedMaterial 仍然是最常用的材质类型,适合大多数真实世界物体的渲染。
WWDC 2023