こんにちは、みにくい社長です。
今回はゲーム開発の描画周りの最適化として重要なカリングについて解説します。
カリングの種類
まずカリングには3つのステップがあります。
視錘台カリング
オクルージョンカリング
バックフェースカリング
です。
まず視錘台カリングは、カメラの視錐台にオブジェクトが含まれているかどうかを判定する方法です。
こちらは一般的にCPUで判定を行うもので、簡単に実装出来て効果が高い為、使用されないケースは無いと思います。
次がオクルージョンカリングで、別のオブジェクト(オクルーダー)によって遮蔽されているオブジェクトをカリングします。
こちらは描画されるオブジェクトの配置によって、効果が高い場合もあれば、逆に無駄な負荷になってしまう場合があります。
そして実装方法も複数あって複雑な為、必ず実装されているとは限りません。
最後にバックフェースカリングですが、カメラから見て背面になっているポリゴンをカリングします。
こちらはGPU側で自動で行われる為、特別な事情が無い限りは使用されていると思います。
カリングの単位
オブジェクトをカリングする際には判定する形状が計算量に直結します。
オブジェクトのメッシュ>AABB>バウンディングスフィア
の順で計算量は軽くなりますが、AABBとスフィアは大差がないので精度を見て判断で良いと思います。
また、インスタンシングしている場合はインスタンスメッシュの単位でカリングを行わないと、オブジェクトの範囲が大きすぎて効果が得られないことがあります。
オクルージョンカリングの手法
オクルージョンカリングはオブジェクトの配置によって費用対効果が変化しやすい為、手法も複数考えられてきました。 CPUだけで完結する方法もあれば、CPUとGPUとハイブリッドのもの、GPUで完結するものもあります。
- Masked Software Occlusion Culling
この手法は階層的Zバッファを用いてCPUで完結する手法です。 計算量が解像度に依存するので負荷軽減で工夫は必要ですが、実装はシンプルになる為、効果がある場合は採用の価値ありです。
- OcclusionQuery
こちらはCPUとGPUのハイブリッドで実装します。GPUに対してクエリを発行し、プリZバッファで作成したZバッファに対してZテストに合格したオブジェクトのみを描画対象とします。クエリ発行時の描画呼び出し負荷と、カリング結果を適用するのが次フレームになるのが難点です。
- GPU駆動レンダリング
昨今のトレンドであるGPU駆動レンダリングのフロー内で可視性バッファを作成し、カリングを行います。そもそもGPU駆動レンダリング自体が大幅な高速化になっており、オブジェクト単位ではなくポリゴン単位でのカリングも可能になりますが、実装が複雑です。DirectX 12世代のメッシュシェーダーを使用することでより良い効果が得られますが、マルチプラットフォームで対応するにはもう少し待つ必要がありそうです。
今回は概要だけ触れましたが、次回は実装の詳細について解説したいと思います。
では、またねー。