~下の画像をクリックすると、影が動くアニメーションが見られます(注意:4.92MB)。■はじめに今回は,前回のプログラムを変更して、地平線マップに取り組んでみます。今回はセルフソフトシャドウのおまけ付きです。今回のプログラムは、次のものです。今回も、初期化に少し時間がかかります。(地平線マップ:DirectX9(頂点シェーダ1.1,ピクセルシェーダ2.0)まぁ、いつものように適当にファイルが入っています。出力されるフレームワークのファイルは紹介を省かせていただきます。アプリケーションのソースあと、実行ファイル、モデル及び、プロジェクトファイルが入っています。2つのマップの線型補間を使って計算していたために、2つの影を合成していたことがばればれでした。それは明らかに変なので、影が滑らかに移動する方法について取り組んでみます。その方法が地平線マップです。紹介されているので、今となっては、特に目新しい技術ではありません。地平線マップと前回の遮蔽マップの違いは、マップとして格納する変数の種類が違うということです。遮蔽マップの時には、ライトが当てられたときに、その部分が影になるかどうかを格納しました。(今回のプログラムでは、実際には、一番高い部分までの角度のタンジェントを格納しますが、本質的には同じ事です)。今回のマップを見ると、前回の影の形がくっきりと浮き出ていたマップとは違って、影の起きる方向に長い尾が確認できます。これは、「視線方向に一番高い部分」ということで、1つ高い山があれば、しばらくはその山が高い部分になるからです。今回は、影の落ちる角度とライトの角度を比較することによって、影になるか判定するので、ライトの角度、すなわち影の長さを自由に変えることができます。高いライトなら影を短く、低いライトなら影を長くするなどの調整が簡単に行なえます。今回は、視線も32方向に飛ばして、それぞれの方向に対する地平線マップを作成します。1つのマップにRGBAの4成分を使って、4方向のマップを格納します。今回の場合には、一番高い部分というものが補間されるので、途中の状態も滑らかなものとなります。■地平線マップの作成それでは、地平線マップを作成しましょう。地平線マップは、前回の遮蔽マップとそれほど変わりません。視点の高さを比較して、それを視線のテクセルまでの距離で割って、tan(地面の高さの仰角)を計算します。}先ほどの計算では、一番高い場所の判定はしていません。高い場所を検索するために、アルファ合成を使います。これは、ピクセルシェーダの出力と、すでにレンダリングされたフレームバッファの値を比較して、値の大きな方をフレームバッファに書き込むというものです。何のために使うんだこんなのと思っていたのですが、こんな使い道があるんですね。テクセルをずらした量をシェーダに引き渡すのを忘れないようにしましょう。}■シーンの描画さて、それでは地平線マップを使って影をつけましょう。それがライトの高さ(下のプログラムでは0.3)と比較して、地面が高ければ日が射さない影(遮蔽量が1)になって、地面が低ければ日が射します(遮蔽量が0)。ライトの高さを変えれば、影の長さは変わります。あとは、この遮蔽量を使って、照明計算をします。Out;}さて、これだけではくっきりした影になるので、ソフトにしましょう。影になったとしても、真っ暗にするのではなくて、少しだけ暗くするようにします。具体的には、影に隠れたとき(光の高さまた、遮蔽量が0より小さくなることはないので、0でクランプします。}■マップの枚数に関する考察CEDECの時には、地平線マップは、8方向からのライティングを記述する2枚のテクスチャだけで十分だという説明がなされました。今回は、8枚のテクスチャを追加って、32方向からのライティングを記録しています。この枚数が少ないとどうなるのでしょうか?ためしに、今回のプログラムでマップの枚数を1枚にしてみて、4方向からの光しか考えないと、次のアニメーションになります。4方向しか遮蔽マップを作成しないときには、高い山の影はライトをぐるりと1週させたときに星型の軌跡を描きます。従って、山の高さが高いと、マップの枚数が少ないときにはおかしな影ができることがわかります。山の高さがそんなに高くなくて、影がさほど伸びないなら、4方向や8方向でも十分な場合はあるでしょう。■最後に前回と今回は、テクスチャに遮蔽情報を埋め込んでライティングをしました。なければいけないわけではありません。ポリゴン1枚使うだけでも、けっこうましな画面を作ることができます。非常に遠くの景色で、詳細な情報が要らないなら、これで十分でしょう。光源の方向によって、影を変化させることができるので、こけおどしもばっちりです。もどるimagire@gmail.com。