RealityKit - 基础概念

RealityKit Experience

Posted by Quincy-QC on 2021-06-21

前言

最近Apple刚好在WWDC21上发布了Object Capture,基于这个契机,我们就想用苹果提供生成的模型加上最新的RealityKit框架进行一次实景AR开发,这篇文章就简单介绍RealityKit的基础概念。

介绍

RealityKit框架专门为增强现实量身定制,能够提供逼真的图像渲染、相机特效、动画、物理特效等等。借助原生ARKit整合、基于物理的超逼真渲染、变换和骨骼动画、空间音频和刚体物理,RealityKit可以比以往更加快速轻松地进行增强现实开发。

基础概念

如下图ARView的结构层次:
RealityKit

首先ARView就是用于展示AR体验的视图,可以将它添加到父视图中,通过初始化cameraMode的不同,可以确定是否需要使用相机生成真实的AR场景还是虚拟场景,这个比较简单。看下API:

1
public init(frame frameRect: CGRect, cameraMode: ARView.CameraMode, automaticallyConfigureSession: Bool)

其次是Scene就是保存AR视图呈现的容器,我们不需要直接创建,可以通过ARView·获取到scene这个熟悉,后续我们的模型都是直接或者间接添加到这个scene上。

然后就是Entity了,这里有Anchor EntityModel Entity,其实本质都是继承与Entity,同时,如果我们想要自定义一些Entity,我们可以通过继承Entity,同时实现相应的协议,同时加载相应的Component,就可以创建具有不同外观和行为的实体,如下图:
RealityKit

这边又有两个概念,一个是协议,一个是Component,其实概括来讲就是协议让Entity拥有了某项能力,而Component则是用来真正装备该能力的组件修饰,所以,如果我想要一个Entity拥有外观属性(大小、颜色),那我们我们就需要继承HasModel这个协议,同时配置Component这个属性赋予这个实体真正的外观属性,后面再深入介绍。

苹果默认提供了两个基础Entity,一个是Anchor Entity,一个是Model Entity,现在我们就来具体介绍这两个Entity

Entity

一个基类Entity默认实现了HasTransformHasSynchronization协议,拥有Transform componentSynchronization component两个组件,分别用于空间转换(大小、位移,旋转)与联网时的同步操作,同时还实现了HasHierarchy协议,允许所有的Entity拥有层级关系(父实体,子实体)。

AnchorEntity

Anchor Entity默认实现了HasAnchoring协议,实现该协议之后就是允许该实体能够将该虚拟内容渲染到真实世界,我们一般用来把他作为基础实体,然后后续具体的实体添加到这个Anchor Entity上,后续添加到ARView上继续渲染,可以把他当成一个载体,本身并没有形状或者外观。

ModelEntity

另一个默认提供的实体是Model Entity,实现了HasModel, HasPhysics两个协议。

  • HasModel这个协议本身就继承于HasTransform协议,他针对与HasTransform协议,又增加了一个Model component组件,允许设置该实体的外观大小包括纹理等信息。
  • HasPhysics这个协议是HasPhysicsBodyHasPhysicsMotion协议的总和。
    • HasPhysicsBody又继承于HasCollisionHasCollision又继承于HasTransformHasCollision增加的组件特性就是碰撞体积与控制模式(是否需要记录细节碰撞信息);HasPhysicsBody新增的组件特性是允许对该物体施加外力并进行运动。
    • HasPhysicsMotion新增的组件特性是基础运动模式,能够在创建后无需外力就保持一个持续的运动,同时判断是否允许外界改变行为;

自定义Entity

所以,基于上面的介绍,我们自定义Entity也就很简单了,只要针对于我们的场景,选择不同的协议与添加对于的Component就可以得到我们定制的实体,用于展示,非常Swift。

简单实现

那么我们就来简单实现一个非AR场景下的Box实体,并增加一个自旋动作。
首选我们就自定义一个实体,有以下需求:

  • 直接添加到Scene上,需要有Anchor Entity的锚点添加特性,所以继承HasAnchoring协议
  • 需要自定义一个形状box和颜色,所以继承HasModel协议
  • 需要增加一个自旋匀速运动,所以继承HasPhysics协议
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Box: Entity, HasAnchoring, HasModel, HasPhysics {
required init(world: SIMD3<Float>) {
super.init()

position = world

// 设置大小,颜色,形状
model = ModelComponent(
mesh: .generateBox(size: 0.5),
materials: [SimpleMaterial(color: .cyan, roughness: 0.5, isMetallic: true)]
)

// 设置碰撞体积
collision = CollisionComponent(
shapes: [.generateBox(size: [0.5, 0.5, 0.5])],
mode: .default,
filter: .default
)

// 设置物理模型大小,密度,运动模式(非动态)
physicsBody = {
var c = PhysicsBodyComponent(
shapes: [ShapeResource.generateBox(size: [0.5, 0.5, 0.5])],
density: 0.95,
material: .generate(),
mode: .kinematic
)
return c
}()

// 给定y方向恒定角速度转动
physicsMotion = PhysicsMotionComponent(linearVelocity: [0, 0, 0], angularVelocity: [0, 1, 0])
}

required init() {
fatalError("init() has not been implemented")
}
}

这样,一个简单的自定义实体就已经定制完了。

然后创建我们的ARView,添加到主视图,并通过ARView获取的Scene添加Box实例,然后就能肯定一个沿着y轴恒定速度旋转的盒子了。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

let arView = ARView(frame: view.bounds, cameraMode: .nonAR, automaticallyConfigureSession: false)
view.addSubview(arView)

let box = Box(world: [0, 0, 0])
arView.scene.addAnchor(box)
}
}

效果图:
RealityKit

结语

一个简单的旋转模型就实现了,是不是很简单,可以自己尝试下。