WonderflでReal Time? Ambient Occlusion


Real time ambient occlusion on FlashPlayer10 | Si+(wonderfl.net)
Real Time Ambient Occlusion といっても,最近流行ってるらしい Depth Buffer を利用した Ambient Occlusion じゃ無くて(ry.一応,平面上に薄ボケたドロップシャドウが出来たり,球同士が近づくと暗くなったりするので,ちゃんと計算は出来てるっぽいんだけど,Real Timeと称するには激重だし,計算量の割りに効果がすごく地味.でも臆することなく出せるのが Wonderfl Quarity (注;褒めてます).


計算方法はシンプルで,オブジェクトの全頂点に対して,法線方向に配置したヘミキューブ上に黒で全オブジェクトをレンダリングして得られた画像から開口率(Ambient Occlusion)を計算.Phong Shadingレンダリング時に,各頂点のAmbient/Diffusion値に先ほど計算した開口率を加算する.以上.
単純に高速化を考えるなら Screen Space Ambient Occulusion,高精度化なら Texture上に Ambient Occlusion 値の分布を焼き付ける方法のほうが良いと思うんだけど,キューブマップを使った計算に慣れておくと,後々 Global Illumination やる時に何かと役立つかなって事でこの方法にした.


ただ,この方法の実直な実装によるリアルタイム大域照明は,少なくともFlash10上では無理.
そもそも,ヘミキューブ法は前回のモンテカルロ法によるAmbient Occlusion計算よりは早いものの,レンダリング回数が爆増するため,GPUが使えない現Flash10で高速計算は期待できない.Wonderflで上げたシーンの場合,頂点数1015(球;242×3+平面;289)なので,単純計算で 1 フレームに 5075+1 回レンダリングすることになる.ヘミキューブ上では z-sort や シェーディングを気にする必要は無いものの,まじめに描画していたらリアルタイムには程遠い.このデモでは,ActionScript描画関数中最速のFillRectで,遠方で球とほぼ同面積となる正方形をヘミキューブ上に描画して近似している.また,ヘミキューブの大きさ自体も正面8x8/側面8x4と極小にして処理時間を稼いでいる.あと,Ambient Occlusion は無限平面がある場合,接地していないと不自然に陰が濃くなるので,Ambient Occlusion 計算専用の平面を球の真下に配置してヘミキューブ上に描画している.


今回の方法は,グローシェーディングを使って陰影を表現する点ではラジオシティ法と同じなので,パッチの細かさがダイレクトに精度に効いてくる.平面を16x16に分割してるけど,陰の濃淡で分割した頂点が見えているのが分かる.32x32位まで細かくすると静止画なら誤魔化せるものの,球が動いているとやはり頂点が見えてきてしまう.ラジオシティ法みたいに,陰の濃い場所を動的に分割していくのが現実解かも知れないけど,どんどんリアルタイムから遠ざかってくな.


【追記】
Ambient Occlsion オン/オフ を付けた.あと,オブジェクトの動きを止めたら Ambient Occlsion の再計算を行わないようにした.オブジェクト位置が変わんなければ,再計算の必要が無いのは,この方法の利点ではある.