Primer 11 — Deep dive
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、またはコンソールから叩きます。

PC(デスクトップGPU)
ラスタの絶対性能に余裕があるので、平均 overdraw が 4〜6 程度でも成立します。ただしコストは「画素数 × 重なり回数」なので、1440p で軽かったシーンが 4K で急に苦しくなる。必ず出荷解像度で測ること。逆に言えば、内部解像度を落とせばラスタ負荷も比例して下がります。
コンソール(PS5 / XSX 相当)
内部解像度を落として TSR で戻す運用(Primer 10)が前提なので画素数自体は減りますが、GPU 予算そのものが薄い。平均 overdraw 3 を超えると植生だけで数ミリ秒を持っていかれます。トリムと WPO の距離カットは必須と考えたほうが安全です。
切り分けの手順
stat unit で GPU バウンドを確認(Primer 08)。② GPU Visualizer で Nanite のパスが太いかを見る。③ 太ければ Nanite Visualization の Overdraw で赤い場所を探す。④ 赤いのが植生なら本ページの対策、そうでなければ半透明や重なる装飾を疑う(半透明は Nanite の外なので別問題)。⑤ 直したら同じ視点で測り直す。この輪を回すのが基本です。

Glossary — 用語

よく出る言葉

前の深掘り
Primer 10 · TAA / TSR の副作用
次の深掘り
Primer 12 · Lumen の品質と速度