Swift 如何在Arkit3.0中改进人的遮挡

Swift 如何在Arkit3.0中改进人的遮挡,swift,augmented-reality,scenekit,arkit,realitykit,Swift,Augmented Reality,Scenekit,Arkit,Realitykit,我们正在使用ARKit中的人眼遮挡功能开发一个演示应用程序。因为我们希望在最终场景中添加视频,所以我们使用SCNPlanes来使用SCNBillboardConstraint渲染视频,以确保它们朝向正确的方向。这些视频也是部分透明的,使用我们应用的scnmatary上的自定义着色器(因此一次播放两个视频) 现在我们有一些问题,人们的遮挡非常不确定(见图)。我们用来测试的视频是一个穿着深色裤子和裙子的女人(如果你想知道图片中的黑色是什么的话) 我们面临的问题是,遮挡并不总是与人对齐(如图中所示),

我们正在使用ARKit中的人眼遮挡功能开发一个演示应用程序。因为我们希望在最终场景中添加视频,所以我们使用
SCNPlane
s来使用
SCNBillboardConstraint
渲染视频,以确保它们朝向正确的方向。这些视频也是部分透明的,使用我们应用的
scnmatary
上的自定义着色器(因此一次播放两个视频)

现在我们有一些问题,人们的遮挡非常不确定(见图)。我们用来测试的视频是一个穿着深色裤子和裙子的女人(如果你想知道图片中的黑色是什么的话)

我们面临的问题是,遮挡并不总是与人对齐(如图中所示),而且人的头发也不总是被正确检测到

现在我们的问题是,是什么导致了这些问题?我们如何才能改善这些问题,直到它们看起来像这样?我们目前正在探索问题是否是因为我们使用的是平面,但仅仅使用
SCNBox
并不能解决问题


更新日期:2020年10月29日

由于新的深度API和更高质量的ZDepth通道,您可以提高ARKit 4.0中
人物遮挡
对象遮挡
功能的质量,该通道可以以60 fps的速度捕获。不过,要实现这一点,您需要iPhone12Pro或第四代iPadPro2020,以及激光雷达扫描仪

但在Arkit3.0中,除非您使用Metal或MetalKit,否则无法改进
人员遮挡
功能。不过,相信我,在Arkit3.0中,使用金属族框架改进
人员遮挡
并不容易

<强> ToP:考虑<强>实际工具包和<强> AR快速查看< /强>框架支持<代码>人遮挡< /代码>。


为什么在使用人员遮挡时会出现此问题? 这是由于第五频道的性质——
ZDepth
频道。我们都知道,3D场景的渲染最终图像可以包含5个用于数字合成的主通道—
红色
绿色
蓝色
阿尔法

当然,还有其他有用的渲染过程(也称为AOV)用于合成:
法线
运动向量
点位置
UV
视差
,等等。但这里我们只对两个主要渲染集感兴趣—
RGBA
ZDepth


ZDepth通道在Arkit3.0中有三个严重的缺点。 问题1ZDepth的混叠和反混叠

在任何高端软件(如Nuke、Fusion、Maya或Houdini)中渲染ZDepth通道,默认情况下会产生锯齿边或所谓的锯齿边。游戏引擎也不例外——SceneKit、RealityKit、Unity、Unreal或Stingray也有这个问题

当然,您可以说,在渲染之前,我们必须启用名为
抗锯齿的功能。而且,是的,它几乎适用于所有频道,但不适用于ZDepth。ZDepth的问题是–每个前景对象(尤其是透明对象)的边界像素都会“转换”为背景对象,如果
抗锯齿
。换句话说,FG和BG的像素在FG对象的边界上混合

坦率地说,有一种解决深度问题的有效方法–您应该使用
深度频道
而不是
ZDepth频道
。但是没有一个游戏引擎支持它,因为深度频道非常庞大。因此,深度频道comp既不适用于游戏引擎,也不适用于ARKit。唉


问题2ZDepth的分辨率

即使RGBAlpha通道都是8位的,常规ZDepth通道也必须以32位的进行渲染。32位文件的颜色位深度对CPU和GPU来说是一个沉重的负担。还记得在ARKit视口中合成几个层吗?这里是在3D模型和背景角色上合成前景角色。你不觉得这对你的设备来说太多了吗,即使这些设备是在真实的屏幕上合成的而不是在真实的屏幕上合成的?但是,在16位或8位
中渲染ZDepth通道会压缩真实场景的深度,从而降低合成质量

为了减轻CPU和GPU的负担并节省电池寿命,苹果工程师决定在捕获阶段使用缩小的ZDepth图像,然后将渲染的ZDepth图像放大到视口分辨率,并使用Alpha通道(也称为分段)制作模具然后使用
放大
合成操作固定ZDepth通道的边缘。因此,这让我们找到了在你的照片上可以看到的令人讨厌的人工制品(某种“痕迹”)

请看《将人们带入AR》的pdf演示幻灯片


问题3ZDepth的帧速率

第三个问题源于ARKit以每秒60帧的速度工作。仅降低ZDepth图像分辨率并不能完全解决问题。因此,苹果工程师的下一个合乎逻辑的步骤是——在Arkit3.0中将ZDepth的帧速率降低到15fps。然而,最新版本的ARKit 4.0以60 fps的速度捕获ZDepth通道,这大大提高了人员遮挡和对象遮挡的质量。但在Arkit3.0中,这也带来了伪影(ZDepth channel wh的某种“下降帧”)
static var personSegmentationWithDepth: ARConfiguration.FrameSemantics { get }
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)
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
    }
}
arView.environment.sceneUnderstanding.options.insert(.occlusion)