This explanation is currently available in Japanese.
ひとことで
画面に映らない物体を、描く前に対象から外す処理です。カメラの見える範囲(視錐台)の外にある物体を外すのが視錐台カリング、壁や建物の後ろに隠れて見えない物体を外すのが遮蔽(オクルージョン)カリングです。GPU に渡す物体が減れば、頂点の処理や描画命令の準備、影の描画まで、すべての手間が減ります。
ゲームでの使いどころ
- すべてのゲーム:視錐台カリングは、ほぼすべてのエンジンが自動で行っている。
- 屋内・都市:壁や建物で視界がさえぎられる場面では、遮蔽カリングの効果が大きい。部屋と出入口に分けるポータルカリングも使われる。
- 影:光源から見た視錐台で、影を落とす物体を選ぶ。
- 大量の物体:GPU でカリングして、インダイレクト描画で残りを描く。
しくみ
視錐台カリング:視錐台は、上下左右と手前・奥の 6 枚の平面で囲まれた形です。物体を包囲体(球や AABB)で近似し、各平面の外側に完全に出ているかを調べます。球(中心 、半径 )なら、平面の方程式 ( は内向き)に対して
となる平面が 1 枚でもあれば、見えません。物体が多い場合は、BVH などの木構造で、箱ごとまとめて外します。
遮蔽カリング:まず、大きな遮蔽物(壁や地形)だけを低い解像度で描き、画素ごとの一番手前の距離(深度バッファ)を作ります。次に、各物体の包囲体が画面上で占める範囲の深度を調べ、その範囲のどこを見ても物体の方が奥にあれば、隠れていると判断します。範囲を速く調べるために、深度バッファを縮小しながら「その範囲で一番奥の値」を持たせたピラミッド(Hi-Z)を使います。
実装のポイント
- 前のフレームの深度を使う:遮蔽物を先に描く代わりに、前のフレームの深度バッファを再利用する方法もあります。カメラが速く動くと、一瞬物体が欠けることがあるので、もう一度確かめる工夫をします(2 段階の遮蔽カリング)。
- 包囲体はゆるめで安全:包囲体が小さすぎると、見えている物体を消してしまいます。少し大きめの方が安全です。
- 遮蔽物は単純な形で:遮蔽の判定用には、見た目のメッシュではなく、内側に収まる単純な形(箱など)を使います。
- カリングの手間にも注意:小さな物体を 1 つずつ判定するより、まとめた単位で判定する方が速いことがあります。
つまずきやすい点
- 影が消える:画面の外にある物体でも、影は画面内に落ちることがあります。影を描くときは、光源から見た範囲でカリングします。
- 大きな物体の中心だけで判定:中心が画面外でも、端が画面に映っていることがあります。必ず大きさを含めて判定します。
- 遮蔽カリング自体が重い:遮蔽物が少ない開けた場所では、遮蔽カリングの手間の方が大きくなることがあります。場面に応じて使い分けます。
デモで試すこと
- 左の青いカメラから見える範囲(扇形)と、700 個の物体があります。「視錐台 + 遮蔽カリング」では、緑が描く物体、灰色が視錐台の外、紫が壁に隠れて外した物体です。
- 右下のグラフは、壁だけを描いて作った「方向ごとの一番手前の距離」(深度バッファ)です。壁のある方向では距離が短くなり、その奥の物体が外されます。
- 「視錐台カリング」だけにすると、壁の後ろの物体も描く対象に残ります。「なし」では 700 個全部を描きます。左下の数で比べてください。
- 「カメラを振る速さ」を変えると、見える範囲と隠れる物体が入れ替わっていく様子を見られます。