ARKit 和 RealityKit 阶段
当您启动 AR 应用时,ARKit 和 RealityKit 分为三个阶段:
每个阶段都可能大大增加模型放置所需的时间(+1...+4 秒,具体取决于设备)。让我们来谈谈每个阶段。
跟踪
这是您的 AR 应用的初始状态。在这里,iPhone 以 60 fps 的速度混合来自 RGB 后置摄像头的视觉数据和来自 IMU 传感器(加速度计、陀螺仪和指南针)的 1000 fps 的转换数据。自动生成的 Feature Points 帮助 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、Motion Blur 和 Ray-traced Contact Shadows(在 A11 和更早版本上具有投影阴影)。如果您不需要所有这些功能,只需禁用它们即可。之后,您的应用会更快。
实用方案一
(阴影、运动模糊、深度补偿等已禁用)
使用以下属性禁用处理器密集型效果:
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>