ひとことで
同じ画素を、1 フレームの間に何度も塗り重ねることです。不透明な物体は、手前の物が奥の物を隠すので、深度テストで奥の画素の計算を省けますが、煙や炎のような半透明の板(ビルボード)は、重なった枚数だけ画素を塗り直す必要があります。GPU が 1 秒間に塗れる画素の数(フィルレート)には限りがあるので、爆発のエフェクトを画面いっぱいに重ねると、三角形が少なくても急に重くなります。
ゲームでの使いどころ
- エフェクトの最適化:煙・炎・爆発・魔法の粒子で、画面を覆う大きな板の数を抑える。
- UI:半透明のパネルやぼかしを重ねすぎない。
- 草や葉:アルファテストの板を大量に重ねた植生も、オーバードローが多い。
- 性能の調査:エンジンのオーバードロー表示(重なりのヒートマップ)で、重い場所を見つける。
しくみ
画素 1 つを塗る手間(フラグメントシェーダーの実行とブレンド)× 塗る回数が、画素の処理の総量です。画面全体の平均の重なりは、ざっくり
で見積もれます。板が大きいほど、数が多いほど、カメラに近いほど増えます。
透明な部分も塗っている:板のテクスチャが中央の丸い煙だけでも、GPU は板の四角形全体の画素についてシェーダーを実行し、透明な所もブレンドします。見た目に何も変わらない画素にも、手間がかかっています。
不透明な物体の場合:手前から奥へ描くと、深度テストで奥の画素を早く捨てられます(アーリー Z)。深度だけを先に描く「深度プリパス」も同じ目的の手法です。
実装のポイント
- 板の形を絞る:四角形の代わりに、テクスチャの不透明な部分をぴったり囲む多角形(6〜8 角形)を使うと、透明な部分を塗らずに済みます(Unreal の「Cutout」など)。
- 大きく少なく、小さく多く、を使い分ける:画面を覆う大きな板を数枚重ねるより、見た目に必要な分だけの小さな板にする方が軽いことが多いです。
- 近すぎる粒子を消す:カメラの目の前の粒子は画面いっぱいに広がるので、近づいたら薄くして消すか、描かないようにします。
- 低い解像度で描く:煙のようにぼんやりした物は、半分や 4 分の 1 の解像度のバッファに描いてから合成すると、塗る画素が 4〜16 分の 1 になります。
つまずきやすい点
- 三角形の数だけ見て安心する:粒子の三角形は少ないので、頂点の数では重さがわかりません。塗る画素の量で考えます。
- 高解像度の画面で急に重くなる:画素の処理は解像度に比例するので、4K や高 DPI の画面ではオーバードローの影響が何倍にもなります。
- アルファテストの草:不透明に見える草でも、アルファテスト(discard)を使うとアーリー Z が効きにくくなり、重なりが多いと重くなります。
デモで試すこと
- 「重なりの回数(ヒートマップ)」では、画素ごとに何枚の板が塗られたかが色で表示されます。青 → 黄 → 赤の順に多く、煙の中心では何十回も塗っています。
- 周りのぎざぎざは、板の四角形の角です。透明な部分も塗っていることがわかります。
- 「板の大きさ」や「板の数」を増やすと、塗る回数が急に増えます。左下と右下で、1 画素を塗る平均の回数(見積もり)を確かめてください。
- 「透明な縁を削った小さい板にする」を入れると、塗る回数が大きく減ります。「ふつうの見た目」に戻して、見た目があまり変わらないことを比べてください。