アンビエントオクルージョン
Ambient Occlusion別名:AO、環境光の遮蔽
概要
部屋の隅、物のすき間、物体の接地面のように、周りの物に囲まれて環境光が届きにくい場所を暗くする処理。物体が床に置かれている感じや、形のくぼみがはっきりする。
デモ
使われる場面
3D のリアルタイム描画
画面に描いた深度から、ピクセルごとに周りの遮られ具合を見積もる方法(画面空間の AO)が広く使われる。後処理として追加でき、場面の奥行き感を手軽に増やせる。
事前計算(ベイク)
動かない背景や小物では、遮られ具合を前もって計算し、テクスチャや頂点の色に焼き込んでおく。実行時の負荷がほとんどなく、品質も高い。
テクスチャ制作
モデルのくぼみを暗くした AO マップを作り、マテリアルに組み込む。汚れやほこりのたまり方を描くときの下地にも使う。
静止画やイラストの仕上げ
光の計算を省いた絵や、アニメ調の陰影に重ね、接地感や立体感を足す。
判断基準
| こういうとき | こうする |
|---|---|
| 物体が床から浮いて見える、場面がのっぺりしている | AO を足す。接地面と隅に暗がりができ、置かれている感じが出る。 |
| 隅や物体のまわりが、黒く汚れたように見える | 強さを下げるか、調べる距離を短くする。AO は環境光だけに掛けるもので、日なたまで暗くなっているなら掛けすぎである。 |
| 動く物体の縁に、暗い輪郭や残像のような影が出る | 画面空間の AO の弱点で、画面に映っていない物による遮りを扱えない。強さを下げるか、動かない物は焼き込みに切り替える。 |
| 直接光の影がすでにはっきり出ている | 効果は控えめでよい。AO は直接光の影の代わりではなく、影の中や日陰の明暗を補うものである。 |
| 屋外の広い場面や、大きな地形 | 調べる距離を場面の大きさに合わせて広げる。距離が短すぎると、大きなくぼみに暗がりが付かない。 |
こう見えたら
指示の例
物体が床から浮いて見える。アンビエントオクルージョンを有効にして、接地面と部屋の隅に柔らかい暗がりを付けて
AO が強すぎて、物のまわりが黒く汚れたように見える。強さを半分くらいにして、調べる距離も短くして
大きな岩のくぼみには暗がりが付かず、小さなすき間にだけ付いている。AO の調べる距離を場面の大きさに合わせて広げて
カメラを動かすと AO の暗がりがちらつく。動かない背景は、画面空間の AO ではなく、ベイクした AO に切り替えて
詳細
環境光は四方から届く
空や周りの壁から届く光(環境光)は、一方向からではなく、面の上に広がる半球のあらゆる方向から届く。開けた場所では半球全体から光が届くが、部屋の隅や物のすき間では、半球の一部が周りの物にふさがれている。ふさがれた方向からは光が届かないので、その分だけ暗くなる。直接光の影のように形のはっきりした影ではなく、囲まれた場所ほどじわりと暗くなる、柔らかい明暗である。アンビエントオクルージョン(AO)は、この「環境光がどれだけさえぎられるか」を求めて、環境光の明るさに掛ける。
式
点 での AO は、法線 側の半球 について、さえぎられない方向を余弦で重み付けして平均したものである。
は、方向 に距離 以内で何かに当たれば 0、当たらなければ 1 になる関数である。 は、何にもさえぎられなければ 1 で、囲まれているほど 0 に近づく。調べる距離 で区切るのは、遠くの壁まで数えると、部屋の中のすべての点が暗くなってしまうためである。
デモは、読み込み時に各頂点から 64 方向へ光線を飛ばしてこの値を求め、頂点に焼き込んでいる。当たった距離が近いほど強くさえぎったとみなし、 に近い当たりは弱めて数えている。
// 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 は、画面に映っている物だけを使って遮られ具合を見積もる。画面の外や物の裏側にある物は数えられないので、画面の端で暗がりが消えたり、カメラの動きで暗がりの形が変わったりする。