ジオメトリシェーダでステンシルシャドウ&最適化

ジオメトリシェーダでステンシルシャドウを実装してみます。以前(DX9など)はシャドウボリュームの生成が面倒でしたが、ジオメトリシェーダを使うことによって簡単にできそうです。それと、単純な実装ではピクセルシェーダの負荷が大きすぎるため、できるだけシャドウボリュームの描画を減らす最適化も同時に行います。

ステンシルシャドウ
ステンシルシャドウ

ステンシルシャドウ

詳しい原理などは省略。ポリゴンの辺を光源方向に引き伸ばしたシャドウボリュームを描画することで影を生成します。表の場合ステンシル値を+1、裏の場合に-1とすると影の部分のステンシル値が0以外になるという仕組みを使い、すべてのポリゴンに対してこの処理を行うことで、ポリゴンモデルの影を落とすことができます。シャドウボリュームの生成にジオメトリシェーダを利用します。

デプスステンシルステートの設定

※ステートの設定は独自FXファイルで行っています

シャドウボリューム生成と最適化

すべてのポリゴンに対してシャドウボリュームを生成した場合、とてつもない量のピクセル処理が発生してしまいます。それを軽減するために事前に描画不要なシャドウボリュームを検出し、最適化を行います。隣接ポリゴンが共有している辺から延びるシャドウボリューム面は、必ず片方が+1、もう片方が-1となるため描画をキャンセルできます(ただし、光源方向から見た方向が同じ場合のみキャンセル可能)。これをジオメトリシェーダで検出し、必要なシャドウボリュームのみを描画します。隣接ポリゴンの情報が必要となるため、プリミティブは隣接付三角形リスト(triangleadj)を使用。隣接するポリゴンがない場合、正反対の隣接ポリゴンを登録、ジオメトリシェーダで判定、そこには必ずシャドウボリュームを描画。

※本当に最適化されているか未確認、FPS計測で確認予定

追記2013/4/30 最適化の効果を測定

CPU:Intel Core i3 3.30GHz
GPU:GeForce GTX 660

最適化 FPS ピクセル書込
255 18917158
1200 3722369

効果絶大。

影の描画

シャドウボリュームによって影の部分のステンシル値が0以外になっているので、その部分を半透明描画で暗くします。
画面全体に以下のシェーダ定義で黒いポリゴンを描画。

※ステートの設定は独自FXファイルで行っています

サンプルプログラム

“ジオメトリシェーダでステンシルシャドウ&最適化” をダウンロード dx11StencilShadow.zip – 59 回のダウンロード – 65 KB

隣接付三角形リストの生成

PMD/VMDファイル、シェーダファイル

sample_data.hで読み込むファイルを指定します。

リンクなど

スクリーンショットのモデルとモーション

モデルデータ

ままま式GUMIβ版

モーションデータ

【第9回MMD杯Ex】星間飛行GUMI/ニコニコ動画

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.