~■はじめに前回、リアルタイム大域照明を取り扱いました。これは、入射光を環境マップとして取り込んで、それらを球面調和関数展開することによって、拡散光をより正確に表現する手法です。今回は、さらにPRTを併用して、自己遮蔽つきのリアルタイム大域照明を実装してみました。いつものようにプログラムです。用のプログラムも用意しておきました。カーソルキーで、カメラが回って、zやxでズームが変えられます。マップなし」、「環境マップのみ」の切り替えができます。pキーでティーポットの動きを止めることができます。上の画像は、下のように拡散光と環境マップが合成されて最終的な出力になっています。=ソースには、いつものように適当にファイルが入っています。大事なファイルは次のものです。マップのためのシェーダ■何をやっているの前回は、オブジェクトに入射する光のレンダリング方程式の入射光Liに関して、SH展開をしました。今回は、このレンダリング方程式を2つの項に分解します。このV(x,ωi)は遮蔽項と呼ばれる項で、外部から入射した光が自分のほかの部分にさえぎられて届かなかったら0、届いたら1となるような関数です。遮蔽項によるレンダリング方程式の分離は、「外部から届いた光の項」と「光が自分の別の部分にあたって、その光が反射した項」の意味で入射光を分類したように取ることができます。ここで、「光が自分の別の部分にあたって、その光が反射した項」は、一度光が反射してから届くので、「拡散光は反射率は小さくその効果は小さい」、「反射光は非常にまれにしか反射しないので、ほとんどの場合無視することができる」と理由で、これらの項を無視すると、レンだリング方程式は、と近似することができます(もちろん、この近似が成り立たない場合もあります。そのときには、今回の方法は使えません)。この関数に関して、入射光を球面調和関数展開すると、次のような式に変形できます。ここで、Almは、次のような係数です。Almだけが異なるということが分かります。係数の違いは、遮蔽項があるかないかということです。Almはモデルの法線だけにしか依存していなかったのですが、今回は、法線ベクトルとレンダレングする位置に依存します。法線ベクトルはレンダリングする位置だけによるので、実際には、レンダリングする位置だけによるということになります。この係数はPRTのSH展開の係数に他なりません。今回用意したテクスチャは、次のものです。自分でテクスチャを張り込んだのですが、きれいに張れていないのは勘弁してください。レンダリングの工程では、最初に、このテクスチャがレンダリングされる座標を調べます。これは、レンダリング先をテクスチャ座標にあわせて、位置座標をレンダリングされる色にしてレンダリングします。適当にスケールをあわせると次のようになります。同じように、法線マップも作成します。次に、レンダリングしたテクセルごとに、レンダリングされる位置と法線方向の向きにカメラを置いて、モデルを描画します。すると、自分が描画された位置から、外部の光がさえぎられるかわかるので、その情報を元に係数をレンダリングします。実際に作成するシーンは次のようになります。テクスチャを1つずつ走査して、スフィアマップの様に自分をレンダリングして、さらにSH係数を掛けることによって、被積分関数をもとめ、あとは64ボックスサンプリングで、1テクセルの情報まで落としこみます。x成分にSH(1,-1)、y成分にSH(1,0)、z成分にSH(1,1)、w成分にSH(0,0)の成分を埋め込んでいるので、今回は極彩色のグラデーションが見れると思います(今回は、2次以上の高次の計算は面倒くさいのでしていません)。最終的な画像は次の様になります。浮動小数点バッファがつかえない環境では、上のテクスチャを読み込んで、レンダリングの時に使えば、実行することができます。描画方法とかは前と一緒なので省略~■最後にこれなら、実用になるものだと思うのですが、いかがでしょうか。それにしても、このモデルは、ティーポットのテクスチャの継ぎ目が分かってしまうので、きちんとしたモデルを準備したいですね。もどるimagire@gmail.com。