可視マップ

可視マップ(visibility map)を作ってます。
視点から飛ばしてレイが物体に衝突したときに、そこから光源にシャドウレイを飛ばして
光源の寄与を計算するのですが、毎回のシャドウレイの衝突判定の計算時間を減らすために、
あらかじめUVマップ上に各点から光源への可視性(シャドウレイがぶつかるかどうか)
を計算しておいて、後で参照する方法です。いかにも計算時間が短縮できそうです。


IBLの場合、各光源サンプルに対して可視マップを生成します。
光源が128点の場合には128枚の可視マップ画像が必要となるため、メモリが厳しそうです。


それはおいておいて、とりあえず1つの光源に対して可視マップを作ってみました。


(a)元のリンゴ画像(IBL・128点でレンダリング


これに対して、128点の光源の内,一つの光源に対応する可視マップを計算した結果です。


(b)可視マップ


赤い部分がシャドウレイが光源に届いた(U,V)値で、青い部分がシャドウレイが遮蔽された(U,V)値に相当します。
これをそのままテクスチャとして表示してみました。青い部分は影に相当します。


(c)可視マップの貼り付け


ちなみに、以下が可視マップではなく、パストレで各点で可視性を計算した正しい結果です。

(d)ちゃんと計算した正しい結果


分かりづらいですが、(c)と(d)のリンゴのへその部分で微妙に違うようです。(U,V)値から各ポリゴンの局所座標系(u,v)への変換誤差や可視マップの画像サイズや、UV展開の形状に問題がありそうです。

実際に、リンゴのへその部分ではUV展開した三角形がつぶれているようです。


(d)可視マップ上のつぶれた三角形(下側の三角形)


以前からポリゴンとUVがユニークに対応するようなUV展開をしてくれるようなフリーのソフトや
ポリゴンモデルを探しているけど、なかなか見つかりません。
ユニークで三角形間の隣接性を保ち、三角形がつぶれることなく、ポリゴンとUV上の三角形の面積が同じように
自動展開するのは難しそうです。


ただし、可視マップの場合には、可視性のデータを保存できれば良いので、
テクスチャマップのように人間が編集しやすいようなUV展開でなくとも、ポリゴンごとに可視性の
UVルックアップテーブルを持たせれば良さそうです。

あと、最初で述べたサンプル点が128点とかなった場合だけど、128点のデータを保存するのではなく
乱数nに対して、n \mapsto光源のインデックス に対応付けるハッシュみたいなのを持たせたらいいかも。
cos則を含めた重点的サンプリングもできそうだし。さらに消費メモリが増えそうだけど・・・


それと、青い部分と赤い部分の境界箇所では可視マップを参照するのではなく、まじめに
シャドウレイを飛ばしたほうがよさそうだ。