デプスシャドウ技法~その基本形
GPUのピクセルスループット(テクセルフィルレート)が劇的に向上したことに後押しされて、最近では「ステンシルシャドウボリューム技法」よりも採用例が多くなってきているのが「デプスシャドウ技法」(Depth Shadow)だ。この技法は「シャドウマップ技法」(Shadow Maps)や「デプスバッファシャドウ技法」(Depth Buffer Shadow)とも呼ばれたりするが、本連載では「デプスシャドウ技法」で統一する。
この技法はDirectX 9/SM3.0時代に様々な改良版が生まれており、本連載では、その改良版までを紹介しようと思う。まずは、この基本形の概念から解説しよう。
この技法では光源からの遮蔽構造を、「光源から遮蔽物までの距離」の情報で表現するのがキモとなる。
「光源から遮蔽物までの距離」……というと難しいイメージがあるが、実はこれは光源の場所を仮想的な視点として、そのシーンの深度値を求めるZバッファレンダリングを行うことで得られてしまう。
この光源からの距離をまとめたZバッファ(デプスバッファ)の内容は実質的に「遮蔽の分布」を表すので、これを特に「シャドウマップ」と呼ぶ。この技法を「デプスシャドウ技法」「デプスバッファシャドウ技法」「シャドウマップ技法」と呼ぶのはこのあたりから来ているのだ。なお、このシャドウマップはZバッファではなくテクスチャ(最近では浮動小数点テクスチャなど)に対して生成する場合もある。
最終的なシーンのレンダリング時には、描画対象ピクセルについて、光が当たっているピクセルなのか、そうでないのか(=影になる)を、そのシャドウマップを参照し判定しながら描いていく。
描画対象ピクセルとシャドウマップとの対応は、そのシャドウマップを、前述した投射テクスチャマッピングの要領でシーンにマッピングしてやることで実現される。
描画対象ピクセルが3D空間上において、光源からどれくらいの距離にあるのかを計算して求めて、それと対応するシャドウマップの値を比較してやる。
この比較は、イメージ的には、描画するそのピクセルに対して光が届いているかどうかの判定に相当する。届いている場合、そのピクセルの光源からの距離とシャドウマップ側の値は一致することになる。つまり、この場合は光っている、という判断になる。
一方、シャドウマップ側の値の方が小さいという場合は、描画対象ピクセルのところまで光が届かなかった(=つまり遮蔽されている)ことを表すので影になるのだ。
光の遮蔽構造がちゃんと考慮されるので、この技法でもセルフシャドウ表現は行われる。そしてもちろん相互投射影の表現も自ずと現れる。
シャドウマップの生成は、実際にそのシーンに登場する全てのポリゴン(3Dモデル)を光源方向からレンダリングすることに相当するので、負荷は高そうだ。しかし、テクスチャ適用や特別なピクセルシェーダによるライティングを行わないZ値出力だけのZバッファレンダリングは、最新GPUは倍速で動作するので比較的高速に完了できる。
このシャドウマップ生成のZバッファレンダリングの際に、ポリゴンに貼られたテクスチャの内容に配慮したシャドウマップを生成することもできなくはない。そうすればステンシルシャドウボリューム技法で問題となった四角ポリゴンに葉テクスチャを貼ったケースにおいても、ちゃんと葉の形で影を落とすことが可能となる。
デプスシャドウ技法の問題点
この技法のキーポイントは、そのシーンの光の遮蔽構造を表したシャドウマップの精度にある。そう、生成される影の品質や精度は強くシャドウマップの解像度に依存してしまうのだ。
広いシーンの遮蔽構造を解像度の不十分なシャドウマップで生成した場合、影は非常に大ざっぱになるどころか、強いジャギーが出てしまう。
例えば、例えば100m×100mからなるシーンの全ての影を256×256テクセルのシャドウマップで表したとしよう。すると、(100m÷256テクセル)で、約40cm×40cmの領域の遮蔽構造がわずか1テクセルに落ち込んでしまう。要するに、ある程度狭い屋内のようなシーンならまだしも、屋外などの広い空間では、高解像度のシャドウマップを生成しなければ、影の品質はかなり落ちてしまうのだ。
シャドウマップ解像度が不十分だと、このデプスシャドウ技法はカクカクした影になってしまうのに対し、ステンシルシャドウボリューム技法ではこうした問題は起こらない。このカクカクした影のジャギーをなくすには、短絡的にはありったけの高解像度のシャドウマップを作ることだが、それは実際問題として難しい。
このデプスシャドウ技法の進化の歴史は、この影のジャギーをなくすための工夫に等しく、今でも様々な改良型デプスシャドウ技法が編み出されている。
次回からはそうした改良版の典型をいくつか紹介していくことにしよう。(続く)
(トライゼット西川善司)