开发 visionOS 前,你需要了解的 Apple AR 技术全景
![image.png](https://i.typlog.com/xrealityzonecn/8304718830_836768.png)
掐指一算,自从 2017 年 Apple 发布 ARKit(同一年,Apple 发布了 iPhone X),Apple AR 相关的技术已经发展了 6 年多了。在这 6 年,每年的 WWDC 上 AR 的相关技术都会占据 Sessions 的一席之地,尽管没有 Swift 和 SwiftUI 相关话题的热度高,但是依然保持着稳定的输出。
可惜的是,由于使用场景的限制,绝大多数开发者可能仅仅是知道 Apple 有 AR 相关的技术,但对这项技术并没有实际的上手或者是深入了解。因此说他是 iOS 开发者一个“熟悉的陌生人”可能并不为过。
在这篇文章中,我们将会尝试从以下这些方面,来帮助你对 visionOS 发布之前,Apple AR 技术有一个大致的了解:
- 2017~2022,每年的 WWDC 都发生了什么
- 从官方 30+ 个 Sample Code 演示中总结出来的 AR 整体框架
- 所有 AR App 都会用到的最基础的代码,以及编程概念
- 精进 Apple AR 必须了解的其他技术
- 入门 Apple AR 的推荐资料
争取在你看完这篇文章后,能够和 Apple AR 从陌生人相处成可以进一步合作的同事😉。
时间线:从 2017 到 2022
首先,让我们先来看看从 2017 年到 2022 年的这些年,每一年的 WWDC 都发生了什么。
2017 年
2017 年可以说是 Apple AR 的 “元年”,这一年的 WWDC 上,Apple 发布了 ARKit 框架以帮助开发者在 Apple 生态下进行 AR App 的开发。
发布之初,ARKit 提供了平面识别(PlaneTracking)以及设备运动状态跟踪的两项基础能力(WorldTracking),这两项能力是基于计算机视觉框架 Vision 对摄像头数据和 iOS 设备的陀螺仪传感器实现的。尽管基础,但这两个功能已经为 AR App 的开发打好了最坚实的地基。利用这两项能力,开发者可以非常简单地实现一个"物品放置"类的 AR App。
![image.png](https://i.typlog.com/xrealityzonecn/8307652246_588222.png)
除此之外,iPhone X 上搭载的原深感摄像头也为精细的人脸识别能力提供了硬件保障。基于此,ARKit 提供了对面部表情的精确识别(FaceTracking),开发者可以使用 ARKit 不仅可以识别用户的面容,甚至可以精细识别用户的表情与对应的面部三维模型。
![image.png](https://i.typlog.com/xrealityzonecn/8307652235_116322.png)
然而,ARKit 本身只是一个通过摄像头和陀螺仪来理解现实世界的框架,因此要开发 AR App,还需要有合适的 2D 或者 3D 渲染引擎与之相结合才能让用户看到更为真实的 AR 画面。
在此之前,Apple 的技术生态中已经有了 SceneKit 和 SpriteKit 这两个用于 3D 和 2D 游戏的游戏引擎。此在 ARKit 发布之时,Apple 非常自然地选择了将 ARKit 与 SceneKit、SpriteKit 相结合的方式,让开发者能够基于 SceneKit 或者 SpriteKit 来完成 AR App 的开发。
![image.png](https://i.typlog.com/xrealityzonecn/8307652226_400509.png)
在这一年,开发者也基于 ARKit 的能力做出了很多有趣的 App,例如 3D 笔刷:
![1.gif](https://i.typlog.com/xrealityzonecn/8307652117_160255.gif)
2018 年
由于 ARKit 是一个技术框架,在不借助 App 的情况下用户很难直接体验到 AR 的魅力,因此在 2018 年,Apple 基于原有的 QuickLook 提供了 AR QuickLook,让用户能够直接通过系统内置的文件 App 来以 AR 的方式预览三维模型:
![2.gif](https://i.typlog.com/xrealityzonecn/8307652069_100378.gif)
而在这一年,更新后的 ARKit 2 更新更多的现实世界的识别能力,除了现实世界的平面和人脸,ARKit 还可以追踪识别现实世界中的图片(ImageTracking)、三维物体(ObjectTracking),甚至还能在用户扫描现实世界时,对现实世界进行 “截图”,然后将其反映在场景中有反光效果的三维物体上(EnvironmentTexturing)。
(WWDC 2018,环境纹理效果展示,其中水果碗是三维模型,香蕉是现实世界中存在,可以看到水果碗上反射出来了香蕉的外表)
2019 年
随着 ARKit 能力的增强,Apple 发现 SceneKit 这个为游戏设计的引擎在 AR 场景下无论是性能还是易用性还是存在着局限性。因此,在 2019 年的 WWDC 上,Apple 发布了专门为 AR 场景设计的渲染引擎—— RealityKit。
和 SceneKit 相比,RealityKit 在 AR 场景下 API 使用起来会更加简单。并且同一时间推出的创作者工具—— Reality Composer 也只能和 RealityKit 协作。
使用 Reality Composer,即便你是不懂开发的 AR 爱好者,也可以通过简单的操作构建一个比较完整的 AR 场景,并且无论是在 Mac、iPad 还是 iPhone 上,你都可以使用 Reality Composer 来完成场景的构建工作。
![image.png](https://i.typlog.com/xrealityzonecn/8307652037_38384.png)
这一年 ARKit 也带来了不少更新,其中最引人瞩目的,无疑是 ARKit 对人物的精准识别(PeopleOcculusion),当人物处于三维物体的前方时,人物就会遮挡住三维物体,进而让整个 AR 的体验更为真实:
![image.png](https://i.typlog.com/xrealityzonecn/8307652027_822302.png)
除此之外,ARKit 还支持了人物的动作捕捉——仅仅通过普通的摄像头就能完成(BodyTracking),无需复杂的动作捕捉设备。
![3.gif](https://i.typlog.com/xrealityzonecn/8307652006_526839.gif)
2020 年
在 2020 年之前,开发者如果想要将三维模型转换成 RealityKit 或者 SceneKit 支持的 USDZ格式只能使用一个命令行工具——USDZ Converter,这在一些需要对模型进行精细化调整的场景下是不太方便的。因此在 2020 年,Apple 推出了 Reality Converter,补上了 Apple 在创作者工具这里的一块拼图。
![image.png](https://i.typlog.com/xrealityzonecn/8307651996_878789.png)
与此同时,从这一年开始,Apple 也开始在一些设备上增加了 LiDAR 扫描器——一个通过向现实世界发射激光来测量设备到物体的距离的传感器。
![4.gif](https://i.typlog.com/xrealityzonecn/8307651970_914224.gif)
以往的 ARKit 都是基于计算机视觉技术来认识现实世界的,因此在一些光照场景不好的场合就会出现定位效果不好的问题。在配有 LiDAR 传感器的设备上,这一问题得到了解决,这也让 AR App 的体验得到了明显得到提升。
![LiDAR 的扫描效果.gif](https://i.typlog.com/xrealityzonecn/8307651047_966352.gif)
这一年 ARKit 也增加一个新的认识现实世界的方式:地理位置定位(GeoTracking)。但可惜的是,这个功能只能在一些美国的城市才能使用。这是因为,地理位置定位需要将 GPS 数据和 Apple 对现实世界的高精度扫描结果结合分析才能得到稳定的结果,因此在使用地理位置定位前,Apple 必须对当地的现实世界场景进行扫描。
![6.gif](https://i.typlog.com/xrealityzonecn/8307651931_722222.gif)
2021 年
在 AR App 的开发过程中,精美的三维模型一直是良好用户体验不可缺失的部分,为了降低开发者获取这些模型的成本,在 2021 年,Apple 在 RealityKit 中提供了 Object Capture 的 API,让开发者可以直接通过对物体拍照来生成高质量的三维模型。
![Object Capture - Augmented Reality - Apple Developer.gif](https://i.typlog.com/xrealityzonecn/8307650898_054727.gif)
2022 年
不仅如此,2022 年 Apple 又推出了 RoomPlan,这是一个让开发者能够通过配有 LiDAR 的设备,就可以对房屋进行建模的框架。
![8.gif](https://i.typlog.com/xrealityzonecn/8307651891_306575.gif)
小结
漫长的六年时光让 Apple AR 的能力逐渐丰富,仅仅是这六年间出现的各种框架、工具就已经让人眼花缭乱了。不用担心,上面出现的种种名词,你都可以通过下面的这张图来再次回顾他们出现的时间,以及当年出现的一些主要更新:
![image.png](https://i.typlog.com/xrealityzonecn/8307651877_317231.png)
在上面出现的所有的名词术语中,最为关键的就是 ARKit 和 RealityKit 这两个框架了,他们各有分工,ARKit 负责获取现实世界的各种信息,而 RealityKit 则专注于将虚拟的 3D 内容真实地渲染出来。
如果把 Apple AR 不精确做一个类比的话,ARKit 就像是 CoreLocatioin / CoreMotion 这样的设备信息框架,获取着现实世界的更多维度的信息;而 RealityKit 则就是像 UIKit / SwiftUI 这样的 UI 框架,只不过 RealityKit 更加专注于 3D 世界的渲染。
好,很棒,现在你已经认识和了解了 ARKit、RealityKit 这两个 AR 世界最为核心的两个框架,它们在 WWDC 历年 AR 相关的视频 中占据了绝对的主角位置:
![image.png](https://i.typlog.com/xrealityzonecn/8307651865_901667.png)
除了 RealityKit 和 ARKit,你可能还会看到其他一些名词,有的你可能会完全陌生,先别着急,在后面我们会展开向你介绍它们的,现在,让我们来继续我们的旅程。
做分类:用合适的框架认识 AR 技术
相信在前面的时间线展示中,你已经看到了很多例如 WorldTracking、FaceTracking 这样的名词了。在 AR 的世界中,这样的名词数不胜数。仅仅是看一遍 Apple 官方所有的 Sample Code,这些 Demo 所表现的各种技术名词都已经让人眼花缭乱了:
![image.png](https://i.typlog.com/xrealityzonecn/8307651855_85541.png)
Tips:
为了方便你快速了解这些 Demo 所体现的能力,这里的每个 Demo 都附上了一个展示的视频或者图片,并对 Demo 的重点内容进行了讲解,你可以直接点击 飞书多维表格 的链接进行查看。
如果你想亲自去跑这些 Demo,由于需要真机运行,证书的配置将会是一件非常繁琐的事情。为了方便你运行,XR 基地将这些所有的 Demo 汇总在 apple-wwdc-ar-demo 这个仓库中,并通过一个单独的 xcconfig 文件统一配置,每个工程直接打开就可以跑。
如果不用一个合适的框架来将他们分类,恐怕我们就要迷失在新鲜术语的海洋中了。
因此在继续深入 AR 的世界之前,我们不妨暂停一下,回想一下我们所熟悉的,在小小的屏幕上所开发的 App 的基本框架。
在一个简单 iOS 应用的开发过程中,我们可以将最基本的开发工作归类在下面两个领域:
![image.png](https://i.typlog.com/xrealityzonecn/8307651798_180991.png)
- 渲染:将数据转换成屏幕像素的过程,UITableView 在这里陪伴我们度过了一段段美好的岁月
- 交互:响应用户触摸操作的过程,单击、双击、拖拽以及各种自定义的手势识别器帮助我们更准确的获知用户的想法
实际上,在 AR App 中,你也可以将所有的能力按照上面的方式进行分类,只不过需要额外的增加一个新成员:场景理解。
![image.png](https://i.typlog.com/xrealityzonecn/8307651786_987744.png)
所谓场景理解,指的是 AR App 对于现实世界信息的分析理解,进而影响 App 的内容呈现。
在传统的 iOS 应用开发中,对地理位置的使用也算是场景理解的一种基本表现,一些类似美团、地图这样的 App 会根据用户当前所处的位置,展现出不同的内容。
而在 AR App 中,对现实的理解就不仅仅是地理位置这么简单了,简单回顾一下你就会发现,ARKit 的所有能力,都是围绕着场景理解展开的,我们再回顾一下在前面的历年 WWDC 中所看到的各种场景理解能力:
- PlaneTracking:识别平面
- WorldTracking:识别设备在现实世界中的相对位置
- FaceTracking:识别设备采集到的人脸以及面部表情
- ImageTracking:识别现实世界中的图片
- ObjectTracking:识别现实世界中的三维物体
- BodyTracking:识别现实世界中的人体姿态
- GeoTracking:识别设备所处的位置
这些场景理解能力是帮助开发者开发出拟真的 AR App 最重要的能力。例如,借助 WorldTracking 中的 EnvironmentTexturing(环境纹理,ARKit 可以通过对相机画面的分析对现实世界的大致样子进行建模,进而赋予虚拟物体更真实的反射效果),你可以在一个虚拟的金属小球表面呈现出真实的反射效果。
![Adding Realistic Reflections to an AR Experience.gif](https://i.typlog.com/xrealityzonecn/8307651604_96767.gif)
而在渲染和交互这里,由于需要和真实的世界进行交互,大部分 AR App 都会选择 3D 场景进行渲染和交互,这也就要求开发者在开发 App 时,必须将视线从二维空间转移到三维空间。
![image.png](https://i.typlog.com/xrealityzonecn/8307650722_634573.png)
而将视线转移到三维空间后,由于游戏引擎(例如 Unity、Unreal)已经在这个领域已经有了相当多的积累,开发者的知识库就需要扩充很多来自游戏的新知识了。例如物理模拟、ECS (一种游戏代码的组织范式,可以类比成我们所熟知的 MVC)这些只有在游戏编程才会出现的术语也会进入到开发者的视线中。
尽管可能比较粗糙,但这个框架已经基本能够帮助我们理解 Apple AR 的大部分能力以及他们所起到的作用了。现在,让我们尝试将上面所有 Sample Code 的能力按照这个框架进行分类,会不会感觉清晰了一点 😉:
![image.png](https://i.typlog.com/xrealityzonecn/8307651581_44801.png)
上代码:如何开发一个简单的放置类 AR App
讲完了概念上的东西,可能你还是有点儿云里雾里。毕竟,Talk is Cheap,Show me the Code。
那么接下来,通过一些简单的代码实例,你将会理解一个 AR App 究竟应该如何开发,这里我们直接借用 Yasuhito Nagatomo 这位日本小哥编写的 ARBasicApp 的代码实例。在这个 App 中,我们将实现一个最为简单不过的放置类 AR App——当你点击屏幕时,一些可爱的玩具就会出现在现实世界中。
![10.gif](https://i.typlog.com/xrealityzonecn/8307651562_480777.gif)
首先,你需要创建一个 ARView,这是打开 AR 世界大门的第一把钥匙:
class ARViewController: UIViewController {
private var arView: ARView!
override func loadView() {
// ...
arView = ARView(frame: .zero,
cameraMode: .nonAR,
automaticallyConfigureSession: false)
// ...
// set up delegate
arView.session.delegate = self
}
}
这里除了 ARView,还出现了一个 Session 的概念。在 AR App 中,场景理解是一个需要持续进行的过程,因此在这里 Apple 将整个理解过程像 NSURLSession 一样抽象成了一个 Session 对象,并通过 Delegate 来获取整个理解过程的细节信息:
// MARK: - ARSession Delegate
extension ARViewController: ARSessionDelegate {
func sessionShouldAttemptRelocalization(_ session: ARSession) -> Bool {
// ...
}
func sessionWasInterrupted(_ session: ARSession) {
// ...
}
func sessionInterruptionEnded(_ session: ARSession) {
// ...
}
func session(_ session: ARSession, didFailWithError error: Error) {
// ...
}
func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
// ...
}
}
接下来,由于这里选择了不自动配置 Session,因此我们可以有机会自己配置一个 ARWorldTrackingConfiguration,并用这个 ARWorldTrackingConfiguration 开启我们前面看到的各项场景识别能力:
extension ARViewController {
private func startARSession() {
// ...
let config = ARWorldTrackingConfiguration()
// Plane Detection
config.planeDetection = [.horizontal, .vertical]
// Environment Texturing
if AppConfig.enableEnvironmentTexturing {
config.environmentTexturing = .automatic
}
// ...
// People Occlusion
if AppConfig.enablePeopleOcclusion {
if ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth) {
config.frameSemantics.insert(.personSegmentationWithDepth)
}
}
// Run the AR Session with reset-tracking
arView.session.run(config, options: [.removeExistingAnchors, .resetTracking])
// ...
}
到这里,我们就已经可以运行起来带有场景识别能力的 AR App 了。让我们给这个 App 增加一点用户交互,这里仍然还是 iOS 开发所熟悉的 UITapGestureRecognizer:
class ARViewController: UIViewController {
// ...
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self,
action: #selector(tapped(_:)))
arView.addGestureRecognizer(tap)
}
}
当用户点击屏幕的时候,UITapGestureRecognizer 只能告诉我们用户在屏幕这个二维空间的点击位置。
在 AR App 中,我们需要知道用户点击处所对应的三维空间位置,这里可以使用 Raycast 来获取这一信息,所谓 Raycast,指的是发射一条射线,返回这条射线上所碰触的所有物体(可以不精确的理解为三维版本的 HitTest):
![image.png](https://i.typlog.com/xrealityzonecn/8307651549_833021.png)
了解了概念后,再看代码就比较简单了:
extension ARViewController {
@objc private func tapped(_ gesture: UITapGestureRecognizer) {
if gesture.state == .ended {
let location = gesture.location(in: arView)
// create ray cast query
guard let query = arView.makeRaycastQuery(from: location,
allowing: .estimatedPlane,
alignment: .any) else {
return
}
let raycastResults = arView.session.raycast(query)
if let result = raycastResults.first {
// [Note] result.anchor: ARAnchor? can not be casted to ARPlaneAnchor
// - if query's allowing is .existingPlaneInfinit, result.anchor will be ARPlaneAnchor
// - if query's allowing is .estimatedPlane, resutl.anchor will be nil
let anchorEntity = AnchorEntity(raycastResult: result)
placeARScene(anchorEntity)
} else {
// do nothing (no raycast result)
}
}
通过 raycastResults,我们得到了一个现实世界的三维坐标,接下来要做的事情就是加载对应的模型。
你可能会注意到这里又出现了一个没见过的名词——Anchor(锚点),在 Realitykit 和 ARKit 的世界中,Anchor 所代表的是一个虚拟的点或者区域,用来将虚拟世界中的图像、模型、视频等元素与现实世界中的物理位置和方向进行关联。
![image.png](https://i.typlog.com/xrealityzonecn/8307651539_311224.png)
在这里,我们将这个锚点和用户所点击的区域进行绑定,方便下一步加载模型时加载在正确的位置。
前面我们提及到,在 AR App 中会不可避免的涉及到很多来自游戏引擎的编程概念,在这里我们即将调用的placeARScene()
中的 Scene,也是一个来自游戏引擎的概念。你可以不精确的将 Scene 理解为游戏中的关卡,一个 Scene 中会负责将一个关卡中玩家看到的所有东西按照层级组织在一起,例如在 Unity 中,你会看到:
![image.png](https://i.typlog.com/xrealityzonecn/8307651511_370352.png)
不过这里我们还无法有这样可视化的工具来辅助我们开发,让我们继续来用代码构建我们的 AR 世界,将刚刚创建的 AnchorEntity 放置到 Scene 的根节点下:
extension ARViewController {
private func placeARScene(_ anchorEntity: AnchorEntity) {
if arScene != nil {
removeARScene()
}
arView.scene.addAnchor(anchorEntity)
arScene = ARScene(anchorEntity: anchorEntity)
arScene?.setScale(sceneScale)
arScene?.loadModels()
startFrameLoop()
}
}
完成了场景理解、交互,现在让我们来完成最重要的渲染。
在这里,我们会通过 RealityKit 内置的方法,将三个格式为 USDZ 的 3D 模型挂载到 AnchorEntity 之下:
final class ARScene {
func loadModels() {
ARSceneSpec.models.forEach { modelSpec in
// ...
Entity.loadAsync(named: modelSpec.fileName)
.sink(receiveCompletion: { _ in
// handle error
}, receiveValue: { [weak self] entity in
// ...
self?.anchorEntity.addChild(entity)
// ...
})
.store(in: &loadingSubscriptions)
}
}
}
至此,一个简单的放置类 AR App 就完成了!
看过去了这么一大堆代码,让我们再来回顾一下刚才接触到的所有概念:
![image.png](https://i.typlog.com/xrealityzonecn/8307651487_5712805.png)
再精进:AR 背后默默支持的其他技术
除了 ARKit 和 RealityKit ,在 Apple 庞大的武器库中,还有很多技术能够帮助我们实现一个体验良好的 AR App,这里我们主要介绍这几个你在深入时大概率会碰到的技术:
- USD:由皮克斯所开发的三维场景文件格式
- CoreML:苹果的机器学习框架
- Vision:苹果的视觉智能框架
- Multipeer Connectivity:苹果端到端的本地连接和发现服务框架
- Metal:苹果提供的高性能的底层图形框架
USD
![image.png](https://i.typlog.com/xrealityzonecn/8307651461_765524.png)
先来说说 USD(Universal Scene Description),出于皮克斯和 Apple 之间 有趣的过往,Apple 选择一个皮克斯推出的三维场景格式就不奇怪了。而 USD 也是 RealityKit 唯一支持的第三方三维模型格式。前面我们所提及到的 AR Quicklook 支持的也是 USD 这种格式。
在日常的开发流程中,我们主要会看到这几种文件后缀——usda 、usdc 以及 usdz,其中,usda 是纯文本文件格式(你可以直接用文本编辑器将其打开),而 usdc 则是二进制格式,usdz 则类似 zip ,是一种压缩包格式,在这个文件中可以有一些贴图(png、jpg 格式等),你可以使用 unzip -l
来查看其内部的内容,比如 这个文件:
$ unzip -l teapot.usdz
Archive: teapot.usdz
Length Date Time Name
--------- ---------- ----- ----
4262569 01-24-2023 18:24 teapot.usdc
2210854 01-24-2023 18:24 0/teapot_bc.png
489015 01-24-2023 18:24 0/teapot_ao.png
1246353 01-24-2023 18:24 0/teapot_r.png
793984 01-24-2023 18:24 0/teapot_n.png
17302 01-24-2023 18:24 0/teapot_m.png
--------- -------
9020077 6 files
如果你想看到更多的 USD 文件例子,你可以前往 Apple 的 Quick Look Gallery 游玩一番。
![image.png](https://i.typlog.com/xrealityzonecn/8307651440_062712.png)
Tips:
你可能会注意到,在 Quick Look Grallery 中,Examples with animations 中的例子下载下来是 .reality 格式。这种格式是 Apple 针对 Reality Composer 所特制的三维场景文件格式(在一开始的 Reality Composer 中,三维场景只能被导出为 .reality 格式),可以认为这是 Apple 针对三维场景的一种专有格式。
不过,专有格式的坏处就是通用性不够,除了 Reality Composer,你几乎无法在其他任何建模工具中打开 .reality 文件,为了能够增强其通用性,在 2020 年 Apple 针对 USD 规范进行了 AR 相关的扩展,让 Reality Composer 可以导出 .usdz 格式,也给其他建模工具支持这种格式提供了 范例。
简单两句话可能不太能完全讲清楚这里的曲折历史,不过放心,我们会在后面的技术解析中专门开辟一期来展开这个话题,记得回来看哦~
CoreML && Vision
![image.png](https://i.typlog.com/xrealityzonecn/8307651425_584776.png)
机器学习和视觉智能,这两者可以说是 ARKit 实现场景理解的底层基石。CoreML 和 Vision 则一起,从 iOS 11 开始承担起来 Apple 在 AR 场景理解上的重任。ARKit 中很多场景理解的能力在 CoreML 和 Vision 中都能找到更加底层的接口。
例如,前面我们提及过的 BodyTracking,你也可以使用 Vision 中的 VNDetectHumanBodyPoseRequest 来实现:
// Get the CGImage on which to perform requests.
guard let cgImage = UIImage(named: "bodypose")?.cgImage else { return }
// Create a new image-request handler.
let requestHandler = VNImageRequestHandler(cgImage: cgImage)
// Create a new request to recognize a human body pose.
let request = VNDetectHumanBodyPoseRequest(completionHandler: bodyPoseHandler)
do {
// Perform the body pose-detection request.
try requestHandler.perform([request])
} catch {
print("Unable to perform the request: \(error).")
}
当然,了解 CoreML 和 Vision 肯定不是为了使用 ARKit 已经封装好的功能。在 CoreML 和 Vision 中,还有很多非常适合 AR 场景使用的功能还没有被封装在 ARKit 中, 了解他们有助于我们实现那些 ARKit 尚未封装好的功能,这其中,最典型的例子就是手势识别。
在 ARKit 的当前版本中,我们还不能非常精细地识别到画面中的人物手势并进行区分。而借助 Vision 提供的 VNDetectHumanHandPoseRequest ,以及 CoreML 配套的模型训练工具 CreateML 中提供的 Hand Action Classification,我们就可以轻松实现人物的手势识别。
![image.png](https://i.typlog.com/xrealityzonecn/8307651405_949445.png)
例如,在 WWDC 21 的这个示例中,借助以上两个框架,我们就可以实现下面这段视频中对人物手势的精准识别:
![11.gif](https://i.typlog.com/xrealityzonecn/8307651392_05653.gif)
Multipeer Connectivity
独乐乐不如众乐乐,手机 App 是如此,AR App 也不例外,除了直接录屏分享,一个制作精美的 AR App 如果能够提供本地多人联机能力,那这个 App 带来的快乐无疑会增倍。
而为了实现这样的功能,从 iOS 7 时代就推出,但是长久以来容易被忽视的 Multipeer Connectivity 框架在 AR 场景中又焕发出了新的活力。RealityKit 也基于这个框架提供了非常简洁的封装。例如,基于 MultipeerConnectivityService,我们可以非常简单的通过几行代码来完成和其他设备间的场景共享:
let peerID = MCPeerID(displayName: UIDevice.current.name)
let session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
arView.scene.synchronizationService = try? MultipeerConnectivityService(session: self.session)
HoloKit 中令人惊叹的多人 AR 游戏场景,就是基于这项能力实现的:
![12.gif](https://i.typlog.com/xrealityzonecn/8307651368_355932.gif)
Metal
最后,就不得不提及到 Metal 了。在 Apple AR 世界中,你看到的那些栩栩如生的虚拟 3D 物体的背后,都有 Metal 这个底层图形绘制框架的默默支持。
![image.png](https://i.typlog.com/xrealityzonecn/8307651359_479113.png)
作为一个 2014 年就发布的底层图形框架,Metal 已经成功成为了在 iOS 平台进行底层图形绘制的不二选择(成功替换掉了在 Apple 平台被废弃的 OpenGL ES),前面我们所介绍的 SceneKit 和 RealityKit,以及 iOS 开发者所熟知的 CoreImage,甚至 Unity 这样的游戏引擎,都是基于 Metal 去操作 GPU 的。
![image.png](https://i.typlog.com/xrealityzonecn/8307651351_552266.png)
因此,当你的 AR App 需要实现一些更加高效或者定制化的渲染效果时,你就可以使用 Metal 来大展身手了。例如在 Apple 的 Sample Code - Creating a Fog Effect Using Scene Depth 中,就基于 Metal 实现了非常高效的雾气的效果:
![image.png](https://i.typlog.com/xrealityzonecn/8307651341_29524.png)
在实际使用中,除了直接使用 Metal,你还可以选择使用 MetalKit(提供了很多方便的工具类和函数)、MPS(Metal Performance Shader,提供了一系列高性能的计算和渲染 Shader) 和 MetalFX(将低分辨率的画面 upscale 为高分辨率的画面,以获得更好的渲染性能) 这三个框架来快速开发
除了用于绘制,得益于 GPU 强大的并行计算能力,Metal 也在机器学习中被广泛使用,CoreML && Vision 的底层也使用到了 MPS 来加速计算:
![image.png](https://i.typlog.com/xrealityzonecn/8307651333_84202.png)
心中有数:学习 Apple AR 的资料推荐
呼,看到这里,相信我们已经达成了最开始的那个小小的目标:和 Apple AR 成为了可以进一步合作的同事。
为了尽可能帮助你在入门的这条路上走的更加顺利,在这里 XR 基地的各位开发者们精心准备了一些比较推荐的入门资料:
- AR Quick Look:先快速玩起来
- 简单一览:Quick Look Gallery
- 发现更多好玩的模型文件:Sketchfab
- 3D 入门
- RealityComposer
- RealityKit
当你学习完以上的资料之后,在概念上相信你会清晰不少,不过接下来,你还需要尝试写一些具体的代码来练个手。从 Sample Code 中找一些你感兴趣的 Demo 尝试改一改来上个手叭~