シャドウマップの解像度問題関連の諸技術について
シャドウマップのaliasing problemというのがある。光源方向と面の角度が近い部分に生じる影の例のギザギザであるが、これはカメラ近傍でバッファの解像度が足りないために起こる。一般的にカメラの視野は奥が広くなった錘台なのに対して、光源からの視野は平行光源なので直方体である。これで視錘台全体を単純に収めようとすると多くの無駄な部分が生じてしまうし、カメラの近傍が最も解像度が必要なのにも関わらず遠方と比べて小さな解像度しか確保されない。そこで、視野の錘台に対して光源の視錘台を様々にゆがませる手法が提案されてきた。
Perspactive Shadow Maps (PSM):
http://www-sop.inria.fr/reves/Marc.Stamminger/psm/
あらかじめカメラ方向からのprojection変換まですませたモデル(カメラから遠くが小さく近くが大きくなってる)をライト方向から見てZを描画する。無限遠光源のprojection変換はカメラ側で先に行われたprojection変換によってperspectiveなものに変更される。カメラとライトの角度が小さい場合、projection変換による変形は相殺され、いつもの扁平なシャドウバッファが描かれる。
Trapezoidal Shadow Maps (TSM):
http://www.comp.nus.edu.sg/~tants/tsm.html
PSMではカメラの動きが直接シャドウバッファの内容に大きな変化を与えるため、影が安定しなかった。(continuity problem)これを解決するため、カメラの視錘台を台形の断面をライトへ向けた柱体に近似するというのがTSM。これまたライトの向きがカメラに近づくと台形が描けなくなり意味がなくなる。
Light Space Shadow Maps (LiSPSM):
台形を求めるのが面倒くさいのでライト方向から見て90度の角度を向く錘台で近似する。ライト方向からはこの錘台の横っ面をいつも見ることになる。相変わらずカメラの向きとライトの向きの間の角度が小さくなると意味がなくなるし、カメラやライトがお互いの近くを移動すると錘台の角度が急激に変動しシャドウバッファの内容が大きく変わる。
シャドウバッファの内容を連続的にゆがませるのは限界が見えている。PSM以降のものはPSMの問題を根本から解決しているわけでなく、PSMでカメラとライトの角度に比例して解像度が落ちていくcontinuity problemを別の錘台を近似させることである程度角度が小さくなりきるまで破綻を抑制しているだけである。FPSならいいのだが、斜め見下ろしサードパーソンの場合、光源方向とカメラ方向の角度がほとんど重なってしまう場面が頻発するため、PSM系は全く使えないとしても言いすぎでない。また、モデルの一部分におけるシャドウバッファ上の解像度は一定に定まらないためシャドウマップをぼかして行うソフトシャドウ手法を併せて実装できないというのも個人的には欠点だ。このソフトシャドウが大好きなので。
Cascading Shadow Maps (CSM):
http://appsrv.cse.cuhk.edu.hk/~fzhang/pssm_vrcia/index.html
CSMは視錘台を複数に輪切りに切り分けて平坦なシャドウバッファを複数描く方法である。PSMの系譜に無いまったく別個のアイデア。ある程度の重なる部分をもたせてカメラからの距離によって視錘台を分割、これらにライトからの視野をピッタリ合わせてライトからのZを描画する。参照するときは複数のバッファのすべてをフェッチして、結果をピクセルシェーダ上でフェードしながら表示する必要がある。カメラからの距離を境界前後でclampしたものをフェードのパラメータとして用いる。3分割するのが一般的なようだが、2分割でも十分な性能を発揮する。ゲームの内容によっては、コストのかかるオブジェクトは近傍のバッファにしか描かないようにしてパフォーマンスを稼ぐなど細かな調整をすることもかんがえられるし、可能性は無限大。
もうPSM系はめんどいから黙ってCascading Shadow Mapsを使えばいいと思うよ。
http://videogameprogramming.blogspot.com/2006/03/cascading-shadow-maps.html