アンビエントオクルージョンちゃん

コンピュータグラフィックスについて書きますっ

アンビエントオクルージョン・はじめの一歩

はじめに

こんにちは!アンビエントオクルージョンちゃんです。

アンビエントオクルージョンを実現する技法は数多くあれど、そもそもアンビエントオクルージョンが一体何を意味するのか、という点については意外と見過ごされているような気がします。そこで、アンビエントオクルージョンについて基礎、原理から解説してみたいと思います。

元々、アドホックで場当たり的な要素の強いアンビエントオクルージョンですが、今回はあくまで物理ベースな大域照明技術の一つとして解釈・説明していきたいと思います。

 

 

基礎知識

アンビエントオクルージョン(Ambient occlusion)は日本語で言うと「環境遮蔽」となります。比較的低負荷ながらも大域照明が考慮された高品質な結果を得ることが出来るため、オフラインレンダリング・リアルタイムレンダリング問わず、CG業界では非常に幅広く使われている技術です。

2010年にはHayden Landis、Ken McGaugh、 Hilmar Kochらにアンビエントオクルージョンに関する業績についてアカデミー科学技術賞が与えられました。

典型的な、アンビエントオクルージョンのみ計算した結果は以下のようになります。物体の陰影が綺麗に表現されているのが分かると思います。このような表現はレンダリングしたい対象の点のみ考慮した局所照明モデルでは実現できず、シーン全体を考慮した大域照明モデルによって実現できます。アンビエントオクルージョンはそのような大域照明モデルを実現する一手法ということになります。

同じ床でも、場所によってはドラゴンの足によって隠されているため暗くなっており、場所によっては回りに何も無いため白く明るくなっているのは、シーン全体を考慮しているが故、というわけです。

 

f:id:Ambient-Occlusion:20131015195429p:plain

 

動機

最初に、アンビエントオクルージョンを導入する動機について説明します。

まず、注目点がどのように周囲の光の影響を受けるかのモデルを考えます。(注目点は例えばレンダリングしたいピクセルと対応するシーン中の点などです)

f:id:Ambient-Occlusion:20131015202440p:plain

一般的な状況において、注目点は二種類の光の影響を受けると考えることができます。光源から直接注目点まで届く直接光の影響と、直接光が周囲の物体によって反射を繰り返してから注目点に到達する間接光の二種類です。今回は特に、アンビエントオクルージョンについて考えているため間接光を周囲の環境からの光、環境光(Ambient light)と呼ぶことにします。

さて、この周囲からの光の影響を正確に考慮すると非常に現実感のあるCGを得ることができることが知られています。しかし、物体間の光の相互反射を全てシミュレーションする必要があるため、非常に計算コストが大きいという事実もあります。

オフラインレンダリング・リアルタイムレンダリング両方で、この間接光・環境光の影響を高速に精度よく計算しようという試みは何十年もの間行われてきました。そして、かなり良い結果も得られています。それでもやはり環境光を丸ごと計算するのは大変なので、ある程度シーン全体を考慮しつつ(大域照明を考慮しつつ)、計算速度もそれなりなモデルを使うことで速度と計算コストのバランスをとろう、という発想がアンビエントオクルージョンを使う動機になります。

環境光の影響の近似

まず、コストの大きい環境光の影響の計算を何らかの方法で近似することを考えます。この部分は本質的にはアンビエントオクルージョンとは関係ありません。例えば、リアルタイムレンダリングにおいてはアンビエント光と呼ばれる定数値を使って計算を近似したりします。また、Image Based Lightingによる結果を使うこともあります。(IBLによるライティングはまさに環境光の分布を画像として入力し、その影響を計算するものでした)

以下の例では入力の環境光成分は定数とします。

環境遮蔽項の計算

さて、環境光成分が定まったとします。しかしこのままでは注目点以外の、周囲の点を考慮していません。考慮しないまま最終的な結果をレンダリングすれば、局所照明モデルでレンダリングした、ということになります。前述したとおり、これではあまり綺麗な絵にはなりません。そこで、周囲のシーンを考慮するわけですが、アンビエントオクルージョンによるレンダリングは、周囲のシーンによって注目点がどれくらい遮蔽されるかのみを考慮します。この近似によって、物体間の光の相互反射を考慮した場合よりも低コストで大域照明が考慮された高品質な結果を得ることが出来るわけです。

f:id:Ambient-Occlusion:20131015205313p:plain

例えば、上のようなシーンでは、注目点は八方向のうち二方向から来る光がブロックされています。このブロックのされ具合=遮蔽度を環境遮蔽項、すなわちアンビエントオクルージョン項と呼びます。

f:id:Ambient-Occlusion:20131015205646p:plain

 

また、上のようなシーンにおける遮蔽度は先ほどのシーンより大きい、ということになり、注目点における環境光の影響はより小さくなるということがわかります。

では、この環境遮蔽項をどのように計算するか、ですが、これはオフラインレンダリングとリアルタイムレンダリングではずいぶん違うようです。

オフラインレンダリングにおいては、ある程度時間をかけて計算することが可能なため、注目点をから全方向に向かってレイトレーシングを実行、周囲の物体と何本ヒットしたかを計算することで環境遮蔽を計算することが多いようです。

一方、リアルタイムレンダリングにおいてはレイトレーシングは時間がかかりすぎます。そこで、Depth mapなどと使って注目点周囲のジオメトリを復元し、Screen Spaceで遮蔽度を大雑把に近似する、といった手法が主流のようです。(いわゆるScreen Space Ambient Occlusion)

詳しい計算式については後述します。

環境遮蔽項と環境光の関係

今回、環境光は局所照明モデルによって周囲の物体の影響を考えないで計算したと仮定しました。一方環境遮蔽項は周囲の物体からの遮蔽度で、これは基本的に0(完全に遮蔽)から1(全く遮蔽されていない)の値になります。

そこで、レンダリングを行う際には、環境光の影響と環境遮蔽項の値を乗算し、これに直接光による影響を加算します。

このとき、良くある(?)間違いとして、(直接光の影響+環境光の影響)×環境遮蔽項としてしまうことです。環境遮蔽項はあくまで環境光、すなわち間接光についての項なので直接光とは関係がありません。正しくは直接光の影響+(環境光の影響×環境遮蔽項)です。

(まああくまで厳密に物理に基づいた場合なので、最終的な見た目如何、という側面もあります)

実際の処理の例

それでは実際、各成分がどのように計算され、どのような見た目なのかを具体例を挙げて解説します。

まず、直接光の影響のみ計算したレンダリング結果は以下のようになります。

f:id:Ambient-Occlusion:20131015210048p:plain

 

一方、環境光の影響のみ計算したレンダリング結果は以下のようになります。今回は環境光を定数で近似したため、一色で塗りつぶされています。

f:id:Ambient-Occlusion:20131015215233p:plain

 

各点において、周囲の物体からの遮蔽度を計算したレンダリング結果はいかのようになります。すなわち環境遮蔽項・アンビエントオクルージョン項です。

f:id:Ambient-Occlusion:20131015210308p:plain

以上を全て統合すると以下のような結果になります。

f:id:Ambient-Occlusion:20131015215302p:plain

 

 さて、アンビエントオクルージョンを考慮しない場合(局所照明モデルのみ)と考慮した場合の比較が以下です。

f:id:Ambient-Occlusion:20131015215343p:plain

 

 

 アンビエントオクルージョンの考慮によって品質が向上していることが分かります。まとめると以下のようになります。繰り返しになりますが、まず環境光の影響と環境遮蔽項(アンビエントオクルージョン項)の乗算を計算して、それに直接光の影響を加算していることに注意してください。

f:id:Ambient-Occlusion:20131015215352p:plain

 

 数式でみる環境遮蔽項

環境遮蔽項を計算するための数式について説明します。

f:id:Ambient-Occlusion:20131015221933p:plain

図のような状況において、位置xに存在する点pにおける環境遮蔽項は以下のようにして計算できます。

f:id:Ambient-Occlusion:20131015222009p:plain

このとき、関数Vは、位置xにおいて点pがω方向から遮蔽されるかどうかを表す二値関数です(0なら遮蔽されており、1なら遮蔽されていない)。V = 1とすれば全く遮蔽されていないことになり、上の積分の結果はA = 1となります。また、V = 0とすれば完全に遮蔽されているのでA = 0となります。

これは、関数Vを法線nの方向の半球上で積分している、ということになり、この結果はそのまま遮蔽度になるわけです。cosθは、いわゆるコサイン項です。基本的に、同じ強さの光でも法線に近い方向(θが0°に近い方向)から来る光のほうが点pに対する影響は大きいという法則があります。(極端な話、θ=90°から来る光は真横から来る光となり、このような光は点pに対する影響はありません)これを環境遮蔽項は最終的に環境光の影響の度合い使われるため、周囲の光の影響についてコサイン項を考慮する必要があります。また、V=1として半球上に積分すると、結果はπとなるので、正規化するためにπで割る必要があるため、1/πの項があります。

実装例

アンビエントオクルージョンを計算するためのプログラムの例としてAOBenchというものがあります。

http://code.google.com/p/aobench/

まとめ

アンビエントオクルージョンは環境遮蔽のことで、簡易的な大域照明モデルです。レンダリング対象の点が周囲の物体によってどの程度遮蔽されるのかを計算、その結果を環境光に作用させることで高品質なレンダリングを実現します。