web-dev-qa-db-ja.com

ARKitはオブジェクトを壁の後ろに隠します

ARKitによって追跡される水平面および垂直面を使用して、オブジェクトを壁の後ろ/実際のオブジェクトの後ろに隠すにはどうすればよいですか?現在、3Dで追加されたオブジェクトは、部屋を出るとき、および/または背後にあるべきオブジェクトの前に、壁を通して見ることができます。 ARKitが提供するデータを使用して、壁を通してオブジェクトが表示されずに、より自然なARエクスペリエンスを提供することは可能ですか?

27
Steve

ここには2つの問題があります。

(そして、あなたも 正規表現を使用

ARKit/SceneKitのオクルージョンジオメトリを作成する方法

SceneKitマテリアルの colorBufferWriteMask を空の値([](Swift)では、そのマテリアルを使用するオブジェクトはビューに表示されませんが、レンダリング中は引き続きzバッファーに書き込まれ、他のオブジェクトのレンダリングに影響します。実際には、オブジェクトのような形の「穴」ができます。この穴を通して、背景(ARSCNViewの場合はカメラフィード)が表示されますが、他のSceneKitオブジェクトを隠すことができます。

また、隠されている他のノードの前に、オクルードされたものがレンダリングされることを確認する必要があります。これは、ノード階層を使用して行うことができます(親ノードが子の前にレンダリングされるか、またはその逆にレンダリングされるかを覚えていませんが、テストするのは簡単です)。階層内のピアであるノードには確定的な順序はありませんが、 renderingOrder プロパティを使用すると、階層に関係なく順序を強制できます。このプロパティはデフォルトでゼロに設定されているため、-1に設定するとすべての前にレンダリングされます。 (またはより細かく制御するには、いくつかのノードのrenderingOrdersを値のシーケンスに設定します。)

オクルージョンジオメトリを配置する場所がわかるように、壁などを検出する方法は?

IOS 11.3以降(別名「ARKit 1.5」)では、 vertical プレーン検出をオンにできます。 (注: vertical から平面アンカーが戻ると、それらは自動的に回転します。したがって、アンカーにモデルをアタッチすると、ローカルの「上」方向はまた、iOS 11.3の新機能では、方向に関係なく、検出された各平面のより詳細な形状推定を取得できます( ARSCNPlaneGeometry を参照)。

ただし、水平および垂直がある場合でも、平面の外側の限界は時間とともに変化する推定値にすぎません。つまり、ARKitは壁の一部がどこにあるかをすばやく検出できますが、ユーザーがデバイスを振って空間をマップするために時間を費やすことなく、壁の端がどこにあるかを知りません。その場合でも、マッピングされたエッジは実際の壁のエッジと正確に一致しない場合があります。

したがって...検出された垂直面を使用して仮想ジオメトリをオクルードすると、壁の端に隠れていないか、場所を通して見えることにより、隠されるはずの仮想オブジェクトが見える場所を見つけることができますここで、ARKitは実際の壁全体をマッピングしていません。 (後者の問題は、ARKitよりも大きな範囲を想定することで解決できる場合があります。)

28
rickster

オクルージョンマテリアルを作成するのは本当に簡単です

    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
1
kakashy

優れたソリューション:

GitHub:arkit-occlusion

私のために働いた。

しかし、私の場合、コードで壁を設定したかったのです。したがって、ユーザーが壁を設定したくない場合->平面検出を使用して壁を検出し、コードで壁を設定します。

または、4メートルの範囲でiphone dephtセンサーが機能し、 ARHitTest で障害物を検出できます。

0
MoD

ホールドアウト操作(別名ブラックホールまたはブロッキングマテリアル)では、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セッションからの一連のARAnchorsです。それについて読む こちら

0
ARGeo