Explore advanced rendering with RealityKit 2
Augmented Reality 高级 22m

探索 RealityKit 2 的高级渲染

Explore advanced rendering with RealityKit 2

2021年6月10日

在 Apple 官方观看视频

一句话判断

如果你想在 AR 里做出接近游戏引擎级别的视觉效果,这集是必看内容 —— 但前提是你得会写 Metal shader,RealityKit 2 没打算给你拖拽式编辑器。

这场 Session 讲了什么

这集是 RealityKit 2 渲染能力的深入讲解,聚焦在 Custom Material 的底层机制和高级渲染技术。Session 从渲染管线出发,解释了 RealityKit 如何处理光照、阴影、环境反射,然后展示了如何通过 Custom Material 在各个环节插入自定义逻辑。

内容涵盖了:Surface Shader 的编写规范、Geometry Modifier 的使用场景(顶点动画、程序化变形)、Post-Process 效果的实现思路,以及如何利用 GPU instancing 提升大量相似物体的渲染性能。

Session 还讨论了 AR 场景特有的渲染挑战:虚拟物体和真实环境的光照一致性、半透明材质的处理、以及 LiDAR 数据在渲染中的应用。

值得深挖的点

Geometry Modifier 的执行时机。Geometry Modifier 在渲染管线的顶点阶段执行,每帧每个顶点都会调用。你可以用它做旗帜飘动、水面波纹等效果,但要控制计算复杂度 —— 一个 10 万顶点的网格,shader 里一个多余的正弦计算就会吃掉不少帧时间。RealityKit 提供了内置的 modelPositionmodelNormal 和自定义参数,通过 vertex_attribute 语义传递。

AR 环境光照和 Custom Material 的协作。RealityKit 自动估算环境光照(ARFrame.lightEstimate),Custom Material 的 .lit 模式会自动应用这些估计值。但如果你在 shader 里完全接管了颜色计算(.unlit 模式),需要自己采样环境贴图来实现反射效果。Session 建议大部分场景用 .lit 模式起步,只对特效(全息投影、发光体)使用 .unlit

代码片段

Surface Shader 基础结构(Metal):

// RealityKit 的 surface shader 函数签名
[[visible]]
void hologramSurface(realitykit::surface_parameters params) {
    // 获取表面材质属性
    auto surface = params.surface();
    // 自定义颜色:带扫描线效果的全息材质
    float2 uv = params.geometry().uv0();
    float scanline = sin(uv.y * 100.0 + params.uniforms().time() * 3.0) * 0.5 + 0.5;
    // 基础颜色 + 扫描线
    half3 baseColor = half3(0.0, 0.8, 1.0);
    half3 finalColor = baseColor * half3(scanline * 0.5 + 0.5);
    surface.set_base_color(half4(finalColor, 0.7));
    // 半透明物体不需要写入深度
    surface.set_opacity(half(0.7));
}

Geometry Modifier 实现顶点动画(Metal):

// 让物体沿法线方向做呼吸效果
[[visible]]
void breathingGeometry(realitykit::geometry_parameters params) {
    float3 position = params.model_position();
    float3 normal = params.model_normal();
    // 基于时间的呼吸效果
    float scale = sin(params.uniforms().time() * 2.0) * 0.02;
    // 沿法线方向偏移顶点
    float3 newPosition = position + normal * scale;
    params.set_model_position(newPosition);
}

Swift 侧配置 Custom Material

import RealityKit

func setupHologramMaterial() throws -> CustomMaterial {
    // 编译并加载 Metal shader 库
    let library = CustomMaterial.DefaultLibrary()
    let surfaceShader = CustomMaterial.SurfaceShader(
        name: "hologramSurface",
        library: library
    )
    let geometryModifier = CustomMaterial.GeometryModifier(
        name: "breathingGeometry",
        library: library
    )
    var material = CustomMaterial(
        surfaceShader: surfaceShader,
        geometryModifier: geometryModifier,
        lightingModel: .unlit  // 全息效果不使用环境光照
    )
    // 设置透明排序
    material.triangleFillMode = .fill
    material.cullMode = .none  // 双面渲染
    return material
}

最佳实践

  1. Shader 开发先用 .unlit 模式验证效果.lit 模式的光照计算会干扰你的颜色输出,调试阶段关闭光照能更快定位问题。
  2. Geometry Modifier 中避免复杂分支。GPU shader 中的 if-else 会严重影响性能,用 stepmixsmoothstep 等数学函数代替条件判断。
  3. 透明物体排序(Sorting)是 AR 的老大难问题。RealityKit 按距离排序,但不保证所有情况下都正确。多个半透明物体重叠时,考虑用 SortingGroupComponent 手动控制渲染顺序。

还有什么值得关注

  • RealityKit 2 支持 GPU instancing,通过 InstancingComponent 可以高效渲染大量相同物体。
  • TextureResource 支持动态更新,可以用摄像头画面作为纹理映射到 AR 物体上。
  • Post-process 效果目前没有官方 API,需要通过自定义 shader 在 Surface 阶段模拟。
WWDC 2021