オクルージョンカリングは、あるオブジェクトが他のオブジェクトに隠されていて現在カメラに映らないときに、オブジェクトのレンダリングを無効にする機能です。これは、3D コンピュータグラフィックスでは自動的に行われません。カメラからもっとも遠いオブジェクトが最初に描かれ、近いオブジェクトは、それらの上に描画されるからです(これは “overdraw” と呼ばれています)。オクルージョンカリングは、フラスタムカリングとは違います。フラスタムカリングは、カメラの表示領域外にあるオブジェクトのレンダラーを無効にしますが、“overdraw”よって視界から隠されたものについては無効にしません。オクルージョンカリングを使用するときには、まだフラスタムカリングの効果も有効なことに注意してください。
オクルージョンカリングの処理では、まず仮想的なカメラを使ってシーン全体をスキャンし、可視状態になり得るオブジェクトの階層構造を生成します。ゲームの実行時には各カメラがこのデータを利用して、可視か不可視かを識別します。その識別結果を利用して、Unity は可視状態のオブジェクトだけを描画します。その結果、ドローコール数が減少し、ゲームのパフォーマンスが向上します。
オクルージョンカリングに用いられるデータは複数のセル( Cell )で構成されています。各セルはシーン全体のバウンディングボリューム( Bounding Volume )を分割したものです。ちなみに、より詳細にはこれらのセルは 二分木を構成しています。オクルージョンカリングは二つの木構造データを使います。一つは View Cells (静的オブジェクト向け)で、もう一つは Target Cells (移動するオブジェクト向け)です。View Cells は可視の静的オブジェクトのインデックスに紐付けられていて、静的オブジェクト向けにより正確なカリング結果を提供するために使われます。
ゲームオブジェクトを作成するときには、このセルのことを理解しておくとよいでしょう。なぜなら、ゲームオブジェクトのサイズと、セルのサイズのバランスをうまい具合に取る必要があるからです。オブジェクトに対して小さすぎるセルや、逆に複数のセルにまたがるようなオブジェクトも作るべきではありません。大きなオブジェクトを小さなピースに分割することで、カリングの効果を向上することができるかもしれません。しかしながら、その一方ではドローコールを削減するためには小さなオブジェクトをマージすることもできます。そして、同じセルに含まれているオブジェクト同士にはオクルージョンカリングの効果は発動しない、という点も注意が必要です。
“overdraw” シーン描画モードを使用すれば、行われているオーバードローの量が分かります。またゲームビューの Stats 情報ウィンドウでは、描画されている三角形、頂点、バッチの量を見ることができます。以下の画像はそれらの、オクルージョンカリングの適用前と適用後の比較です。
オクルージョンカリングを利用するにあたっては、いくつかの設定が必要になります。まず、ジオメトリのレベルをちょうどいい大きさのピースに分割しておかなければなりません。さらにレベルを明確に定義し、できるだけ小さなエリアごとにまとまるように配置することもお勧めします。例えば、エリアの粒度はレベルに存在する壁やビルなどの非常に大きなオブジェクトに一度に閉塞されるようなもの同士がまとまる程度にするとよいでしょう。この考え方は、個々のメッシュがオクルージョンのデータに基づいて有効化または無効化されるというものです。したがって、例えばレベルにたった一つのオブジェクトしか無く、しかもその中に部屋とすべての家具のメッシュが含まれているような場合には、すべてがカリングされるか、または何もカリングされないか、の 2 択になってしまいます。これでは意味がありません。また、家具のパーツごとにメッシュをわけて、それぞれのパーツがカメラの視点に基づいてカリングされるようにする、ということも同じくらい意味がありません。
シーン内でオクルージョンを適用するすべてのオブジェクトには Inspector 内で Occluder Static タグをつける必要があります。これを行う方法は、オクルージョンの計算に含めたいオブジェクトを複数選択し、Occluder Static および Occludee Static のチェックマークをつけることです。
Occludee Static をどのような場合に利用できるか説明します。他のオブジェクトを遮ることがない透明なオブジェクトや小さなオブジェクトには、Occluders ではなく Occludees のチェックマークをつけるべきです。このチェックマークが付けられたオブジェクトは、他のオブジェクトによる遮蔽判定のときには考慮され、遮蔽する側として判定された場合には無視されます。これにより計算コストが下がります。
オクルージョンカリングに関して何か操作するときは、Occulusion Culling ウィンドウ (Window->Occlusion Culling) を利用するとよいでしょう。
Occulusion Culling ウィンドウでは、遮蔽するメッシュの設定や、オクルージョンエリア の設定が行えます。
Occlusion Culling ウィンドウ の Object タブで、メッシュレンダラー を選択している場合は、Static 関連のフラグを変更することができます。
Occlusion Culling ウィンドウ の Object タブで、オクルージョンエリア を選択している場合は、オクルージョンエリア関連のプロパティーを変更することができます(詳細については、オクルージョンエリア を参照してください)。
メモ: オクルージョンエリアを一つも作成していない場合は、デフォルトではシーン全体にオクルージョンカリングが適用されます。
注意: カメラがオクルージョンエリア外にある場合、オクルージョンカリングは適用されません。したがって、カメラが移動する可能性のある場所をオクルージョンエリアに設定しておくことがいいです。しかし、オクルージョンエリアをあまりに大きしすぎると、今度はベイク処理に時間がかかってしまいます。
オクルージョンカリング bake ウィンドウには、Unity のデフォルト値にベイク値をリセットすることができる “Set Default Parameters” ボタンがあります。多くの場合、典型的なシーンに適しています。しかし、シーンの内容に合わせて値を調整することによって、さらに良くなるかもしれません。
プロパティー | 説明 |
---|---|
Smallest Occluder | オクルージョンカリングを行う際に、他のオブジェクトを非表示にするために使用されるオブジェクトの最小サイズです。このサイズよりも小さなオブジェクトは、それらによってオクルージョンされたオブジェクトをカリングすることはありません。たとえば、値が5の場合では、5メートルより高いまたは広いすべてのオブジェクトは、その背後に隠れたオブジェクトがカリングされることになります(レンダリングされず、レンダリング時間を節約します)。このプロパティーのよい値を選ぶことによって、オクルージョンデータのためにオクルージョンの精度とストレージのサイズのバランスをとることができます。 |
Smallest Hole | この値は、カメラから見ることのできるジオメトリ間のもっとも小さな隙間を表します。値は、穴を通り抜けることができたオブジェクトの直径です。シーンでは、カメラが見ることができる非常に小さな隙間がある場合、最小の穴の値は隙間より小さくなければなりません。 |
Backface Threshold | Unity のオクルージョンは裏面をテストすることで、不必要な詳細を削減し、データサイズの最適化しています。デフォルト値の100は、堅牢で、データセットから裏面を削除することはありません。もし値が5ならば、目に見える裏面との位置に基づいて多くのデータを減少させるでしょう。この考え方は一般的に、カメラ位置は、多く場合裏面が表示されないことです。- 例えば、地形の下のビュー、または、到達できないような固体オブジェクトの中からビューです。閾値が100未満なら、Unity は、完全にデータセットから、これらのエリアを削除します。これにより、オクルージョンのためのデータサイズを削減します。 |
Bake タブの下部に Clear と Bake ボタンがあります。オクルージョンカリングデータの生成を開始するために Bake ボタンをクリックします。データが生成されたら、プレビューし、オクルージョンカリングをテストするために Visualization タブを使用することができます。結果に満足できない場合、以前に計算されたデータを削除するために Clear ボタンをクリックします。その後、設定を調整して再度ベイクしてください。
バウンディングボリュームのサイズはシーン内のすべてのオブジェクトに影響されるため、できるだけすべてのオブジェクトがシーンの可視領域に収まるようにしてください。
オクルージョンデータを生成する準備ができたら、Bake ボタンをクリックしましょう。その際、Bake タブにある Memory Limit の値を正しく選択しましょう。この値が小さいほどデータの生成は高速になり、内容は不正確になります。逆に値が大きいほどリリースに向けた製品レベルのクオリティーに近づいていきます。
オクルージョンデータの生成にかかる時間はセルの詳細さとデータサイズ、選択したクオリティーに左右されることに注意してください。
生成処理が完了したら、ビューエリアにカラフルな立方体が表示されます。この立方体と同じ色に着色されている領域は、それぞれ同じオクルージョンデータを共有しています。
Clear ボタンをクリックすると、オクルージョンカリングのために以前に計算されたデータを消去できます。
オクルージョンカリングを適用するためには Occlusion Area を作成し移動オブジェクトが配置される場所となるようサイズを修正する必要があります(当然、移動するオブジェクトを Static とすることはできません)。Occlusion Area を作成するためには、空のゲームオブジェクトに Occlusion Area コンポーネントを追加します。(メニューで Component -> Rendering -> Occlusion Area を選択)
Occlusion Area を作成した後 Is View Volume チェックボックスをオンにして動くオブジェクトをオクルージョン(無視)します。
プロパティー: | 説明: |
---|---|
Size | オクルージョンエリアのサイズを定義 |
Center | オクルージョンエリアの中心を設定します。デフォルトでは、( 0, 0, 0 )であり、ボックスの中央に位置しています。 |
Is View Volume | カメラを配置できる場所を定義します。Occlusion Area 内にある Static オブジェクトをオクルージョンするときオンにします。 |
Occlusion Area を作成した後、箱をセルに分割する方法を確認する必要があります。Occlusion Area がどのように算出されたか確認するためには Edit を選択し、オクルージョンカリングプレビューパネル( Occlusion Culling Preview Panel ) で ビュー( View ) をトグルして選択してください。
Occlusion Area を作成した後、箱をセルに分割する方法を確認する必要があります。Occlusion Area がどのように算出されたか確認するためには Edit を選択し、オクルージョンカリングプレビューパネル( Occlusion Culling Preview Panel )でビュー( View )をトグルして選択してください。 Occlusion Culling プレビューパネル
オクルージョンをセットアップした後、Occlusion Culling をオンにして( Visualize mode の Occlusion Culling Preview Panel 上で)、メインカメラ をシーンビューの中で移動することでテストを行うことができます。
メインカメラを移動するのに合わせ( Play モードでない場合も)、オブジェクトが無効( disable )となることを確認できますオクルージョンデータでエラーが出ないことを確かめる必要があります。移動するのにあわせオブジェクトがビューに割り込んできたらエラーであると認識できますこの場合、エラーを修正するためにオプションとしては画面解像度を変更する( Target Volumes を変更していた場合)か、オブジェクトを移動してエラーが出ないようにする方法があります。オクルージョンでデバッグをするためにはメインカメラを問題が発生しているポジションに移動してスポットでチェックを行うことができます。
処理が完了するとビューエリアでカラフルなキューブを確認することができます。青いキューブは Target Volumes ( Target Volume )のセル分割を意味しています。白いキューブは View Volumes ( View Volume )のセル分割を意味しています。もしパラメーターが正しく設定されていればいくつかのオブジェクトはレンダリングされません。その理由はカメラのビュー範囲(円錐状)の外にあるか、他のオブジェクトの配置により無視されているか、のいずれかになります。
オクルージョンが完了した後、シーン上で何もオクルージョンされない場合、オブジェクトをより小さなパーツに分解しそのオブジェクトがセルの中に納まるサイズに小分けします。