自己遮蔽項付きリアルタイム大域照明


~ Real-Time Global Illumination with self shadows ~






■はじめに

前回、リアルタイム大域照明を取り扱いました。
これは、入射光を環境マップとして取り込んで、それらを球面調和関数展開することによって、拡散光をより正確に表現する手法です。
今回は、さらにPRTを併用して、自己遮蔽つきのリアルタイム大域照明を実装してみました。

で、いつものようにプログラムです。

GeForce FX では、PRTテクスチャを作成する工程で浮動小数点バッファを使うためにHALで動かないのですが、あらかじめテクスチャを用意しておけば高速に動作するので、私が作成したPRTテクスチャを読み込んで実行するGeForce FX 用のプログラムも用意しておきました。

カーソルキーで、カメラが回って、zやxでズームが変えられます。
また、aキーで「全照明効果」、「環境マップなし」、「環境マップのみ」の切り替えができます。
pキーでティーポットの動きを止めることができます。

上の画像は、下のように拡散光と環境マップが合成されて最終的な出力になっています。

+ =

ソースには、いつものように適当にファイルが入っています。 大事なファイルは次のものです。

main.hアプリケーションのヘッダ
main.cppアプリケーションのソース
hlsl.fxシェーダプログラム
paraboloid.fxDual paraboloid マップのためのシェーダ

■何をやっているの

前回は、オブジェクトに入射する光のレンダリング方程式

の入射光Liに関して、SH展開をしました。
今回は、このレンダリング方程式を2つの項に分解します。

このV(x,ωi)は遮蔽項と呼ばれる項で、外部から入射した光が自分のほかの部分にさえぎられて届かなかったら0、届いたら1となるような関数です。
遮蔽項によるレンダリング方程式の分離は、「外部から届いた光の項」と「光が自分の別の部分にあたって、その光が反射した項」の意味で入射光を分類したように取ることができます。
ここで、「光が自分の別の部分にあたって、その光が反射した項」は、一度光が反射してから届くので、「拡散光は反射率は小さくその効果は小さい」、「反射光は非常にまれにしか反射しないので、ほとんどの場合無視することができる」と理由で、これらの項を無視すると、レンだリング方程式は、

と近似することができます(もちろん、この近似が成り立たない場合もあります。そのときには、今回の方法は使えません)。
この関数に関して、入射光を球面調和関数展開

すると、次のような式に変形できます。

ここで、Almは、次のような係数です。

これらの式を見ると、今回は、前回と係数 Almだけが異なるということが分かります。
係数の違いは、遮蔽項があるかないかということです。前回は遮蔽項が無かったので、係数 Almはモデルの法線だけにしか依存していなかったのですが、今回は、法線ベクトルとレンダレングする位置に依存します。但し、法線ベクトルはレンダリングする位置だけによるので、実際には、レンダリングする位置だけによるということになります。
しかも、この係数はPRTのSH展開の係数に他なりません。そこで、前回はスフィアマップで求めた Alm を、模様を描いたデカールのテクスチャと同じ構造をもったテクスチャに焼き付け、デカールのテクスチャ座標を使って、係数 Alm を張り込みます。

今回用意したテクスチャは、次のものです。

自分でテクスチャを張り込んだのですが、きれいに張れていないのは勘弁してください。

レンダリングの工程では、最初に、このテクスチャがレンダリングされる座標を調べます。
これは、レンダリング先をテクスチャ座標にあわせて、位置座標をレンダリングされる色にしてレンダリングします。 適当にスケールをあわせると次のようになります。

同じように、法線マップも作成します。

次に、レンダリングしたテクセルごとに、レンダリングされる位置と法線方向の向きにカメラを置いて、モデルを描画します。
すると、自分が描画された位置から、外部の光がさえぎられるかわかるので、その情報を元に係数をレンダリングします。
実際に作成するシーンは次のようになります。

テクスチャを1つずつ走査して、スフィアマップの様に自分をレンダリングして、さらにSH係数を掛けることによって、被積分関数をもとめ、あとは64ボックスサンプリングで、1テクセルの情報まで落としこみます。
なお、x成分にSH(1,-1)、y成分にSH(1,0)、z成分にSH(1,1)、w成分にSH(0,0)の成分を埋め込んでいるので、今回は極彩色のグラデーションが見れると思います(今回は、2次以上の高次の計算は面倒くさいのでしていません)。
最終的な画像は次の様になります。

浮動小数点バッファがつかえない環境では、上のテクスチャを読み込んで、レンダリングの時に使えば、実行することができます。

描画方法とかは前と一緒なので省略~

■最後に

これなら、実用になるものだと思うのですが、いかがでしょうか。

それにしても、このモデルは、ティーポットのテクスチャの継ぎ目が分かってしまうので、きちんとしたモデルを準備したいですね。





もどる

imagire@gmail.com