ポストプロセス・画面表現

画面空間アンビエントオクルージョン

SSAO / GTAO

隅や接触部分へ近似的な影を加える。

8 / 10

インタラクティブデモ

デモを準備しています…

画面空間アンビエントオクルージョン

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

ひとことで

物の隅、隙間、物が床に接する部分は、周囲からの光(環境光)が届きにくいので、ほんのり暗くなります。これをアンビエントオクルージョン(環境光の遮蔽)と呼びます。SSAO(Screen-Space Ambient Occlusion)は、描き終えた画面の深度と法線だけを使って、各画素の周りがどれだけ物に囲まれているかを近似し、この暗さを加える手法です。物の接地感と立体感が大きく増します。

ゲームでの使いどころ

  • 接地感:キャラクターや家具が床から浮いて見えるのを防ぐ。足元や物の下に柔らかい影ができる。
  • 細部の立体感:壁と床の隅、階段の段差、岩の割れ目、布のしわ。
  • 動的な物:事前に焼き込んだ AO(ライトマップ)が使えない、動く物や壊れる物にも AO を付けられる。

SSAO は Crytek の『Crysis』(2007 年)で初めて実用化され、その後、HBAO、GTAO(Ground Truth AO)などの改良版が広く使われています。

しくみ

各画素について:

  1. 深度から、その画素の 3D 位置 p\mathbf{p} を復元し、法線 n\mathbf{n} を読む。
  2. p\mathbf{p} の周りの、法線側の半球の中に標本点をばらまく(中心に近いほど多く)。
  3. 各標本点を画面に投影し、その位置の深度と比べる。標本点より手前に物があるなら、その点は物の中に埋まっている(遮られている)とみなす。
  4. 遮られた点の割合を「遮蔽の量」とし、環境光をその分だけ弱める。
AO=1−1N∑i=1N[ zscene(si) が si より手前 ]⋅rangeiAO = 1 - \frac{1}{N}\sum_{i=1}^{N} \big[\, z_{\text{scene}}(\mathbf{s}_i) \text{ が } \mathbf{s}_i \text{ より手前} \,\big] \cdot \text{range}_i

rangei\text{range}_i は、標本点とかけ離れた距離にある物(遠くの壁が手前に見えているだけ)を数えないための重みです。

ノイズとぼかし:標本点の数を少なくするため、画素ごとに標本の向きをランダムに回し、偏りを細かいノイズに変えます。最後に、ぼかして(または TAA で時間方向に平均して)ノイズを消します。

実装のポイント

  • 環境光だけに掛ける:本来、AO は環境光(IBL など)を弱めるもので、直接光(太陽)には掛けません。簡易的に画面全体へ掛けると、明るい場所まで不自然に暗くなります。
  • 低解像度で計算:画面の半分の解像度で計算し、深度を考慮したぼかし(バイラテラルフィルタ)で拡大します。
  • 半径の調整:半径が小さいと細かい隙間だけ、大きいと物の周りに広い暗がりができます。シーンの大きさに合わせます。

つまずきやすい点

  • 輪郭の暗いにじみ(ハロー):物の輪郭の外側の背景が、手前の物に遮られていると判定されて暗くなることがあります。範囲の重みで抑えます。
  • 画面外の物は見えない:画面の端や、手前の物に隠れた場所の遮蔽は正しく計算できません。カメラが動くと AO が変化して見えることがあります。
  • かけすぎ:強すぎる AO は、画面全体を汚れたように見せます。

デモで試すこと

  1. 「遮蔽の量だけ」にすると、球が床に接する部分、台座の根元、柱の足元が暗くなっているのが分かります。
  2. 「SSAO なし」と「SSAO あり」を切り替えると、物の接地感の違いがよく分かります。
  3. 「標本点の数」を減らし、「ざらつきをぼかす」をオフにすると、ノイズが目立ちます。
  4. 「調べる半径」を大きくすると、暗がりが物の周りに広く広がります。

参考資料

Unreal Engine Post Process Effects ↗

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