LoginSignup
14

More than 5 years have passed since last update.

ARKitでオクルージョン

Last updated at Posted at 2018-12-10

オクルージョンとは

オクルージョンとは手前にある物体が背後にある物体を隠して見えないようにする状態のことです。

現実世界では後ろにある物体が前にある物体に隠れるのは当然ですが、ARの世界では物体の表示をうまいことコントロールしないと、前後関係がうまく表現できません。

以下にオクルージョンの例をあげます。

ナイアンティックの例

まずは、ナイアンティックの動画です。バーチャルのピカチュウが現実の人の影に隠れています。

スクリーンショット 2018-12-11 0.05.40.png
https://youtu.be/7ZrmPTPgY3I

テクテクテクテクの例

この前僕がテクテクテクテクを外苑前で使った時に撮った以下の画像もオクルージョンしてます。

tek.jpg

ARKitでオクルージョン

ARKitでも平面に関してならレンダリングを工夫すれば行うことができます。

occlusion.gif

決めてはrenderingOrderです。

renderingOrder

スクリーンショット 2018-12-10 23.43.29.png

SCNNodeのパラメータのrenderingOrderをいじるだけでオクルージョンができます。

平面検出については、[iOS 11][ARKit] 平面の検出について #WWDC2017
あたりの記事を読んでいただいた上で、以下のようなお決まりのパターンのplaneAnchorの取得から平面のNodeを置くコードを見ていきましょう。

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let planeAnchor = anchor as? ARPlaneAnchor else {
            return
        }
        let extent = planeAnchor.extent
        let plane = SCNPlane(width: CGFloat(extent.x), height: CGFloat(extent.z))
        let planeNode = SCNNode(geometry: plane)
        planeNode.name = "arPlane"
        planeNode.renderingOrder = -1
        planeNode.eulerAngles.x = -.pi/2
        node.addChildNode(planeNode)
    }
}

注目すべきなのは、

planeNode.renderingOrder = -1

これをすることで、planeNodeを描画する順番が一番最初になります。なぜならSCNNodeのrenderingOrderのデフォルト値は0だからです。

0より-1のほうが小さいので必ず先に平面が描画され、その結果、以下の赤いBoxNodeは平面と重なったときに隠れます。

occlusion.gif

別に-1じゃなくても良いんですが、-1を使うと、他のNodeには0が入ってるので手っ取り早いですね。

このrenderingOrderをコントロールすることで、例えばSceneKit の SCNNode のレンダリングオーダーでどこでもドア的表現をするのようなこともできます。

まとめ

  • 平面にNodeを貼ることができれば、その後ろに物体を隠してオクルージョンができる
  • Nodeさえ表面にうまいこと貼ることができれば机以外にもオクルージョンできるかも?

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14