「なぜゲームは重くなるのか?」に迫る本連載。第2回目は、カメラに映らないオブジェクトを描画しない最適化手法「カリング」にフォーカスします!オブジェクトが描画される仕組みをもとに、カリングによって負荷が抑えられる仕組みや、2種類あるカリングの具体的な処理の方法を解説します。
TEXT / rita
EDIT / 神谷 優斗
目次
▼「なぜ最適化が必要なのか?」を説明する第1回はこちら
カリングの前に「描画処理の流れ」を理解する
カリングは、空間内に存在するすべてのオブジェクトを描画するのではなく、画面に映らないオブジェクトを描画対象から省くことで、無駄な描画処理をカットする仕組みです。
それでは、なぜカリングを行うと処理が軽くなるのでしょうか?それは、画面にオブジェクトを描画するための処理はいくつかの段階に分かれており、カリングによって一部の段階をスキップできるからです。
描画処理に必要なデータは3種類
カリングの仕組みを解説する前に、描画処理の流れについて簡単に説明します。1つのオブジェクトを画面に表示させるためには、以下のようなデータが必要です。
ポリゴンデータ(頂点・インデックスバッファ)
一般的な3DCGにおいて、オブジェクトの形は多角形の集まり「ポリゴン」で表現します。ポリゴンを構成するデータは、多角形を作る頂点ごとの位置情報などを含む「頂点バッファ」と、どの頂点同士が集まって多角形を作るかを決める「インデックスバッファ」で構成されます。
テクスチャ
テクスチャ(画像)はポリゴンの表面の色や柄を指定するほかに、様々な情報を付与するためにも利用されます。CGのために用意されるデータのうち、容量の大半を占めます。
シェーダ
ポリゴンデータやテクスチャを入力として、画面上にどのような色を出力するかを処理するための小さなプログラムです。頂点やピクセルそれぞれに対して、GPU上で並列実行されます。
描画処理はGPUが行うため、これらのデータは処理の前にGPUに転送されます。データの転送には時間がかかるため、ゲームのロード時に行います。
1つのオブジェクトが描画されるまでの流れ
送られたデータをもとに、GPUは描画処理を順番に実行します。
- 送られたデータを指定し、GPUに「このオブジェクトを描いてください」と指示を出す
- オブジェクトの位置や向き、カメラの状態に基づき、画面内のどの位置に描画されるのかを計算する
・ここでオブジェクトが画面内に入っていなければ、描画は無駄
- すでに描画されているオブジェクトとの前後関係を比較しつつ、画面内のどのピクセルに書きこむのかを計算する
・各ピクセルがすでに描画されている場合、描画したオブジェクトが自身より手前にあるのか、奥にあるのかをチェックし、上書きしてもよいかを判断する。この処理は「デプステスト」と呼ばれる
・ここで1ピクセルも書き込む場所がなければ、描画は無駄
- 書きこむことになったピクセルに色を付けていく
・ここでオブジェクトが画面内に入っていなければ、描画は無駄
・各ピクセルがすでに描画されている場合、描画したオブジェクトが自身より手前にあるのか、奥にあるのかをチェックし、上書きしてもよいかを判断する。この処理は「デプステスト」と呼ばれる
・ここで1ピクセルも書き込む場所がなければ、描画は無駄
実際にはより複雑な処理を行っていますが、大まかにはこのような流れで描画が行われます。描画結果はテクスチャとして出力され、まだ描画が済んでいない別のオブジェクトの描画に使われます。描画結果が、別のオブジェクトで上書きされることもあります。
このようにして、空間内のすべてのオブジェクトに対する描画処理が終わったら、最後に出力された描画結果が画面に表示されます。
ここで重要なのは、そもそも描画処理自体が無駄になってしまうケースが複数あるということです。各工程の処理はいずれも負荷が高く、無駄な実行は大きなタイムロスにつながります。その対策として行われるのが、処理が無駄になるかを判定し、無駄になるようであればそもそも描画しないようにする「カリング」です。
ここからは、工程「2」と「3」にそれぞれ関連している、2つのカリング手法について解説します。
画面に映らないときは描画しない「フラスタムカリング」
「オブジェクトの位置や向き、カメラの状態に基づき、画面内のどの位置に描画されるのかを計算する手順」において、描画する必要のないオブジェクトを弾くためのカリングは「フラスタムカリング」と呼ばれます。
ゲームの画面に映る領域は、カメラの位置と向きによって決まります。カメラが映す領域のことをフラスタム(視錐台)と呼びます。
画像の黄色い点線が視錐台にあたる。視錐台がそのまま視界となる(画像はアンリアルエンジン公式ドキュメントより引用)
フラスタム内に入っていないということは、画面外にあることと同じ意味になります。オブジェクトがフラスタムに含まれるかどうかを判定し、含まれないものを描画対象から外すカリング手法が「フラスタムカリング」です。
フラスタムに入っているかどうかは、当たり判定を用いて行います。キャラクターと地形の衝突判定や、攻撃の命中判定は厳密に行う一方で、フラスタムに含まれるかを判定する処理は簡単に済ませます。なぜなら、カリングで正確な判定処理を使ってしまうと、描画を省略することで減らせる時間よりも判定処理にかかる時間の方が大きくなってしまうためです。
フラスタムカリングで行われる判定処理
カリングには判定処理が低負荷であることが求められますが、低負荷は正確性とトレードオフの関係にあります。負荷が低く、描画対象の抜け漏れがない方法として、オブジェクトを包み込むシンプルな形状の領域「バウンディングボリューム」を当たり判定として用いる方法が使われます。
バウンディングボリュームとして最も単純なのは、オブジェクトの中心点とそこから最も遠い頂点までの距離を半径とする球(スフィア)です。フラスタムとの重なりは、互いの距離に基づくシンプルな計算で判定できます。
もう少し厳密な当たり判定として、頂点座標の最大値と最小値からなる直方体「バウンディングボックス」を使う場合もあります。球よりも計算量は増えますが、事前計算によって低い負荷で判定処理を行えます。
フラスタムカリングでは、バウンディングボリュームとフラスタムが重なっているかどうかをチェックする。黄色い線が球状のバウンディングボリューム、青い線がバウンディングボックスを示している(画像はアンリアルエンジン公式ドキュメントより引用)
ほかのオブジェクトに隠れる場合は描画しない「オクルージョンカリング」
「すでに描画されているオブジェクトとの前後関係を比較しつつ、画面内のどのピクセルに書きこむのかを計算する工程」で無駄になるオブジェクトを描画しないために行うカリングは「オクルージョンカリング」と呼ばれます。
オブジェクトがフラスタム内に含まれていたとしても、カメラと対象オブジェクトの間に別のオブジェクトがあった場合は隠れてしまいます。物陰に隠れているかどうかを判定して、完全に隠れているなら描画対象から外す仕組みがオクルージョンカリングです。
工程「3」で行うデプステストによって、手前にあるオブジェクトが奥にあるオブジェクトに上書きされない処理がピクセル単位で行われます。
オブジェクトの一部が隠れているだけならば、デプステストによって手前のオブジェクトが描かれている部分とそうでない部分でうまく描き分けられます。しかし、オクルージョンカリングによって完全に隠れていることがあらかじめわかっているのならば、わざわざデプステストを行わず、最初から描画自体をキャンセルできます。
オクルージョンカリングで行う遮蔽判定は、フラスタムカリングよりも処理負荷が高いため、フラスタム内の全オブジェクトに対して毎フレーム判定するのは困難です。そこで、ゲーム内で動いたり消えたりしないオブジェクト(静的なオブジェクト)に対してはゲームの実行中ではなく制作段階で事前に計算を行っておく(事前計算)などで負荷を軽減する工夫が必要となります。
静的な遮蔽を事前計算
静的なオブジェクトに対しては、遮蔽する側(オクルーダー)と遮蔽される側(オクルーディー)の位置関係が事前に計算可能です。事前計算ができていると、カメラの位置と向きを入力するだけで高速に遮蔽状態が判定できます。静的なオブジェクトのみをオクルージョンカリングの対象とする割り切りを行えば、オクルージョンカリングの負荷は大きく抑えられます。
静的な遮蔽の事前計算では、静的なオブジェクトを配置している空間内でカメラの位置と向きを変えながらレンダリングを行ってみて、どの状態から何が見えたのかをリスト化します。そして、カメラの位置と向きを入力すれば計算結果を取り出せるよう、データとして記録します。
ゲームエンジンによっては、この作業を「ベイク」と呼びます。オブジェクトの配置を変えたらベイクしなおす必要があるのは、オブジェクト同士の位置関係が変化し、遮蔽状態も変わるためです。
動的な遮蔽がある場合の対処法
動いたり、自由に出現したりする可能性のあるオブジェクト(動的なオブジェクト)もオクルージョンカリングの対象としたい場合、事前計算は使えません。
そこで、GPUに描画を指示する前に、デプステストとほぼ同じ遮蔽判定処理を行える機能「オクルージョンクエリ」を利用します。
オクルージョンクエリを使った遮蔽判定処理は、デプステストとほぼ同じです。しかし、描画処理を行う前にGPUに問い合わせ、描画処理を行う前段階のプログラムで描画を行うべきかどうかを判断できる点で異なります。
カリングが抱えるジレンマ
カリングに関する判定処理は、大雑把にしないと処理時間がかさんでしまう半面、あまりにも大雑把すぎるとカリングによって減らせる描画対象が少なくなってしまうジレンマを抱えています。
ゲーム開発現場において、判定で使用するバウンディングボリュームを調整できる環境では、実際にどのくらいの処理時間がかかっているのかを見ながらチューニングすることになります。
自身でゲーム用の3Dモデルを制作するうえで、カリングの効果を最大限発揮するためには、以下の2点を意識するとよいでしょう。
- あまりに巨大なオブジェクトを作らず、小さなまとまりに分割する
- 半透明のマテリアルを極力使わない
ここまで説明した通り、カリングの判定で肝となるのはオブジェクトを包むバウンディングボリュームです。オブジェクトが巨大だと、それに従いバウンディングボリュームも大きくなるため、カメラがどこを向いていてもフラスタムに重なってしまいます。
例えば、万里の長城のような形状をそのまま長く作って配置するのはNGです。適切なサイズに分割することで格段にカリングされやすくなるため、サイズを小さく保つことを心がけましょう。
また、ガラスのような半透明のマテリアルが多用されていると、オクルージョンカリングが有効に利用できなくなります。オクルージョンクエリを使うためには、不透明のオブジェクトをカメラに近い順に描画していくことが重要です。しかし、半透明のオブジェクトは、奥にあるオブジェクトを透過するため、2回分以上の完全な描画処理を行う必要があります。
1つのピクセルに対して何度も上書きする「オーバードロー」は、処理負荷の観点からできるだけ避けたいものです。半透明を乱用するとオーバードローが頻発するため、半透明をできるだけ減らして描画負荷を抑えましょう。
ゲームエンジンプログラマ。シリコンスタジオ、ゲームフリークを経て、現在はフリーランス的に活動中。低レイヤ・描画などのランタイムから、ツール・アセットパイプラインまで、ゲームに関する技術はなんでも守備範囲です。RPG・音ゲー・格ゲー・紳士ゲー・お馬さんなどなど幅広く嗜みます。新作を待ちわびているのは『世界樹の迷宮』『ブレイズアンドブレイド』『バーチャロン』など。
関連記事

注目記事ランキング
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
連載・特集ピックアップ
西川善司が語る“ゲームの仕組み”の記事をまとめました。
Blenderを初めて使う人に向けたチュートリアル記事。モデル制作からUE5へのインポートまで幅広く解説。
アークライトの野澤 邦仁(のざわ くにひと)氏が、ボードゲームの企画から制作・出展方法まで解説。
ゲーム制作の定番ツールやイベント情報をまとめました。
東京ゲームショウ2024で展示された作品のプレイレポートやインタビューをまとめました。
CEDEC2024で行われた講演レポートをまとめました。
BitSummitで展示された作品のプレイレポートをまとめました。
ゲームメーカーズ スクランブル2024で行われた講演のアーカイブ動画・スライドをまとめました。
CEDEC2023で行われた講演レポートをまとめました。
東京ゲームショウ2023で展示された作品のプレイレポートやインタビューをまとめました。
UNREAL FEST 2023で行われた講演レポートをまとめました。
BitSummitで展示された作品のプレイレポートをまとめました。
ゲームメーカーズ スクランブルで行われた講演のアーカイブ動画・スライドをまとめました。
UNREAL FEST 2022で行われた講演レポートやインタビューをまとめました。
CEDEC2022で行われた講演レポートをまとめました。



今日の用語
ロード(Load)
- コンピューターの補助記憶装置(HDDなど)に保存されたデータを読み込んで、主記憶装置(メインメモリ)上に展開すること。
- ゲームにおいて、セーブデータを読み込んで中断時の状況を再現すること。
Xで最新情報をチェック!

