Augmented Reality 进阶 25m
RealityKit 新特性
What's new in RealityKit
2020年6月24日
一句话判断
RealityKit 在 2020 年补齐了很多基础能力——自定义材质、Face Tracking 支持和 body tracking 的增强让它从一个”AR 展示框架”逐渐变成一个完整的 AR 开发框架。
这场 Session 讲了什么
这场 Session 全面介绍了 RealityKit 在 2020 年的更新内容。RealityKit 是 Apple 推出的高级 AR 框架,定位是在 ARKit 之上提供更易用的 API。2020 年的更新主要集中在四个方面:自定义材质系统、角色动画增强、与 ARKit 4 新特性的整合,以及 Face Tracking 的改进。
演讲者首先介绍了新的材质系统。之前 RealityKit 只提供了 SimpleMaterial 和 UnlitMaterial,现在新增了 VideoMaterial(可以将视频作为材质贴在 3D 物体表面)和自定义材质的能力。自定义材质允许你编写 Metal shader 来实现特殊视觉效果,如全息投影、卡通渲染、水面效果等。
然后讲解了角色动画方面的改进。RealityKit 现在支持更复杂的骨骼动画(Skeletal Animation),可以从 USDZ 文件中加载带骨骼的动画角色,并支持动画混合(Blend)和动画层叠。这对 AR 游戏和虚拟角色应用来说是关键能力。
Face Tracking 部分介绍了如何利用 TrueDepth 摄像头的面部追踪数据来驱动虚拟角色表情。Session 还讨论了如何利用 ARKit 4 的 Scene Geometry 数据在 RealityKit 中实现更精确的遮挡效果。
值得深挖的点
- 自定义 Material Shader 的编程模型:RealityKit 的自定义材质使用一种声明式的 Shader Graph 风格——你通过定义 Surface Shader 和 Geometry Modifier 来控制渲染。Surface Shader 控制颜色和光照,Geometry Modifier 控制顶点位移。这种设计比直接写 Metal shader 更高层,但灵活性足以覆盖大多数自定义效果。
- VideoMaterial 的应用场景:在 AR 中显示视频是很多场景的需求——比如在虚拟电视屏幕上播放内容、在虚拟广告牌上展示视频广告。VideoMaterial 将视频解码和纹理映射封装成一个简洁的 API,省去了手动管理 AVPlayer 和纹理上传的麻烦。
代码片段
// 使用 VideoMaterial 将视频贴在 3D 物体上
import RealityKit
import AVFoundation
func createVideoScreen() -> Entity {
// 创建 AVPlayer 加载视频
let url = URL(string: "https://example.com/video.mp4")!
let player = AVPlayer(url: url)
// 创建 VideoMaterial
let videoMaterial = VideoMaterial(avPlayer: player)
// 创建一个平面实体并应用视频材质
let screenEntity = ModelEntity(
mesh: .generatePlane(width: 1.6, height: 0.9),
materials: [videoMaterial]
)
player.play()
return screenEntity
}
// 使用自定义材质实现全息效果
func createHologramMaterial() -> Material {
// 通过 ShaderGraphMaterial 或 CustomMaterial 定义
var customMaterial = CustomMaterial(
surfaceShader: "hologram_surface",
geometryModifier: "hologram_geometry"
)
// 设置 shader 参数
customMaterial.custom.parameterNames = ["time", "scanLineSpeed"]
customMaterial.custom.setValue(0.0, for: "time")
customMaterial.custom.setValue(2.0, for: "scanLineSpeed")
return customMaterial
}
// 加载带骨骼动画的 USDZ 角色
func loadAnimatedCharacter() {
// 加载 USDZ 模型(包含骨骼和动画)
let anchor = try! Entity.loadAnchor(named: "character")
// 播放动画
if let animation = anchor.availableAnimations.first {
let repeatAnimation = animation.repeat()
anchor.playAnimation(repeatAnimation)
}
arView.scene.anchors.append(anchor)
}
// 混合多个动画
func blendAnimations() {
let walkAnimation = character.availableAnimations[0]
let waveAnimation = character.availableAnimations[1]
// 创建混合动画
let blend = try! AnimationResource
.source(walkAnimation)
.blend(waveAnimation, blendFactor: 0.5)
character.playAnimation(blend)
}
最佳实践
- VideoMaterial 会持续消耗 GPU 资源,不可见时应暂停播放
- 骨骼动画的骨骼数量控制在合理范围内,过多的骨骼会影响性能
- 使用 ARKit 的环境光估计让虚拟物体的光照与真实场景匹配
- 自定义 shader 中的计算尽量简洁,复杂的 shader 会显著降低帧率
- 利用 RealityKit 的内置物理系统处理碰撞和交互,不要重复造轮子
还有什么值得关注
- RealityKit 后来在 visionOS 中成为了核心的 3D 渲染框架,2020 年打下的基础很重要
- “Explore ARKit 4” 介绍了 RealityKit 底层依赖的 ARKit 新特性
- 如果你在做 AR 创意工具,搭配 “The artist’s AR toolkit” 一起看
WWDC 2020