ARKit 和 RealityKit 阶段
启动 AR 应用时,ARKit 和 RealityKit 分为三个阶段:
每个阶段可能会大大增加模型放置所需的时间(+1...+4 秒,具体取决于设备)。让我们来谈谈每个阶段。
追踪
这是您的 AR 应用程序的初始状态。在这里,iPhone 以 60 fps 的速度混合来自 RGB 后置摄像头的视觉数据和来自 IMU 传感器(加速度计、陀螺仪和指南针)的 1000 fps 的转换数据。自动生成的特征点有助于 ARKit 和 RealityKit 跟踪周围环境并构建跟踪图(无论是 World Tracking 还是例如 Face Tracking)。特征点是在光线充足的环境中,在现实世界对象和纹理的高收缩边距上自发生成的。如果您已经有一个以前保存的世界地图,它会减少将模型放置到场景中的时间。您也可以使用ARCoachingOverlayView
有用的视觉说明来指导您在会话初始化和恢复期间。
场景理解
第二阶段可以包括水平和垂直平面检测、射线投射(或命中测试)和光估计。如果您已激活平面检测功能,则需要一些时间来检测具有相应ARPlaneAnchor(或AnchorEntity(.plane)
)的平面,该平面必须连接虚拟模型 - 在您的情况下为立方体。还有一个高级场景理解允许您使用场景重建功能。您可以在带有 LiDAR 扫描仪的小工具中使用场景重建,它为您在场景和人物遮挡中合成元素提供了改进的深度通道。您始终可以启用图像/对象检测功能,但您必须考虑它是建立在机器学习算法之上的,这会增加模型在场景中的放置时间。
渲染
最后一个阶段用于渲染场景中的虚拟几何体。场景可以包含带有着色器和纹理的模型、变换或资产动画、动态和声音。金属着色器的周围 HDR 反射由神经模块计算。ARKit 无法渲染 AR 场景。对于 3d 渲染,您必须使用 RealityKit、SceneKit 或 Metal 等框架。这些框架有自己的渲染引擎。
默认情况下,RealityKit 中有高质量的渲染效果,如运动模糊或光线追踪阴影,需要额外的计算能力。考虑到它。
小费
要显着减少在 AR 场景中放置对象的时间,请使用以纳秒速度工作的 LiDAR 扫描仪。如果您的小工具没有 LiDAR,则仅跟踪照明条件良好、所有真实世界对象都清晰可辨且纹理丰富且没有重复图案的周围环境。此外,尽量不要在项目中使用超过 10K+ 多边形和高分辨率纹理的多边形几何体(jpeg
或png
尺寸为 1024x1024 的正常尺寸)。
此外,RealityKit 默认heavy
启用了几个选项 -Depth channel Compositing
和(在 A11 及更早版本上Motion Blur
,Ray-traced Contact Shadows
有投影阴影)。如果您不需要所有这些功能,只需禁用它们即可。之后,您的应用程序将更快。
实用方案一
(阴影、运动模糊、深度补偿等被禁用)
使用以下属性禁用处理器密集型效果:
override func viewDidLoad() {
super.viewDidLoad()
arView.renderOptions = [.disableDepthOfField,
.disableHDR,
.disableMotionBlur,
.disableFaceOcclusions,
.disablePersonOcclusion,
.disableGroundingShadows]
let boxAnchor = try! Experience.loadBox()
arView.scene.anchors.append(boxAnchor)
}
实用方案二
(默认启用阴影、深度补偿等)
在 RealityKit 中使用以下代码时:
override func viewDidLoad() {
super.viewDidLoad()
let boxAnchor = try! Experience.loadBox()
arView.scene.anchors.append(boxAnchor)
}
您将获得 Reality Composer 的预配置场景,其中包含水平面检测属性并AnchorEntity
具有以下设置:
AnchorEntity(.plane(.horizontal,
classification: .any,
minimumBounds: [0.25, 0.25])
将跟踪和场景理解与模型加载和渲染分开
您遇到的问题是您的应用程序启动时发生的时间延迟。同时开始世界跟踪(第一阶段),然后应用程序同时尝试检测水平面(第二阶段),然后渲染立方体的金属着色器(第三阶段)。要摆脱这种时间延迟,请使用这种非常简单的方法(当应用程序启动时,您需要跟踪房间,然后点击屏幕以加载模型):
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self,
action: #selector(self.tapped))
arView.addGestureRecognizer(tap)
}
@objc func tapped(_ sender: UITapGestureRecognizer) {
let boxAnchor = try! Experience.loadBox()
arView.scene.anchors.append(boxAnchor)
}
这样可以减少 CPU 和 GPU 上的同时负载。所以你的立方体加载速度更快。
附言
此外,作为替代方案,您可以使用loadModelAsync(named:in:)
允许您从包中的文件异步加载模型实体的类型方法:
static func loadModelAsync(named name: String,
in bundle: Bundle?) -> LoadRequest<ModelEntity>