影まとめ

Mount&Bladeでは木漏れ日の下をくぐるとちゃんと木漏れ日の影が、しかも輪郭をもたないぼやけた影が体に落ちる。木漏れ日の下を馬に乗ってパカパカとくぐりぬけたとき、どっかの美容外科の古いCMみたいなエロイ雰囲気になんだか感動してしまって、影界隈を調べてみた。なにかソフトシャドウを高速に描画する方法が発見されたのかなと思ったが違ったね。GeForceでサポートされてるシャドウマッピング用のハード機能を使ってるらしい。なにはともあれここへくるまで割と調べたりしたのでまとめておくことにする。

シャドウマッピング界隈はデプスバッファをどうやって効率よくびったり四角いテクスチャに収めるかとかライトスペース関連、とソフトシャドウとの2つのテーマについて様々な手法が提案されているようだ。どうやって収めるかは今はどうでもいい。後で広い地形を描画しなくちゃならなくなったら見ることにする。

PCFについて。とりあえず単純に考えれば影の輪郭をぼやけさせるために近傍の点を複数サンプリングして何個が影で何個が光があたってるかを数えて濃さを決めればいい、という考えに行き着く。だがデプスバッファの大きさに比べて描画する領域の方が解像度が高いのでどうしても影だけドット絵になってしまう。そこでUVから、マップのピクセル中心からどれだけ離れてるかを考慮してマップの同じ1ピクセルを参照した場合でも結果にグラデーションをつけたのがBillenear PCF。NVidiaはハードでこれをやってくれる。サンプルする点を半分ランダムにして結果にノイズを加えてバッファのピクセルの境界を誤魔化したのがIrregular PCF、UVの値に基づいてランダムなサンプル点のオフセット群を回転させて、隣の点は隣の点とあまり変わらないけど全体としてはランダムという微妙な要請を実現してる。おもしろいアイデア

VSMについて。サンプル結果をぼかさずに、デプスバッファ自体をぼかしちゃえばいいんじゃないの?というところから話をはじめる。デプスバッファ自体をぼかして、バッファのデプスとの差を結果のぼかしに使うと影を落とす面との距離がひらけばひらくほど差が大きくなって、現実と逆に遠いほど濃くて輪郭のはっきりした影になってしまう。VSMではデプス値の2乗も保存して一緒にぼかす。これを描画時に1乗の方を2乗したものと比べると、輪郭部分においてどれだけ大きなコントラストを補間したかが算出できる。これを使って実際のバッファのぼかしをリアリティのある数値へもっていく。描画時には一点をサンプルするだけでいいので軽い。浮動小数点テクスチャとその補間機能が必要。ハードでこれをサポートしているものはまだ少ない。事前計算できる場面なら普通に使える。非常に微細な差を調べるので浮動小数点の解像度がなくてはだめ。

はじめwikipediaにはトンデモ論文ばっかりがリストされててだまされた。NvidiaGDC関連からあたるべき。

しかし影のぼかしはDX10では標準になってるしNVidiaじゃハードウェア実装されてるし、ということを考えるとライトスペースの方が今世間的には重要なトピックなんだろうと思う。