アンビエントオクルージョン

Ambient Occlusion別名:AO、環境光の遮蔽

概要

部屋の隅、物のすき間、物体の接地面のように、周りの物に囲まれて環境光が届きにくい場所を暗くする処理。物体が床に置かれている感じや、形のくぼみがはっきりする。

デモ

デモを読み込んでいます
白い線をドラッグすると、AO なしとありを見比べられます。部屋の隅、箱の接地面、台の下、柱と壁のすき間に注目してください。「調べる距離」を広げると、暗くなる範囲が広がります。

使われる場面

  • 3D のリアルタイム描画

    画面に描いた深度から、ピクセルごとに周りの遮られ具合を見積もる方法(画面空間の AO)が広く使われる。後処理として追加でき、場面の奥行き感を手軽に増やせる。

  • 事前計算(ベイク)

    動かない背景や小物では、遮られ具合を前もって計算し、テクスチャや頂点の色に焼き込んでおく。実行時の負荷がほとんどなく、品質も高い。

  • テクスチャ制作

    モデルのくぼみを暗くした AO マップを作り、マテリアルに組み込む。汚れやほこりのたまり方を描くときの下地にも使う。

  • 静止画やイラストの仕上げ

    光の計算を省いた絵や、アニメ調の陰影に重ね、接地感や立体感を足す。

判断基準

こういうときこうする
物体が床から浮いて見える、場面がのっぺりしているAO を足す。接地面と隅に暗がりができ、置かれている感じが出る。
隅や物体のまわりが、黒く汚れたように見える強さを下げるか、調べる距離を短くする。AO は環境光だけに掛けるもので、日なたまで暗くなっているなら掛けすぎである。
動く物体の縁に、暗い輪郭や残像のような影が出る画面空間の AO の弱点で、画面に映っていない物による遮りを扱えない。強さを下げるか、動かない物は焼き込みに切り替える。
直接光の影がすでにはっきり出ている効果は控えめでよい。AO は直接光の影の代わりではなく、影の中や日陰の明暗を補うものである。
屋外の広い場面や、大きな地形調べる距離を場面の大きさに合わせて広げる。距離が短すぎると、大きなくぼみに暗がりが付かない。

こう見えたら

  • 物体が床から浮いて見える光と影
  • 隅やすき間まで明るく、場面がのっぺりしている光と影
  • 物のまわりが黒く汚れたように見える光と影

指示の例

  • 物体が床から浮いて見える。アンビエントオクルージョンを有効にして、接地面と部屋の隅に柔らかい暗がりを付けて

  • AO が強すぎて、物のまわりが黒く汚れたように見える。強さを半分くらいにして、調べる距離も短くして

  • 大きな岩のくぼみには暗がりが付かず、小さなすき間にだけ付いている。AO の調べる距離を場面の大きさに合わせて広げて

  • カメラを動かすと AO の暗がりがちらつく。動かない背景は、画面空間の AO ではなく、ベイクした AO に切り替えて

詳細

環境光は四方から届く

空や周りの壁から届く光(環境光)は、一方向からではなく、面の上に広がる半球のあらゆる方向から届く。開けた場所では半球全体から光が届くが、部屋の隅や物のすき間では、半球の一部が周りの物にふさがれている。ふさがれた方向からは光が届かないので、その分だけ暗くなる。直接光の影のように形のはっきりした影ではなく、囲まれた場所ほどじわりと暗くなる、柔らかい明暗である。アンビエントオクルージョン(AO)は、この「環境光がどれだけさえぎられるか」を求めて、環境光の明るさに掛ける。

式

点 p\mathbf{p} での AO は、法線 n\mathbf{n} 側の半球 Ω\Omega について、さえぎられない方向を余弦で重み付けして平均したものである。

A(p)=1π∫ΩV(p,ω) (n⋅ω) dωA(\mathbf{p}) = \frac{1}{\pi} \int_{\Omega} V(\mathbf{p}, \boldsymbol{\omega})\, (\mathbf{n} \cdot \boldsymbol{\omega})\, d\boldsymbol{\omega}

VV は、方向 ω\boldsymbol{\omega} に距離 rr 以内で何かに当たれば 0、当たらなければ 1 になる関数である。AA は、何にもさえぎられなければ 1 で、囲まれているほど 0 に近づく。調べる距離 rr で区切るのは、遠くの壁まで数えると、部屋の中のすべての点が暗くなってしまうためである。

デモは、読み込み時に各頂点から 64 方向へ光線を飛ばしてこの値を求め、頂点に焼き込んでいる。当たった距離が近いほど強くさえぎったとみなし、rr に近い当たりは弱めて数えている。

// AO は環境光(間接光)にだけ掛ける。直接光には、影(シャドウマップ)が別に掛かる
vec3 ambient = albedo * irradiance * ao;
vec3 direct  = albedo * lightColor * max(dot(n, l), 0.0) * shadow;
vec3 color = ambient + direct;

見分け方と落とし穴

AO のかかった絵では、床と物体の接地面、壁と壁の角、物と物のすき間が暗くなる。直接光の影は光の向きで形が決まるが、AO の暗がりは形だけで決まるので、光源を動かしても変わらない。

AO は、物理的に正確な環境光の計算(グローバルイルミネーション)の一部だけを取り出した近似である。さえぎった物からの照り返しは扱わないので、明るい色の壁ぎわでも一律に暗くなる。強さを上げすぎると、接地面のまわりが黒い縁取りのようになり、汚れに見える。デモの「AO の値だけを表示」にすると、どこがどれだけ暗くされているかを確かめられる。

リアルタイム描画でよく使われる画面空間の AO は、画面に映っている物だけを使って遮られ具合を見積もる。画面の外や物の裏側にある物は数えられないので、画面の端で暗がりが消えたり、カメラの動きで暗がりの形が変わったりする。

関連