DEMO
包含功能平面检测、环境纹理、物体操作(添加、选中、拖动、缩放、旋转)、图像识别、环境音效
什么是ARKit
AR(Augmented Reality)
运用计算机技术,将虚拟的信息应用到真实世界,被人类感官所感知。给人一种虚拟物体存在于现实世界的错觉。而ARKit
整合运动传感器数据,相机数据,相机捕捉到的图像分析数据,用于建立现实场景和建模AR内容的虚拟场景的对应关系,为这种错觉提供数据基础,简化构建AR体验。
构建AR体验的三驾马车
Tracking
通过Tracking,我们可以:
- 获得相机在现实世界中的位置。
- 将相机图像和运动数据整合,形成AR视图。
- 追踪特征点,构建AR场景。追踪人脸,图像,物体等。
AR追踪的单位为m。因此在制作AR模型时,需要按照物体实际在现实世界中的屋里比例来制作。这样物体不至于过大或过小,呈现会更真实。
在iOS开发中,Tracking通过AVFoundation
来获取场景图像,CoreMotion
来获取运动数据。结合两者形成AR视图。
Tracking质量
要保证高质量的追踪Tracking数据,需要高质量的特征点。需要满足以下条件:
- 持续的相机数据和传感器数据
- 环境纹理要足够明显。需要处于一个光线充足并且纹理明显的环境当中,这样ARKit更容易提取特征点,建立空间对应关系。
- 静态场景。动态场景会导致视觉数据和运动数据不相符,影响追踪质量。
Scene Understanding
- 平面检测
- hit-testing
- 光线估计
Rendering
对iOS开发者来说,最便捷的渲染方式是SceneKit
。ARKit负责收集数据,渲染负责展示AR模型。
支持的渲染方式如下:
- SceneKit
- SpringKit
- OpenGL/Metal
下面这幅图展示了ARKit
在一个AR应用中的角色。
三步创建你自己的AR体验
创建AR体验只需要三步:
ARSession
通过ARSessionConfiguration
开启,由Delegate回调ARFrame
信息数据进行展示。
相关代码如下:
初始化Configuration
// Start the view's AR session with a configuration that uses the rear camera,
// device position and orientation tracking, and plane detection.
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.horizontal, .vertical]
运行ARSession
sceneView.session.run(configuration)
获取委托数据。ps:如果使用SceneKit
来渲染,则不用关心Session回调,只需要关心SceneKit
的Node
相关操作和回调。
// Access the latest frame
func session(_: ARSession, didUpdate: ARFrame)
接下来我们就来了解一下ARKit
中几个重要的类。
ARSession
AR体验通过ARSession
来开启。它管理着Tracking时所有的进程,是管理设备相机和动作处理的共享对象。ARSession
整合运动传感器数据,相机数据,相机捕捉到的图像分析数据,用于建立设备所在场景和建模AR内容的虚拟场景的对应关系。
每一个AR 体验都需要一个ARSession
对象。如果使用ARSCNView
或者ARSKView
来渲染展示部分,View对象包含一个ARSession
实例。如果使用你自己的渲染器,你需要实例化并维护一个ARSession
对象。
ARSession
对象需要通过ARConfiguration
子类来运行,这个配置决定ARKit如何追踪设备相对于现实场景中的位置及动作。
/**
Runs the session with the provided configuration and options.
@discussion Calling run on a session that has already started will
transition immediately to using the new configuration. Options
can be used to alter the default behavior when transitioning configurations.
@param configuration The configuration to use.
@param options The run options to use.
*/
open func run(_ configuration: ARConfiguration, options: ARSession.RunOptions = [])
ARConfiguration
ARSession
由ARConfiguration
子类来开启。不同Configuration有不同的特性,都是通过环境中的特征点来进行追踪。
ARWorldTrackingConfiguration - iOS 11.0+ - 6DOF
使用后置摄像头精确跟踪设备的位置和方向,并允许平面检测、hit-testing、基于环境的光线估计、以及图像和对象检测追踪。
ARKit使用视觉惯性测量法(visual-inertial odometry)在真实和虚拟空间之间建立对应关系。
功能
-
planeDetection
:查找现实平面(水平或竖直),并作为ARPlaneAnchor
对象来添加到会话中。 -
detectionImages
:识别2D图像并追踪图像的移动,并作为ARImageAnchor
对象添加到场景中。 -
detectionObjects
:识别3D对象,并作为ARObjectAnchor
对象添加到场景中。 -
environmentTexturing
:光面物体上展示环境纹理。 - 在
ARFrame
,ARSCNView
或者ARSKView
中通过hit-testing
来查找与相机场景的2D坐标对应的现实世界中的位置。
最佳实践:
- 在可靠的照明条件中设计AR体验。世界追踪需要清晰的图像来进行图像分析。如果细节不清晰,追踪效果将会降低。比如,相机对着空白墙面或者处于光线不足的场景中时。
- 根据追踪信息来提供用户反馈。世界追踪将图像分析与设备运动关联。如果设备正在移动,ARKit会更好地理解场景。但过度的运动又会降低追踪质量。
ARCamera
类提供追踪状态的原因信息,可以使用此信息来进行UI展示。 - 留出时间进行平面检测,并在获得所需结果时禁用平面检测。平面检测结果是一个凸多边形,会随着检测结果不断变化。
AROrientationTrackingConfiguration - iOS 11.0+ - 3DOF
提供基本AR体验。使用后置摄像头跟踪设备方向。
ARFaceTrackingConfiguration - iOS 11.0+
提供使用前置摄像头的AR体验,并跟踪用户脸部拓扑和表情。
检测到人脸会返回一个ARFaceAnchor
对象。其中的信息包括包头部姿势,脸部网格拓扑,眼球追踪信息和混合形状的信息系数。如果启用光估计,则会估计光线方向。
开启会话:
guard ARFaceTrackingConfiguration.isSupported else { return }
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
-
ARFaceTrackingConfiguration
:使用TrueDepth相机追踪脸部动作和表情 -
ARFaceAnchor
:包含脸部姿势,拓扑,表情信息。如果有多张脸,ARKit会旋转最大的或最清晰的来识别。 ARSCNFaceGeometry
-
ARDirectionalLightEstimate
: 模拟环境光照信息
ARImageTrackingConfiguration - iOS 12.0+ - 6DOF
使用后置摄像头来追踪已知图像,最多可同时最终4张图像。
通过在Asset catalog中创建AR Resource Group,导入需要识别的图像,来进行检测。Group中最多可导入25张图片。
在选择图像时有几点要求:
- 为每张图像指定准确物理尺寸。ARKit通过这个物理尺寸决定图像与镜头的距离。
- 特征点明显,对比度高。利于识别。
- 避免反光材质等会干扰视觉图像的因素。
example:
guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
fatalError("Missing expected asset catalog resources.")
}
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = referenceImages
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
-
ARReferenceImage
: 在现实世界环境中被识别的图像。 -
ARImageAnchor
:包含检测到的图像的位置和方向信息。
最佳实践
- 使用检测到的图像来设置AR场景的参考系
- 使用检测到的图像作为虚拟内容的起点
- 考虑何时允许检测到的图像来触发交互:检测到图像时,操作只会触发一次。要触发多次可使用
removeAnchor:
在合适的时间主动移除,下一次检测到图像时,ARKit会添加一个新的anchor.
ARObjectScanningConfiguration - iOS 12.0+ - 6DOF
提供使用后置摄像头收集高保真空间数据,创建参考对象以便在其他AR体验中进行检测。
通过在Asset catalog中创建AR Resource Group,导入需要包含识别对象信息的.arobject
文件,来进行检测。
example:
let configuration = ARWorldTrackingConfiguration()
guard let referenceObjects = ARReferenceObject.referenceObjects(inGroupNamed: "gallery", bundle: nil) else {
fatalError("Missing expected asset catalog resources.")
}
configuration.detectionObjects = referenceObjects
sceneView.session.run(configuration)
-
ARReferenceObject
:要识别的3D对象 -
ARObjectAnchor
:检测到的3D对象的位置和方向信息。
degrees of freedom
下面这幅图展示的是6 degrees of freedom。其实就是包含在三位坐标x, y, z三轴上的位置(在轴上平移)和方向(绕轴旋转)。
ARFrame
每一个ARFrame
都包含一个ARCamera(虚拟的相机对象:包含位置和成像特征的信息)
ARFrame
包含如下信息:
- 带有位置追踪信息的视频图像
- 追踪的信息和状态
- 场景信息
ARHitTestResult
包含通过检查AR会话的设备摄像机视图中的点找到有关真实世界表面的信息。
ARAnchor
锚点,这个大家都比较好理解。
我们如果要在现实世界中挂一幅画要怎么做呢?大致只需要两步。
- 找到我们要挂画的位置,定一个钉子(下个锚点)
- 把你的画(虚拟物体),挂上去
特点:
- 物理世界中的点,用于放置虚拟物体。
- 包含现实世界位置和方向
- 通过ARSession添加和删除
- 有丰富的子类,包含不同的anchor信息, 或自定义anchor
- 通过ARSessionDelegate更新 add/update/remove
SceneKit相关
了解了ARKit的操作,下一步就要进行渲染。SceneKit负责所有虚拟物体的渲染。这里我们使用ARSCNView
,它的主要功能如下
- 绘制捕捉的图像
- 更新SCNCamera
- 更新场景光线
- 映射SCNNodes到ARAchors
SceneKit会把ARAnchor
与SCNNode
对应。我们要操作虚拟物体时,只需要操作Scene世界中的Node
.我们关注的也都是ARSCNViewDelegate
的回调。
环境音效
可以使用SceneKit
的node-based audio API给物体添加声音。如果需要环境音效效果,需要使用单声道音频。
example:
// MARK: - Sound
/// Sets up the audio for playback.
/// - Tag: SetUpAudio
private func setUpAudio() {
// Instantiate the audio source
audioSource = SCNAudioSource(fileNamed: "fireplace.mp3")!
// As an environmental sound layer, audio should play indefinitely
audioSource.loops = true
// Decode the audio from disk ahead of time to prevent a delay in playback
audioSource.load()
}
/// Plays a sound on the `objectNode` using SceneKit's positional audio
/// - Tag: AddAudioPlayer
private func playSound() {
// Ensure there is only one audio player
objectNode.removeAllAudioPlayers()
// Create a player from the source and add it to `objectNode`
objectNode.addAudioPlayer(SCNAudioPlayer(source: audioSource))
}
ARKit 2新特性
空间映射的存储和共享
新增了ARWorldMap
,包含映射信息。可以保存场景的状态,进行场景共享。
World Tracking Enhancements
- 保存/加载映射
- 更快的初始化和平面检测
- 检测更精准
- 连续对焦
- 4:3视频格式, ARKit2的默认格式
Environment Texturing
可以在光面物体上反射环境纹理,让物体更逼真。
Image Tracking
查阅ARImageTrackingConfiguration
。
Object Detection
查阅ARObjectScanningConfiguration
。
Face Tracking Enhancements
新增眼球和舌头追踪
推荐阅读
官方手册
Introducing ARKit: Augmented Reality for iOS
Face Tracking with ARKit
What’s New in ARKit 2
Understanding ARKit Tracking and Detection