大量描画・実装基盤

オーバードロー

Overdraw / Fill Rate

同じ画素への重ね描きを把握して負荷を抑える。

6 / 10

インタラクティブデモ

デモを準備しています…

オーバードロー

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

同じ画素を、1 フレームの間に何度も塗り重ねることです。不透明な物体は、手前の物が奥の物を隠すので、深度テストで奥の画素の計算を省けますが、煙や炎のような半透明の板(ビルボード)は、重なった枚数だけ画素を塗り直す必要があります。GPU が 1 秒間に塗れる画素の数(フィルレート)には限りがあるので、爆発のエフェクトを画面いっぱいに重ねると、三角形が少なくても急に重くなります。

ゲームでの使いどころ

  • エフェクトの最適化:煙・炎・爆発・魔法の粒子で、画面を覆う大きな板の数を抑える。
  • UI:半透明のパネルやぼかしを重ねすぎない。
  • 草や葉:アルファテストの板を大量に重ねた植生も、オーバードローが多い。
  • 性能の調査:エンジンのオーバードロー表示(重なりのヒートマップ)で、重い場所を見つける。

しくみ

画素 1 つを塗る手間(フラグメントシェーダーの実行とブレンド)× 塗る回数が、画素の処理の総量です。画面全体の平均の重なりは、ざっくり

平均の重なり≈∑i(板 i の画面上の面積)画面の面積\text{平均の重なり} \approx \frac{\sum_i (\text{板 } i \text{ の画面上の面積})}{\text{画面の面積}}

で見積もれます。板が大きいほど、数が多いほど、カメラに近いほど増えます。

透明な部分も塗っている:板のテクスチャが中央の丸い煙だけでも、GPU は板の四角形全体の画素についてシェーダーを実行し、透明な所もブレンドします。見た目に何も変わらない画素にも、手間がかかっています。

不透明な物体の場合:手前から奥へ描くと、深度テストで奥の画素を早く捨てられます(アーリー Z)。深度だけを先に描く「深度プリパス」も同じ目的の手法です。

実装のポイント

  • 板の形を絞る:四角形の代わりに、テクスチャの不透明な部分をぴったり囲む多角形(6〜8 角形)を使うと、透明な部分を塗らずに済みます(Unreal の「Cutout」など)。
  • 大きく少なく、小さく多く、を使い分ける:画面を覆う大きな板を数枚重ねるより、見た目に必要な分だけの小さな板にする方が軽いことが多いです。
  • 近すぎる粒子を消す:カメラの目の前の粒子は画面いっぱいに広がるので、近づいたら薄くして消すか、描かないようにします。
  • 低い解像度で描く:煙のようにぼんやりした物は、半分や 4 分の 1 の解像度のバッファに描いてから合成すると、塗る画素が 4〜16 分の 1 になります。

つまずきやすい点

  • 三角形の数だけ見て安心する:粒子の三角形は少ないので、頂点の数では重さがわかりません。塗る画素の量で考えます。
  • 高解像度の画面で急に重くなる:画素の処理は解像度に比例するので、4K や高 DPI の画面ではオーバードローの影響が何倍にもなります。
  • アルファテストの草:不透明に見える草でも、アルファテスト(discard)を使うとアーリー Z が効きにくくなり、重なりが多いと重くなります。

デモで試すこと

  1. 「重なりの回数(ヒートマップ)」では、画素ごとに何枚の板が塗られたかが色で表示されます。青 → 黄 → 赤の順に多く、煙の中心では何十回も塗っています。
  2. 周りのぎざぎざは、板の四角形の角です。透明な部分も塗っていることがわかります。
  3. 「板の大きさ」や「板の数」を増やすと、塗る回数が急に増えます。左下と右下で、1 画素を塗る平均の回数(見積もり)を確かめてください。
  4. 「透明な縁を削った小さい板にする」を入れると、塗る回数が大きく減ります。「ふつうの見た目」に戻して、見た目があまり変わらないことを比べてください。

参考資料

Unity ComputeShader ↗

分野全体の資料で、この項目を直接扱っているとは限りません。