Post processing

Depth / Normal Edge Detection

深度・法線アウトライン

隣接画素の深度や向きの差から輪郭を描く。

7 / 10

Interactive demo

Preparing the demo…

Depth / Normal Edge Detection

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

描き終えた画面の深度(カメラからの距離)と法線(面の向き)を隣の画素と比べ、差が大きい場所に線を引くポストプロセスです。深度の差からは物の外形(手前の物と奥の物の境目)が、法線の差からは同じ物の中の角や折れ目が見つかります。モデルを 1 つずつ加工しなくても、画面全体に一度に輪郭線を引けます。

ゲームでの使いどころ

  • アニメ・漫画調の表現:トゥーンシェーディングと組み合わせた輪郭線(『ボーダーランズ』シリーズなど)。
  • スタイライズした画面:線画、設計図、スケッチ風の表現。
  • 強調表示:選択した物、拾えるアイテム、壁の向こうの敵に輪郭を付ける(特定の物だけを別のバッファに描いて検出する)。
  • 可読性の向上:似た色の物が重なる場面で、形を分かりやすくする。

しくみ

深度の差:隣り合う画素の深度が急に変わる場所は、手前の物と奥の物の境目です。ただし、床を斜めに見ると、隣の画素との深度の差は平面上でも大きくなります。そこで、平面では 1/深度1/\text{深度} が画面上で直線的に変わることを利用し、2 階差分(両隣の平均との差)を見ると、平面を誤検出せずに段差だけを見つけられます。

ed=∣ w++w−−2w0 ∣w0,w=1深度e_d = \frac{\left|\,w_{+} + w_{-} - 2w_0\,\right|}{w_0},\qquad w = \frac{1}{\text{深度}}

法線の差:隣り合う画素の法線の向きが大きく違う場所は、箱の角や壁と床のつなぎ目です。深度は連続していても、法線は急に変わります。

en=∥n+−n−∥e_n = \lVert \mathbf{n}_{+} - \mathbf{n}_{-} \rVert

2 つを組み合わせると、外形と折れ目の両方を線にできます。しきい値を超えた場所を線とします。

モデルに線を付ける方法との違い:トゥーンで紹介した背面法(モデルを膨らませて裏面を描く)は、モデルごとに線の太さや色を細かく調整できますが、角の折れ目は描けません。画面空間の方法は、画面全体に一様な太さの線を一度に描け、折れ目も描けます。

実装のポイント

  • 法線バッファ:法線は、SSAO や SSR と共有できるので、遅延レンダリングのゲームでは追加のコストがほとんどかかりません。
  • 線の太さ:比べる画素の距離を広げると線が太くなります。距離によって線の太さを変える(遠くは細く)と奥行きが出ます。
  • 物体 ID:物体ごとに番号を書いたバッファの差も使うと、同じ深度・同じ向きで重なる別の物の境目も取れます。

つまずきやすい点

  • しきい値の調整:低すぎると、細かい凹凸や床の模様まで線になってノイズっぽくなり、高すぎると必要な線が切れます。
  • 遠景のちらつき:遠くの細かい形は、画素単位の差で線が出たり消えたりしてちらつきます。遠くほど線を薄くします。
  • 半透明物:深度を書き込まない半透明物には線が出ません。

デモで試すこと

  1. 「インクの線画」では、夜の広場が紙の上の線画になります。「画面に重ねる」では通常の画面に輪郭線が加わります。
  2. 「深度のみ」にすると、物の外形は取れますが、柱の角や台座の折れ目の線が消えます。
  3. 「法線のみ」にすると、角の線は出ますが、同じ向きの面が前後に重なる境目(球と奥の柱など)の線が弱くなります。
  4. 「検出結果のみ」で、深度の差(赤)と法線の差(青緑)がそれぞれどこで検出されているか確認できます。

References

Unreal Engine Post Process Effects ↗

A general reference for this subcategory.