見出し画像

【ARKit】SCNNodeのrenderingOrderとSCNMaterialのcolorBufferWriteMaskとwritesToDepthBufferについて

ARKitでオクルージョンを実現するのに、

geometry.firstMaterial!.colorBufferWriteMask = []
occlusionNode = SCNNode(geometry: geometry)
occlusionNode.renderingOrder = -1

とするテクニックがある。Appleのフェイストラッキングのサンプルで使われている。(仮想のメガネが、鼻の影にちゃんと隠れる)

このrenderingOrderについては結構日本語でも説明がある。

最後のappleengineさんの記事のサンプルがGitHubにもあって、これで各ノードのrenderingOrderを変えたりしてみると理解が捗る。

で、renderingOrderはその名の通り「レンダリング順」を指定するプロパティで、「数値が低いほうが先に描画される」という説明がされていることが多いんだけど、renderingOrderでオクルージョンを実現できることを理解するにはSCNMaterialのcolorBufferWriteMaskとwritesToDepthBufferについても理解したほうがより腹落ちするかなと思ったので本記事で補足してみる。

たとえば、

occlusionNode = SCNNode(geometry: geometry)
occlusionNode.renderingOrder = 100

これでocclusionNodeのレンダリング順はめっちゃ後ろだから、occlusionNodeより後ろの物体が隠れないかというと、隠れる。occlusionNodeが白く描画されて普通に見えるようになるので、いやそりゃ隠れるのは当然でしょと思われるかもしれないが、とにかくこれが物体が後方にある物体を覆い隠すかどうかはレンダリング順だけで説明がつかないということがいえる。

また、renderingOrderを用いたオクルージョンは、「見えない」ノードのレンダリング順を前にすることで、カメラに対して後方にある物体を覆い隠すというテクニックなんだけど、「見えない」といっても、hiddenなノードや、opacityが0なノード、マテリアルのtransparencyが0の場合等はレンダリング順が前であっても後方のノードを覆い隠さない

transparencyを0.00001とかの極小に設定すると後方オブジェクトを見えないオブジェクトで覆い隠せるようになるんだけど、これってどういうことなんだろうか?

で、ポイントになるのが最初のコードのこれ:

geometry.firstMaterial!.colorBufferWriteMask = []

これをやると、マテリアルのtransparencyを0.00001に設定したりする必要がない。これは何をしているのか?

このcolorBufferWriteMaskはググっても日本語記事は見当たらない。そしてなんと公式ドキュメントにも何も書いてない。

ヘッダにはちょっと説明が書いてある:

Determines whether the receiver writes to the color buffer when rendered. Defaults to SCNColorMaskAll.

ここから先は

989字
文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/