Nanite が解決しなかった、唯一の重さ / overdraw
Nanite と
オーバードロー
Primer 06 で見たとおり、Nanite は三角形の数をほとんど気にしなくてよくする技術でした。ところが草木を敷き詰めると、三角形の数は同じなのに GPU が急に重くなります。犯人はオーバードロー。しかも Nanite は、シェーディングのオーバードローは消したのに、ラスタライズのオーバードローは消していません。この非対称性が、このページの主題です。
Overdraw
Software Raster
Masked Material
WPO
Foliage
まず用語だけ — 読む前の30秒
オーバードロー overdraw
1つのピクセルを何回処理したか。重なりが多いほど増える無駄。
カード card / billboard quad
葉のテクスチャを貼った四角い板。1枚2三角形。草木の基本部品。
マスクマテリアル masked
白黒画像で「この画素は捨てる」と決める方式。葉の形の抜きに使う。
ソフトラスタ software raster
Nanite が極小三角形を計算シェーダーで自前に塗る経路。書き込みは atomic。
WPO world position offset
シェーダーで頂点を動かす仕組み。草の揺れなど。Nanite では追加コスト。
HZB カリング hi-z culling
粗い深度画像で「完全に隠れた塊」を丸ごと捨てる高速化。
※ 各語の詳しい定義は、ページ末尾の用語集にもあります。
§1 — Two overdraws
オーバードローは2種類ある
「同じピクセルを何度も塗る」と一括りにされがちですが、GPU の中では別々の工程で別々に発生します。Nanite が消したのは片方だけ。ここを混同していると、可視化モードで赤を見つけても打ち手が決まりません。
Shading overdraw
シェーディングの重複
→ Nanite が解決済み
従来の描画では、あとで隠れてしまう面の色まで計算してしまうことがありました。Nanite は Visibility Buffer に「どの三角形が見えるか」だけを書き、最後に勝った画素だけを1回シェーディングします。何枚重なっていても、シェーディングは原則ピクセルあたり1回。
Raster overdraw
ラスタライズの重複
→ そのまま残っている
「どの三角形が勝つか」を決めるには、重なっている全部の三角形を触らないと結論が出ません。Nanite のソフトラスタは、覆った画素すべてに深度+ID の 64bit atomic max を発行します。10枚重なれば10回。草木で爆発するのはここです。
Nanite のラスタが1画素にしていること
for each covered pixel of the triangle:
z = interpolate depth
// masked なら ここで opacity mask を評価して discard 判定
packed = (z << 32) | triangleID
InterlockedMax(VisBuffer[pixel], packed) // 64bit atomic
この InterlockedMax が肝です。深度テストを atomic の「大きい方が勝つ」で代用しているため、ハードウェアの早期Z棄却で処理を飛ばすことができません。さらに同じ画素に多数のスレッドが殺到すると、メモリの競合で順番待ちが発生します。葉が10枚重なった画素は、10回の atomic 競合を起こします。
§2 — Foliage lab
葉を敷き詰めて、赤くしてみる
左が見た目、右がラスタのオーバードローを色で表したもの(青=1回、赤=8回以上)。UE の Nanite Overdraw 可視化と同じ読み方です。最後のトグルに注目してください ── 見た目はほとんど変わらないのに、赤が引いていきます。
ラスタ overdraw — atomic を叩いた回数
1回
8回以上
平均オーバードロー
最大オーバードロー
ラスタの atomic 総数
シェーディング回数
捨てられた画素の割合
充填率を下げても、ラスタの atomic 総数はびくとも動きません。透明にするのは「色を捨てる」話であって、四角い板を走査する手間はそのまま残るからです。一方トリムを入れると走査する形そのものが小さくなり、一気に落ちる。Nanite の草木対策がマテリアルではなくジオメトリ側にある理由が、この2つの数字の動き方の違いです。
§3 — Why Nanite specifically
なぜ Nanite だと特に痛いのか
重なりが重いのは Nanite に限りません。ただ Nanite の設計には、草木に対して不利に働く事情が4つあります。ここまで踏み込んでおくと、対策がなぜ効くのかを予測できるようになります。
§4 — Fixes
対策カタログ ── 効く順に
上から順に投資対効果が高いものです。クリックで手順と注意点が開きます。どれも「重なる面積を減らす」か「重なる領域を Nanite に触らせない」かのどちらかに分類できます。
§5 — In UE
見つけ方と、環境ごとの目安
推測せず、まず可視化。ビューポート左上の 表示モード → Nanite Visualization、またはコンソールから叩きます。
切り分けの手順
①
stat unit で GPU バウンドを確認(
Primer 08)。② GPU Visualizer で
Nanite のパスが太いかを見る。③ 太ければ Nanite Visualization の
Overdraw で赤い場所を探す。④ 赤いのが植生なら本ページの対策、そうでなければ半透明や重なる装飾を疑う(半透明は Nanite の外なので別問題)。⑤ 直したら
同じ視点で測り直す。この輪を回すのが基本です。