今回はオクルージョンカリングを使ってみます。
Unityでは標準でフラスタムカリングという機能が働いているようです。
このフラスタムカリングはカメラの描画範囲内にあるゲームオブジェクトだけを表示し描画にかかる処理負荷を減らしています。
この場合はカメラに描画されている前面だけではなく後ろにあるゲームオブジェクトも表示されていることになります。
一方、オクルージョンカリングを有効にするとカメラの描画範囲のカメラが写している部分である前面のゲームオブジェクトのみを描画し処理負荷を減らします。
この場合はカメラで見えている部分の後ろは描画しないので処理負荷がさらに減らされます。
オクルージョンカリングを使ってみる
文章だけではわからないと思うのでサンプルを作成しオクルージョンカリングの効果を確認してみます。
サンプルのゲームステージの作成
まずはサンプルのゲームステージを作成します。
ヒエラルキー上で右クリック→Create Emptyを選択し、名前をStageとします。
その子要素に右クリック→Terrainを選択しデコボコの地形を作成します。
テラインに関しては
を参照して作成してください。
今回はサンプルの為に力を入れて作る必要はないです(‘_’)
Stageの子要素に右クリック→3D Object→Cubeを二つ作成しそれぞれTerrainの地形を遮るようにScaleを変え大きい壁にします。
片方はWallという名前にし、もう片方はTransparentWallという名前にしインスペクタでMesh Rendererのチェックを外して透明な壁にします。
↑のようにMesh Rendererのチェックを外しておきます。
作成したサンプルゲームステージは↑のような階層になります。
実際のゲームステージは↑のような感じになりました。
ゲームオブジェクトの設定をする
オクルージョンカリングを行うゲームオブジェクトにするにはそれぞれ設定をする必要があります。
TerrainはStaticにチェックを入れStatic関連のすべてのチェックが入るようにしておきます。
WallはOcculuderとOcculudeeにチェックを入れます。
今回はサンプルなのでStatic全体ではなくこの二つにチェックを入れます。
Occuluderは他のゲームオブジェクトを遮蔽するものでオクルージョンカリングを有効にした場合このチェックがあるゲームオブジェクトの後ろの見えない物は描画しないようにします。
Occuludeeは他のゲームオブジェクトに遮蔽されるものでカメラと自分の間に遮蔽するゲームオブジェクトがあった場合はこのゲームオブジェクトは描画されません。
Wallは見える壁なのでOcculuderとOcculudeeにチェックを入れどちらも行うようにします。
TransparentWallは透明な壁なので自身の後ろにあるゲームオブジェクトはオクルージョンカリングを有効にした場合も描画される必要があります。
その為、TransparentWallはOcculudeeのみにチェックを入れます。
オクルージョンカリングする部分をBakeする
個々のゲームオブジェクトの設定が終わったので、次はオクルージョンカリングをBakeします。
UnityのメニューからWindow→Occlusion Cullingを選択しオクルージョンカリングウインドウを表示します。
Bakeタブを選択し設定をします。
Smallest Occuluderはカリングする最小のオブジェクトのサイズを指定します。
画像では5となっているので例えばCubeを作成しScaleを全て1としていたらOcculuder Staticにチェックが入っていても他のゲームオブジェクトを遮蔽しないみたいです。
Smallest Holeはオブジェクト間の最小の隙間を指定します。
Backface Thresholdは目に見える裏面を積極的に省くかどうかの設定みたいです。
デフォルトでは100になっており、最小で5が指定出来ます。
5だと積極的に目に見える裏面を省いていくみたいです。精度の設定みたいなものでしょうか?
とりあえずSmallest Occuluderを1にして下の方にあるBakeボタンを押します。
↑のようにSceneタブでOcclusion CullingをEditモードにするとオクルージョンカリングされる空間がセルに分割されて表示されます。
オクルージョンカリングするエリアを手動で設定
さきほどOcclusion Cullingの設定をしてBakeボタンを押しましたが、オクルージョンカリングするエリアを設定していませんでした。
エリアを設定せずにBakeした場合はシーン全体にオクルージョンカリングが適用されるようです。
今度は手動でオクルージョンカリングのエリアを作成し設定もしてみましょう。
ヒエラルキー上で右クリック→Create Emptyをしてゲームオブジェクトを作成し、インスペクタのAdd Componentを押してRendering→Occlusion Areaを選択します。
Occlusion AreaのサイズやCenterを調整しカメラが移動するであろう地形をカバーするように設定します。
↑のようにエリアを設定しました。
空のオブジェクトにコンポーネントを追加するやり方以外にもヒエラルキー上にOcclusion Areaが存在しなければOcclution Cullingタブを選択し
ObjectタブのOcclusion Areasを選択しCreate NewのOcclusion Areaを押せばヒエラルキーにOcclusion Areaが作成されます。
エリアサイズの設定等は先ほどと同じです。
エリアを実行時にオープンしたりクローズしたり出来るOcclusion Portalというのもあります。
こちらはスクリプトからも操作出来るみたいですね。
オクルージョンカリングされるか確認する
オクルージョンカリングの設定とBakeが完了したのでカメラを移動してオクルージョンカリングされるかどうか試してみましょう。
↑のようにSceneタブに表示されているOcclusion CullingのウインドウでEditからVisualizeに変換します。
または、
Occlusion CullingタブのVisualizeタブを選択します。
これでSceneタブでカメラをオクルージョンカリングされるエリアで動かせば見えない部分を描画しないようになります。
カメラを動かして確認してみましょう(Unityの実行ボタンを押す必要はありません)。
カメラを壁の方向に動かしていくとフラスタムカリング効果で地面が描画されていない場所が増えていきます。
壁の前には透明な壁がありますがOcculuder Staticにチェックを入れていない為後ろの壁はずっと見える状態ですね。
また壁の後ろの地面は見えない領域の為に描画されないようになっています(オクルージョンカリング効果)。
カメラを壁の前に置いた状態でSceneタブに表示されているOcclusion Cullingのウインドウ内の設定のOcclusion Cullingのチェックを入れたり外したりすると
効果が単純に確認出来ます。
オクルージョンカリングの効果を数値で見てみる
オクルージョンカリングが効いているかどうかは視覚的に確認出来ましたが、実際に描画の処理負荷が軽減されているかどうかも数値で確認しておきましょう。
まずは違いがよく出るようにTerrainの幅を長くし、オクルージョンカリングした時に隠れる部分が大きくなるようにします。
↑のように壁の後ろに長くなるように設定しました。
次にグラフィックのクオリティ設定を上げます。
UnityメニューのEdit→Project Settings→Qualityを選択しQualityでFantasticを選択します(よくわからない方は変更しない方がいいかも)。
↑のようにFantasticを選択します(Defaultは変えてません)。
次にGameタブでStatsを押しパフォーマンスデータが見れるようにします。
↑のように表示されました。
これはオクルージョンカリングのBakeをする前のデータになります。
↑がオクルージョンカリング前の描画される部分です。
オクルージョンカリングの設定をしてBakeします。
↑がオクルージョンカリング後のデータです。
↑がオクルージョンカリングされて壁の後ろが描画されていない状態になります。
前後の比較が大変なので画像を並べて比較してみます。
↑がオクルージョンカリングの前後の結果の違いです。
赤い四角で囲まれた部分で効果が出ているのがわかります。
オクルージョンカリングを使ってみて
今回オクルージョンカリングを使って実験してみましたが、実験サンプルのゲームステージが実用的なものでないので効果のほどがあんまり実感出来ないかも(^_^;)
もう少し複雑な建物とかを設置して試してみたらよかったかもしれませんね。
今回の記事はUnityのマニュアルを参考にさせて頂きました。