更新日期:2021 年 7 月 4 日。
由于新的深度 API和可以以 60 fps 捕获的更高质量的 ZDepth 通道,您可以提高 ARKit 5.0/4.0/3.5 的质量People Occlusion
和功能。但是,为此您需要配备激光雷达扫描仪的 iPhone 12 Pro 或 iPad Pro。Object Occlusion
People Occlusion
但在 ARKit 3.0 中,除非您使用 Metal 或 MetalKit,否则您无法改进功能。People Occlusion
然而,使用 Metal 系列框架在 ARKit 3.0中改进并不容易,相信我。
提示:考虑RealityKit和AR QuickLook框架也支持People Occlusion
。
为什么在使用 People Occlusion 时会出现此问题?
这是由于第五通道的性质——ZDepth
通道。我们都知道,渲染的 3D 场景最终图像可以包含 5 个用于数字合成的主要通道 - Red
、Green
、Blue
、Alpha
和ZDepth
。
当然,还有其他有用的渲染通道(也称为 AOV)可用于合成: Normals
、MotionVectors
、PointPosition
、UVs
、Disparity
等。但这里我们只对两个主要渲染集感兴趣 -RGBA
和ZDepth
.
ZDepth 通道在 ARKit 3.0 中有三个严重的缺陷。
问题 1. ZDepth 的锯齿和抗锯齿。
在任何高端软件(如 Nuke、Fusion、Maya 或 Houdini)中渲染 ZDepth 通道,默认情况下会导致锯齿状边缘或所谓的锯齿边缘。游戏引擎也不例外——SceneKit、RealityKit、Unity、Unreal 或 Stingray 也有这个问题。
当然,您可以说在渲染之前我们必须打开一个名为Anti-aliasing
. 而且,是的,它几乎适用于所有通道,但不适用于 ZDepth。ZDepth 的问题是 – 每个前景对象(特别是如果它是透明的)的边界像素被“转换”为背景对象,如果anti-aliased
. 换句话说,FG和BG的像素混合在FG对象的边缘。
坦率地说,有一个解决深度问题的有效解决方案——你应该使用 aDeep channel
而不是 a ZDepth channel
。但是没有一个游戏引擎支持它,因为它Deep channel
非常庞大。所以深度通道合成既不适用于游戏引擎,也不适用于 ARKit。唉!
问题 2. ZDepth 的分辨率。
常规ZDepth通道必须以32 位渲染,即使RGB和Alpha通道都是8 位的。32 位文件的颜色位深度对 CPU 和 GPU 来说是一个沉重的负担。记住在 ARKit 视口中合成多个图层——这里是前景字符在 3D 模型和背景字符上的合成。你不觉得这对你的设备来说太多了吗,即使这些是在视口分辨率而不是真实屏幕分辨率下合成的?但是,将ZDepth通道渲染为16 位或8 位 compresses
真实场景的深度,会降低合成质量。
为了减轻 CPU 和 GPU 的负担并节省电池寿命,Apple 工程师决定在捕获阶段使用缩小的 ZDepth 图像,然后将渲染的 ZDepth 图像放大到视口分辨率并使用Alpha 通道(又名分割),然后使用扩张合成操作修复 ZDepth 通道的边缘。因此,这导致了我们可以在您的照片中看到的令人讨厌的人工制品(某种“线索”)。
请查看此处的演示文稿幻灯片 pdf。Bringing People into AR
问题 3. ZDepth 的帧率。
第三个问题源于 ARKit 以60 fps的速度工作。仅降低 ZDepth 图像分辨率并不能完全解决问题。因此,Apple 工程师的下一个合乎逻辑的步骤是——在 ARKit 3.0 中将 ZDepth 的帧速率降低到15 fps。然而,最新版本的 ARKit 5.0 以 60 fps 的速度捕获 ZDepth 通道,这大大提高了人物遮挡和物体遮挡的质量。但在 ARKit 3.0 中,这也带来了伪影(ZDepth 通道的某种“丢帧”会导致“轨迹”效果)。
当您使用类型属性时,您无法更改最终合成图像的质量:
static var personSegmentationWithDepth: ARConfiguration.FrameSemantics { get }
因为它是一个可获取的属性,并且在 ARKit 3.0 中没有 ZDepth 质量设置。
当然,如果你想在 ARKit 3.0 中增加 ZDepth 通道的帧速率,你应该实现在数字合成中发现的帧插值技术(其中帧之间是计算机生成的帧):
但是这种帧插值技术不仅占用大量 CPU,而且非常耗时,因为我们需要每秒生成 45 个额外的 32 位 ZDepth 帧(45 个插值 + 15 个实数 = 60 帧每秒)。
我相信有人可能会通过使用 Metal 开发代码来改进 ARKit 3.0 中的 ZDepth 合成功能,但现在这是一个真正的挑战!
您必须在此处People Occlusion in Custom Renderers
查看应用程序的示例代码。
ARKit 5.0 和 LiDAR 扫描仪支持
在 ARKit 5.0、ARKit 4.0 和 ARKit 3.5 中,支持 LiDAR(Light Detection And Ranging
扫描仪)。LiDAR 扫描仪提高了人物遮挡功能的质量和速度,因为 ZDepth 通道的质量更高,即使您在跟踪周围环境时没有物理移动。LiDAR 系统还可以帮助您绘制墙壁、天花板、地板和家具的地图,以快速获得真实世界表面的虚拟网格,以便与其动态交互,或者简单地定位其上的 3d 对象(甚至是部分遮挡的 3d 对象)。具有 LiDAR 扫描仪的小工具可以实现无与伦比的精度,以检索真实世界表面的位置。通过考虑网格,光线投射可以与非平面表面或完全没有特征的表面相交,例如白墙或几乎没有照明的墙。
要激活sceneReconstruction
选项,请使用以下代码:
let arView = ARView(frame: .zero)
arView.automaticallyConfigureSession = false
let config = ARWorldTrackingConfiguration()
config.sceneReconstruction = .meshWithClassification
arView.debugOptions.insert([.showSceneUnderstanding, .showAnchorGeometry])
arView.environment.sceneUnderstanding.options.insert([.occlusion,
.collision,
.physics])
arView.session.run(config)
但sceneReconstruction
在您的代码中使用实例属性之前,您需要检查设备是否具有 LiDAR 扫描仪。您可以在AppDelegate.swift
文件中执行此操作:
import ARKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
guard ARWorldTrackingConfiguration.supportsSceneReconstruction(.meshWithClassification)
else {
fatalError("Scene reconstruction requires a device with a LiDAR Scanner.")
}
return true
}
}
RealityKit 2.0
在 iPhone 12 Pro 或 iPad Pro 上使用 RealityKit 2.0 应用程序时,您有多个遮挡选项——在 ARKit 5.0 中提供相同的选项——改进 People Occlusion
的, Object Occlusion
(例如家具或墙壁)和Face Occlusion
. 要在 RealityKit 2.0 中打开遮挡,请使用以下代码:
arView.environment.sceneUnderstanding.options.insert(.occlusion)