テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】Occlusion Portalについて

モデルが非表示になっている部分をスキップすることで3D空間を効率的に描画するOcclusion Cullingという機能の機能の一つ、Occlusion Portalsという機能についてです。

 

Occlusion Portalsという機能

Occlusion Portalsはマニュアルによると以下のように説明されています。

実行時にオープン・クローズが可能であるオクルージョンプリミティブを作成するには、Unity では オクルージョンポータル を使用します。

 

実際の動作と仕様が混ざって少し分かりにくい説明ですが、このOcclusion Portalsは要するにOcclusion Cullingによる遮蔽の有効・無効が切り替えられる壁を作る機能です。

 

どんなときに使えるのか

分かりやすく役に立つシーンは、ドアを開いて屋内に入るようなケースです。試しに下のような画像にOcclusion Portalsを設定してみます。

  • 四角い部屋にドアがある
  • 部屋の中に色々と物がある
  • 部屋の外にも色々と物がある

f:id:tsubaki_t1:20180106232500j:plain

 

まず最初の状態です。部屋の中には物がありますが、Occlusion Cullingが効いているので表示されません。
ドアの向こうには何があるのか分からない状態です。

f:id:tsubaki_t1:20180106232327j:plain

ドアを空けます。
部屋の中に何があるのかが明らかになります。

f:id:tsubaki_t1:20180106232632j:plain

部屋に入り振り向きます。
部屋の中と外にある玉を確認することができています。

f:id:tsubaki_t1:20180106232726j:plain

ドアを閉じます。

部屋の外は確認できなくなるので描画対象から外されます。

f:id:tsubaki_t1:20180106232815j:plain

 

このポイントはOcclusion CullingのOccluder(遮る側)を動的に有効/無効を切り替えられる点です。

移動や動的な配置は出来ませんが、ドアのような遮ったり遮らなかったりするような物をOcclusion Cullingで使用する場合に利用できます。

 

なお、Occlusion Portals内にOcclusion Cullingを作る事も出来ます。例えば部屋ではなく家の場合、外から見る際にはOcclusion Portalsで内側全部を非表示にしておき、家に入ると家内のOcclusion Cullingを起動する…みたいな感じ。

 

実際に使用してみる

実際に以下のような動きを設定してみます。

f:id:tsubaki_t1:20180107015719j:plain

f:id:tsubaki_t1:20180106235533g:plain

 

簡単なステージの用意

まず下のようなシーンを用意します。

緑のシリンダーが複数存在し、白と赤の壁が遮っています。

f:id:tsubaki_t1:20180106234932j:plain

 

OccluderとOccludeeの設定

色分けは、これから行う設定をわかりやすくするために分けています。

  • 白:Occluder Staticを設定します。
  • 緑:Occludee Staticを設定します。
  • 赤:特に何も設定しない。移動する予定の壁

Occluderは遮る側、Occludeeは遮られる側を定義するstaticです。Occludeeは無くとも動作しますが、設定したほうが安定かつ高速な印象です。

Occluderは無駄に設定すると負荷が高くなるので、大きい壁等に使うと良い感じです。

f:id:tsubaki_t1:20180106235911j:plain

 

Occlusion Portalsの設定

動く赤い壁(門)の設定です。
この壁はカリングしたりしなかったりするので、Occlusion Portalを使用します。

 

Occlusion Portalを設定したGameObjectを配置し、範囲を赤い壁を囲うように設定します。(緑色の枠がOcclusion Portalです)

下の図では大げさに範囲を指定していますが、実際にはもう少しタイトな感じに設定したほうが良いです。理由は後述。

f:id:tsubaki_t1:20180107000443j:plain

 

Occlusion Cullingのベイク

Occlusion Cullingをベイクします。(Window > Occlusion Culling > Bakeボタン)
シーンが保存されていないと失敗することがあります。

f:id:tsubaki_t1:20180107001152j:plain

ベイク時にSmallest Occluder(遮るオブジェクトの最小サイズ)が5くらい巨大だと上手く遮られない事があるので、少し小さめな値を設定しておきます。壁の幅は7mですが幅が1mなので1くらいに設定。

 

ベイクに時間がかかるならOcclusion AreaでOccluderの範囲を限定しとくと良いです。

準備はこれでおしまいです。

 

開閉のテスト

うまく動作するかをテストします。

動作をテストするにはFrame Debuggerを使用…は最終手段です。まずはOcclusion Cullingの拡張で動作を確認します。

以下の手順で、Occlusion Cullingの表示範囲を判定する為のラインをシーンビューにオーバーレイ表示できます。

  1. Occlusionウィンドウを表示
  2. シーンに表示されるOcclusion CullingのウィンドウのEditをVisualizeに変更
  3. Visibility Linesのチェックを入れる

f:id:tsubaki_t1:20180107001716j:plain

これでOcclusion Portals開閉の動作を確認します。

Open(初期設定)ではポータルは無効になり、Visibility Linesの線は貫通、壁の向こうにあるシリンダーは表示されます。

逆にClose(チェックを外す)すると線を遮り、奥のシリンダーが表示されなくなります。

f:id:tsubaki_t1:20180107002237j:plain

 

壁を遮ってしまうケース

さて、Occlusion Portalはカリング用の壁を作ります。ここで少し疑問がのこります。つまり「赤い壁自体をカリングしてしまわないのか?」という点です。

 

結論としては遮ります
概ねのケースでは問題無いでしょうが、運が悪いと赤い壁がカリングされます。そうすると、下の絵のように門の向こう側が見えてしまうといったケースも考えられます。

f:id:tsubaki_t1:20180107002749j:plain

 

Occlusion Portalを壁の内側にする

この解決方法の一つはひどく大雑把です。

カリングは「全てのメッシュがOccluderの向こうに存在する」と判断された際に行われます。逆を言えば、一部でも手前に露出しているならカリングされなくなります。
これは単純に範囲外にあるだけでなく、Smallest OccluderやBackface Thresholdなどの値、はみ出てる範囲によっても起こります。

f:id:tsubaki_t1:20180107003847j:plain

 

カリング対象外にする

上の方法でも上手く設定できない場合、RendererのDynamic Occludedを外します。これでカリングされなくなります。フラスタムカリングでさえ。

f:id:tsubaki_t1:20180107004158j:plain

 

ただ、この設定は最後の手段で出来れば「Occlusion Portalを壁の内側にする」の方法でカリングを無効にしたほうが良い印象があります。

 

Occlusion Portalの内側に潜り込む問題

「Occlusion Portalを壁の内側にする」方が良い理由は、Occlusion Portalの内側にカメラが入り込む事がある為です。

Occluderの内側にカメラが入り込むと、同一のポータル内で見える範囲しか見れなくなります。

 

例えばOcclusion Portalの奥と手前・それと中にCubeを置いた時、Occlusion Portalの中にカメラが入り込むと外側のカメラが全て遮られます。

門に使用するOcclusion Portalの範囲を広く設定している場合、門以外のモデルが非表示になる…みたいな事があるかもしれません。

f:id:tsubaki_t1:20180107010434g:plain

ちなみにOcclusion Cullingでステージの必要な部分が勝手に非表示になる的なやつは、こういった感じでOccluderにカメラがめり込んでるケースが多いです。

 

屋外・屋内のような切替ではこの挙動は便利かもしれませんが、実際に使う場合には注意が必要な挙動の一つです。

関連

Occlusion Cullingの全体的な紹介

tsubakit1.hateblo.jp

Occlusion Cullingで見える・見えないに応じてスクリプトの処理を切り替えるCulling Groupという機能

tsubakit1.hateblo.jp

Culling Groupの応用で、キャラクターが見える位置に移動したらオブジェクトを生成するアプローチ。

tsubakit1.hateblo.jp