こんちわ、Pocolです。
前回までで,ビジビリティカリングの説明が終わりました。
こんなに素晴らしいカリング手法があるのなら,積極的に使いたいと思いました。
で,ふと思いついたのが,ビジビリティカリングをシャドウキャスターのカリングに使おうという単純なアイデアです。
参考文献
[3] Oliver Mattausch, Jiri Bittner, Ari Silvennoinen, Daniel Scherzer, and Micheal Wimmer, “Efficient Online Visibility for Shadow Maps”, GPU Pro 3, pp.233-242, CRC Express, 2012.
[4] Jiri Bittner, Oliver Mattausch, Airi Silvennoinen, Micheal Wimmer, “Shadow Caster Culling for Efficient Shadow Mapping”, I3D’11: Symposium on Interactive 3D Graphics and Games, February 2011, pp.81-88.
実装アイデア
実装アイデアはいたって単純です。
[3]の文献で使用されているハードウェアオクルージョンカリングの代わりにカリング手法をビジビリティカリングに置き換えるだけのものです。
まず,以下を前提とします。
・カメラビューからみた深度バッファがある。
・シャドウマップ行列がすでに求まっている。
[3]の手法をかなり雑に説明すると,
欲しい情報は「カメラビューから見た時のピクセルにシャドウが落ちるかどうか?」であるので,カメラビューのピクセルにシャドウを落とさないものは,そもそも寄与しないからカリングしてよくね?というアイデアです。
実装のためのメモ
ここからは自分なりの実装前の実装するためのメモです。
[3]の手法を実装するために,マスクが必要なります。
まずは,Pre-Zなりで作成されたカメラビューから見た深度バッファを用いて,現在フレームのワールド空間位置座標に変換し点群を求めます。
次に,この求まったワールド空間位置座標にシャドウマップ行列を適用し,ライトビュー空間位置座標に変換します。
これでライトビュー空間からみたときのラスタライズ位置が求まるはずです。
あとはUAV等に,このラスタイズ位置に「カメラから見える」としてフラグを書き込みます。
これでマスクが完成です。
次に,False Negative Passと同じ要領でライトビューからOBBを描画し,マスクバッファ上のフラグが立っている場所にシャドウをキャストするものだけをビジビリティバッファ上に「見える」としてマークします。
これで「カメラビューに寄与するシャドウキャスターのみ」のビジビリティバッファが完成します。
あとはインダイレクトドロー情報を生成して,ExecuteIndirect()で描画すればOKのはず…。
オプションとして,Mainパスに当たる部分のように前フレームのシャドウマップバッファを用いて,粗くカリングしておくという手も考えられます。…あんまり高速化期待できないかもしれませんが。