
シャドウボリュームは、 3Dコンピュータグラフィックスでレンダリングされたシーンに影を追加するために使用される技術です。これは、光源から遮蔽された領域の3D形状を記述するジオメトリとして、 1977年にフランク・クロウによって初めて提案されました[ 1 ]。シャドウボリュームは、仮想世界を影になっている領域と影になっていない領域の2つに分割します。
シャドウボリュームのステンシルバッファ実装はリアルタイムレンダリングで広く使用されており、特にビデオゲームDoom 3 [ 2 ]で採用されています。このゲームで使用されているこの技術の特定のバリエーションは、カーマックのリバースとして知られるようになりました。
現代のリアルタイムレンダリングでは、シャドウマッピング技術とそのバリエーションは、そのパフォーマンス特性と現代のレンダリングパイプラインとの互換性により、より広く使用されるようになっています[ 3 ] [ 4 ]。
影のボリュームを構築するには、光源から影を落とすオブジェクトの各頂点を通る光線を、ある点(通常は無限遠)まで投影します。これらの投影が合わさってボリュームを形成します。そのボリューム内の点はすべて影になり、ボリューム外の点はすべて光によって照らされます。
ポリゴンモデルの場合、ボリュームは通常、モデル内の各面を光源に向かっているか光源から遠ざかっているかに分類することによって形成されます。光源に向かっている面と光源から遠ざかっている面を接続するすべてのエッジのセットが、光源に対するシルエットを形成します。シルエットを形成するエッジは、光源から遠ざかる方向に押し出され、シャドウボリュームの面が構築されます。このボリュームは、可視シーン全体の範囲にわたって拡張する必要があります。多くの場合、これを実現するためにシャドウボリュームの寸法は無限に拡張されます(後述の最適化を参照)。閉じたボリュームを形成するには、この押し出しの前面と背面を覆う必要があります。これらの覆いは「キャップ」と呼ばれます。シャドウボリュームに使用される方法によっては、前面はオブジェクト自体で覆われ、背面は省略される場合があります(後述の深度パスを参照)。
シルエットのエッジに沿った面が比較的浅い場合、影にも問題が生じます。この場合、オブジェクトが自身に落とす影はシャープになり、多角形の面が露わになりますが、通常の照明モデルでは面に沿って照明が徐々に変化します。これにより、シルエットのエッジ付近に粗い影のアーティファクトが残り、修正が困難になります。多角形の密度を上げると問題は最小限に抑えられますが、完全に解消されるわけではありません。影ボリュームの前面がキャップされている場合、影ボリューム全体を光源からわずかにオフセットして、シルエットのエッジのオフセット距離内の影の自己交差をなくすことができます(この解決策は、シャドウマッピングでより一般的に使用されます)。
シャドウボリュームを作成するための基本的な手順は次のとおりです。

Crowに続いて、1991年にTim Heidmannは、ステンシルバッファを使用してシャドウボリュームを持つシャドウをリアルタイムアプリケーションで使用できるほど高速にレンダリングする方法を示しました。この手法には、デプスパス、デプスフェイル、排他的論理和の3つの一般的なバリエーションがありますが、いずれも同じプロセスを使用します。
これら3つの方法の違いは、第2段階におけるマスクの生成方法にある。2回の処理を必要とするものもあれば、1回で済むものもあり、ステンシルバッファの精度をそれほど必要としないものもある。
影のボリュームは、画面上の広い範囲を覆う傾向があり、その結果、3Dグラフィックスハードウェア上で貴重なラスタライズ時間(フィルタイム)を消費します。この問題は、影を落とすオブジェクトの複雑さによってさらに悪化します。各オブジェクトは、画面上に任意のサイズの影のボリュームを落とす可能性があるためです。フィルタイムの問題に対処するために使用される手法については、以下の最適化の項を参照してください。
ハイドマンは、影の前面と背面を別々のパスでレンダリングすれば、ステンシルバッファを使用してオブジェクトの前面と背面の数をカウントできると提案した。オブジェクトの表面が影になっている場合、オブジェクトと目の間には背面の影面よりも前面の影面が多くなる。しかし、それらの数が等しい場合は、オブジェクトの表面は影になっていない。ステンシルマスクの生成は次のように行われる。
オイラー標数によれば、すべての照明面はステンシルバッファ内で0に対応し、すべての閉じた多様体(影の体積)の前面と背面の数は等しくなります。
このアプローチでは、目自体が影のボリューム内にある場合(例えば、光源が物体の後ろに移動する場合)に問題が発生します。この場合、目はまずこの影のボリュームの背面を見ることになり、これによりステンシルバッファ全体に -1 のバイアスが加わり、実質的に影が反転します。これは、前面クリッピングプレーンなど、目に面する影のボリュームの前面に「キャップ」面を追加することで解決できます。目がカメラの後ろにある物体によって投影されたボリュームの影内にある場合も、同様の問題を防ぐために何らかの方法でキャップする必要があります。一般的な実装では、深度パスの適切なキャップ処理が難しいため、このような特殊な状況では深度失敗法(下記参照)が使用されることがあります。あるいは、カメラが内部にある影のボリュームごとにステンシルバッファに +1 のバイアスを与えることもできますが、検出処理が遅くなる可能性があります。
ステンシルバッファのビット数が、目とオブジェクト表面の間に見える影の数を収容するのに十分でない場合、別の潜在的な問題が発生する可能性があります。シーンに十分な数の影のボリュームが存在する場合、オーバーフローが発生する恐れがあります。彩度演算を使用する場合は、ボリューム計算の一部が無視される可能性があるため、問題はさらに悪化する可能性があります。
デプスパステストは、デプスバッファがしばしばzバッファと呼ばれることから、 zパステストとも呼ばれます。
2000年頃、数名が、ハイドマンの手法は深度を反転させることで、あらゆるカメラ位置に適用できることを発見した。物体の表面の手前にある影面を数える代わりに、物体の後ろにある影面を数えることで、同じ結果が得られる。これにより、目と物体の間の影のボリュームはカウントされないため、目が影になるという問題は解決されるが、影のボリュームの後端をキャップする必要があるという条件が生じる。そうしないと、ボリュームが無限遠に向かって後方に向いている部分で影が欠落してしまうことになる。
デプスフェイル方式は、ステンシルバッファの精度に関して、デプスパス方式と同様の考慮事項があります。また、デプスパス方式と同様に、Zフェイル方式と呼ばれることもあります。
ウィリアム・ビロドーとマイケル・ソンギーは、1998 年 10 月にこの技術を発見し、1999 年に Creative Labs の開発者会議である Creativity でこの技術を発表しました。[ 6 ]シム・ディートリッヒは、1999 年 3 月にGDCで、また 1999 年後半に Creativity でこの技術を発表しました。 [ 7 ] [ 8 ]数か月後、ウィリアム・ビロドーとマイケル・ソンギーは、同年、「シャドウボリュームとステンシルバッファを使用したシャドウのレンダリング方法」というタイトルでこの技術の米国特許を出願しました。 [ 9 ] id Softwareのジョン・カーマックは、2000 年にDoom 3の開発中に独自にこのアルゴリズムを発見しました。[ 10 ] id Software は、同社のEAXオーディオシステムを宣伝するゲームと引き換えに、Creative の特許を使用することを許可されました。[ 11 ]この特許は 2019 年 10 月に失効しました。[ 12 ]
上記のいずれのタイプも、排他的論理和のバリエーションで近似できます。このバリエーションは、シャドウボリュームの交差を適切に処理しませんが、レンダリングパスを1回(塗りつぶし時間ではない場合)節約でき、1ビットのステンシルバッファのみを必要とします。以下の手順は、深度パスバージョンの場合です。
{{cite web}}: CS1 maint: bot: 元の URL の状態が不明です (リンク)