首页 文章

ARKit隐藏墙后的物体

提问于
浏览
23

如何使用ARKit跟踪的水平和垂直平面隐藏墙后/真实物体后面的物体?目前,当你离开房间和/或它们应该在后面的物体前面时,可以通过墙看到3D添加的物体 . 那么有可能使用ARKit让我提供更自然的AR体验而不会通过墙壁出现这些对象吗?

4 回答

  • 0

    你有两个问题 .

    (你甚至没有使用正则表达式!)

    如何为ARKit / SceneKit创建遮挡几何?

    如果将SceneKit材质的colorBufferWriteMask设置为空值(Swift中的 [] ),则使用该材质的任何对象都会在渲染过程中仍然写入z缓冲区,这会影响其他对象的渲染 . 实际上,你会得到一个像你的对象一样的形状,背景显示(相机输入,在 ARSCNView 的情况下),但仍然可以遮挡其他SceneKit对象 .

    你应该晦涩难懂 . 你可以使用节点层次结构来做到这一点(我可以很容易地测试) . 作为层次结构中对等方的节点没有确定性顺序,但您可以使用renderingOrder属性强制执行任何层次结构的顺序 . 该属性默认为零,因此将其设置为-1将在所有内容之前呈现 . (或者为了更精细的控制,将几个节点的 renderingOrder 设置为一系列值 . )

    如何检测墙/等,以便知道遮挡几何的位置?

    在iOS 11.3及更高版本(又名"ARKit 1.5")中,您可以打开vertical平面检测 . (注意,当你从那里得到vertical平面锚点时,它们会自动旋转 . 所以如果你将模型附加到锚点,它们的局部"up"方向与飞机垂直 . )在iOS 11.3中也是新的,你可以获得更多每个检测到的平面的详细形状估计(参见ARSCNPlaneGeometry),无论其方向如何 .

    但是,即使您具有水平和垂直,平面的外部界限也只是随时间变化的估计值 . 也就是说,ARKit可以快速检测墙壁的哪个部分,但是如果没有用户花费一些时间挥动设备来绘制空间,它就不知道墙壁的边缘 . 即使这样,映射的边缘也可能与真实墙壁的边缘不精确对齐 .

    因此......如果您使用检测到的垂直平面遮挡虚拟几何体,您可能会发现应该隐藏的虚拟对象显示的位置,或者通过不是完全隐藏在墙的边缘,或者通过位置可见其中ARKit没有映射整个真实墙 . (后一个问题你可以通过假设比ARKit更大的范围来解决 . )

  • 0

    好方案:

    GitHub: arkit-occlusion

    为我工作 .

    但在我的情况下,我想通过代码设置墙 . 因此,如果您不想按用户设置墙壁 - >使用平面检测来检测墙壁并按代码设置墙壁 .

    或者在4米的范围内,iphone depht传感器工作,您可以使用ARHitTest检测障碍物 .

  • 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()
    

    您可以轻松地使用此属性来遮蔽隐形虚拟墙 . 要将这些不可见的虚拟墙放置到正确的位置,可以帮助您(类似于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 .

  • 25

    为了创建一个遮挡材料,它非常简单

    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
    

相关问题