如何使用ARKit跟踪的水平和垂直平面隐藏墙后/真实物体后面的物体?目前,当你离开房间和/或它们应该在后面的物体前面时,可以通过墙看到3D添加的物体。那么有可能使用ARKit让我提供更自然的AR体验而不会通过墙壁出现这些物体吗?
答案 0 :(得分:26)
这里有两个问题。
(你甚至没有use regular expressions!)
如果您将SceneKit材质的colorBufferWriteMask
设置为空值(Swift中的[]
),则使用该材质的任何对象都不会出现在视图中,但它们&# 39;在渲染过程中仍会写入z缓冲区,这会影响其他对象的渲染。实际上,你会得到一个"洞"形状类似于您的对象,背景显示(摄像机输入,在ARSCNView
的情况下),但仍然可以遮挡其他SceneKit对象。
您还需要确保在其应该隐藏的任何其他节点之前进行遮挡渲染。你可以使用节点层次结构来做到这一点(我不能记得父节点是否在他们的子节点之前呈现或反过来,但它很容易测试)。作为层次结构中对等体的节点不具有确定性顺序,但您可以强制执行订单,而不管具有renderingOrder
属性的层次结构。该属性默认为零,因此将其设置为-1将在所有内容之前呈现。 (或者为了更好的控制,将几个节点的renderingOrder
设置为一系列值。)
在iOS 11.3及更高版本(又名" ARKit 1.5")中,您可以打开vertical
平面检测。 (请注意,当你从那里得到vertical
个飞机锚时,它们会自动旋转。所以如果你将模型附加到锚上,它们的本地方向与飞机垂直方向是正常的。 。)iOS 11.3中的新功能,您可以为每个检测到的平面获得更详细的形状估计(请参阅ARSCNPlaneGeometry),无论其方向如何。
然而,即使您有水平和垂直,平面的外部界限也只是随时间变化的估计值。也就是说,ARKit可以快速检测墙壁的哪个部分,但是它不知道墙壁的边缘在哪里,而用户不需要花费一些时间挥动设备来绘制空间。即使这样,映射的边缘也可能与真实墙壁的边缘不完全对齐。
所以......如果你使用检测到的垂直平面来遮挡虚拟几何体,你可能会发现应该被隐藏的虚拟对象透过的地方,或者是没有完全隐藏在墙的边缘,或是通过ARKit没有映射整个真实墙的地方可见。 (后一个问题你可以通过假设比ARKit更大的程度来解决。)
答案 1 :(得分:1)
创建遮挡材料非常简单
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
// Define a occlusion material
let occlusionMaterial = SCNMaterial()
occlusionMaterial.colorBufferWriteMask = []
boxGeometry.materials = [occlusionMaterial]
self.box = SCNNode(geometry: boxGeometry)
// Set rendering order to present this box in front of the other models
self.box.renderingOrder = -1
答案 2 :(得分:0)
很好的解决方案:
为我工作。
但在我的情况下,我想通过代码设置墙壁。因此,如果您不想按用户设置Walls - >使用平面检测来检测墙壁并通过代码设置墙壁。
或者在4米范围内,iphone depht传感器工作,您可以使用ARHitTest检测障碍物。
答案 3 :(得分:0)
对于保持操作(例如黑洞或阻挡材料),您可以在iOS 11和macOS 13中使用名为.colorBufferWriteMask
的实例属性。此属性在渲染材质时会写入深度通道信息。你可以这样使用它:
torus.geometry?.firstMaterial?.colorBufferWriteMask = .alpha
或者这样:
func blockingMaterial() -> SCNMaterial {
let holdout = SCNMaterial()
holdout.isDoubleSided = true
holdout.diffuse.contents = CIColor.black
holdout.colorBufferWriteMask = SCNColorMask(rawValue: 0)
return holdout
}
torus.geometry?.firstMaterial = blockingMaterial()
您可以轻松地使用此属性来遮挡隐形虚拟墙。要将这些不可见的虚拟墙放置在正确的位置,可以帮助您ARWorldMap
课程(适用于iOS 12)和ARAnchors
。
session.getCurrentWorldMap { worldMap, error in
guard let worldMap = worldMap else {
showAlert(error)
return
}
}
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = worldMap
session.run(configuration)
ARWorldMap
是来自世界跟踪AR会话的空间映射状态和ARAnchor集。阅读它here。
答案 4 :(得分:0)
您可以将任何对象隐藏在复制真实墙几何图形的虚拟不可见墙后面。配备LiDAR(光检测和测距)扫描仪的iPhone 12 Pro和iPad Pro 4th Gen帮助我们重建了周围环境的3d拓扑图。 LiDAR扫描仪极大地提高了Z通道的质量,从而可以将人遮挡或从AR场景中移除。 LiDAR还改进了诸如对象遮挡,运动跟踪和光线投射等功能。使用LiDAR扫描仪,您甚至可以在光线昏暗的环境中或在白墙根本没有任何功能的房间中重建场景。借助sceneReconstruction
实例属性,ARKit 3.5中的周围环境3D重建成为可能。有了墙的重建网格,现在可以轻松地将任何对象隐藏在真实的墙后面。
要在ARKit 3.5中激活sceneReconstruction
实例属性,请使用以下代码:
arView.automaticallyConfigureSession = false
guard ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh)
else { return }
let config = ARWorldTrackingConfiguration()
config.sceneReconstruction = .mesh
arView.debugOptions.insert([.showSceneUnderstanding])
arView.environment.sceneUnderstanding.options.insert([.occlusion])
arView.session.run(config)