超雑訳 Logarithmic Perspective Shadow Maps (9)

Share

D. Brandon Lloyd氏の博士論文である,Logarithmic Perspective Shadow Mapsを適当に訳していくことにします。
今回は実装の参考になるImplementation notesを訳していきます。
誤訳があったりなど,日本語としては多々見苦しい点があるかと思いますが,そこはご容赦ください。


CHAPTER 6

Implementation notes

この章ではグラフィックスハードウェア上でシャドウマップの実装するために関連する数多くの問題を議論します。射影テクスチャマッピングを用いたシャドウマッピングの概説から始めます。我々は単純に複数のパーティションを使用してシャドウマップを実装するための様々な選択肢について議論します。パーティションにライト錐台をフィットさせるために関係する問題,シャドウマップのための動的テクスチャアロケーション,パーティションカリングを使用したシャドウマップ描画の高速化,画像をレンダリングする間クエリするために適切なシャドウマップの選択について述べます。また,対数ラスタライゼーションをシミュレートするために使用するフラグメントプログラムも記載します。この論文における実験結果や画像はこのシミュレータを用いて得られています。また,デバッギング/可視化ツールに有益になることが分かったので,この論文を通じて使用したグリッドシェーダについてのコードも提供します。

6.1 Shadow mapping using projective texture mapping

シャドウマッピングはSegalら(1992)によってグラフィックスハードウェア上で射影テクスチャマッピングを使用して最初に実装されました。主なアイデアはオブジェクトの頂点からテクスチャ座標を計算するために射影行列を使用することで,シャドウマップクエリを実行するために使用されました。テクスチャ座標は頂点プログラム上でシャドウマップを描画するためにワールド空間の頂点座標にライトビューの行列\({\bf V}_l\) と射影行列 \({\bf P}_l\) を結合した行列\({\bf M}_l\) を乗算することによって計算することができます。同次3次元テクスチャ座標は頂点で計算され,プリミティブ上で線形補間されます。テクスチャ座標はシャドウマップをクエリするために使用されます。シャドウマップへとテクスチャをルックアップすることは一般的には同次座標をユークリッド3次元座標へと自動的に変換する際に除算を行うことによって行われます。またあるGPUはテクスチャリングモードを持っており結果となるテクスチャz座標とシャドウマップに格納された深度値の比較を自動的に実行し,0または1かどうかの比較結果を返却します。ハードウェアPCFフィルタリングを備えるGPUは\([0,1]\)の範囲で結果を返すことが出来ます。シャドウマップのルックアップの結果はサーフェイス上のライティングに乗算するために使用されます。

6.1.1 Modifications for LogPSMs

LogPSMsは射影テクスチャマッピングの上に構築されています。対数透視パラメータライゼーションの透視部分はちょうど説明したように処理されます。対数部分は2つの変更が必要とされます。最初に,シャドウマップは対数ラスタライゼーションを用いて描画されます。この章の後半で我々はフラグメントプログラムを用いて対数ラスタライゼーションの方法を述べます。次の章では対数ラスタライゼーションを処理するために既存のハードウェアをどのように拡張するかを説明します。次に,画像が描画されるときに手動でテクスチャ座標上で同次除算を行い,そのときにシャドウマップクエリのための最終的なテクスチャ座標を得るために式5.43での対数変換をy座標へと適用します。

6.2 Handling multiple shadow maps

パーティショニング技法は結果としてシーンを覆う複数のシャドウマップになります。複数のシャドウマップを用いた画像を描画するため多くの可能性が存在します。画像は一度に1つのシャドウマップを用いて複数のパスで描画するか,一度に全てのシャドウマップを用いてシングルパスで描画するか,あるいは複数のシャドウマップを用いて複数パスの組み合わせで描画することができます。各手法はそれぞれ利点と欠点があります。最もよいアプローチはアプリケーションや使用されているグラフィックスハードウェアに依存します

Multipass rendering. 最も単純なマルチパスアプローチはシャドウマップの描画とシャドウマップを用いた視点ビューからの画像への描画を交互に行うことによって最終的な画像に影を蓄積することです。最初の画像パスは通常と同じように描画することができます。しかしながら,次のパスでは現在のシャドウマップによって覆われた領域のみ注意深く修正しなければなりません。これらの領域へと描画することを制限する可能性はユーザークリップ平面,ステンシルバッファ,またはフラグメントのKill命令を含んでいます。シーンを複数回描画することは,大きな影響を与えるオーバーヘッドを招く可能性があり,特に複雑なシーンで頂点変換読み込みが高くなります。このコストは後でセクション6.5で述べるように現在のシャドウマップの部分に載らないオブジェクトをカリングすることによって減らすことが出来ますが,これは実装の複雑さのコストが増加することになります。
 他の可能性はディファードシャドウイングを使用することです。このアプローチでは,最初のパスはテクスチャ上に視空間の深度値が各ピクセルに格納されていることを除いて,事前に生成されています。視空間深度テクスチャはワールド空間のフラグメント位置を計算するために使用され,シャドウマップクエリが実行されます。このアプローチの主な欠点はテクスチャ座標とその他の補間量,ならびにスクリーン空間微分(フィルタリングに有益)が手動で計算される必要があり,かなり高価になる可能性があるか,また事前計算して,追加のテクスチャに格納され,追加のメモリとバンド幅を必要とするどちらかをしなければならないことです。従って,ディファードシャドウイングはより高いストレージ,バンド幅に対する頂点変換読み込み,そしてフラグメントシェーダコストをトレードします。ディファードシャドウイングに関する詳細は(Giegl & Wimmer, 2007a; Giegl & Wimmer, 2007b) を参照して下さい。

Singlepass rendering. シングルパス描画は複数パス描画を超える利点をいくつか持っています。マルチパス描画の冗長な計算を回避し,またディファードシャドウイングでは利用できないハードウェア補間と微分へのアクセスを持ちます。また,シングルパス描画はいくつかの欠点も持ちます。最初に,全てのシャドウマップはメモリに格納する必要があります。シャドウマップは大きくなる傾向があり,すぐにメモリリソースを使い果たす可能性があります。第2に,フラグメントシェーダはクエリするためのシャドウマップを決定する追加のコストを負担します。各シャドウマップに対するテクスチャ座標はハードウェア上で補間することが可能ですが,一般的には利用可能な補間機の数はかなり限られています。十分な補間機がないとき,テクスチャ座標はフラグメントプログラム上で計算しなければならず,より大きなコストを招きます。
 LogPSMの現在の実装はシングルパスアプローチを使用します。基本的なアルゴリズムの進行は次のようになります:

1. パーティションの計算。パーティションは視錐台の全体(シングルシャドウマップアルゴリズムについて),\(z\)-パーティションされたサブ錐台,あるいはフェースパーティションから構成されます。
2. 各パーティションに一致するシャドウマップについてパラメータライゼーションを計算する。このステップはパーティションにライト錐台をフィットさせることと,一致する行列\({\bf M}_l\) を計算することを含みます。
3. 各パーティションの最大誤差に基づき各シャドウマップに対するテクスチャ解像度を割り当てする。
4. シャドウマップを描画する
5. 画像を描画する。

Multiple passes with multiple shadow maps. 一度に複数のシャドウマップで複数パス描画することは, マルチパス描画のオーバーヘッドの増加を招くことなく少なすぎる補間機の問題を軽減します。しかしながら,このアプローチもまたシングルパスとマルチパスアプローチの両方の実装の複雑さを招きます。

6.3 Fitting a light frustum to partition

ライト錐台はライト行列 \({\bf M}_l\) によって決定されます。シャドウマップの空間と深度分解能を最大限活用するために,ライト錐台は可能な限り一致するパーティションにタイトにフィットさせるべきです。シャドウマップはシーンの見える部分のみを含む必要があります。それゆえ,視錐台とパーティションの交差を表現する各シャドウマップについてのバウンディング多面体を計算します。シングルシャドウマップについて,多面体は視錐台そのものになります。フェースパーティションについては多面体は視錐台によってクリッピングされた形になり,多面体はライトと面の各エッジを通る平面を持ちます。緊密な多面体は、シーンの一部が表示されているかを決定するためにさらなる分析をシーン境界との交差によって得ることが出来る可能性があります(Brabecら,2002b)。
 シャドウマップは視錐台内の遮蔽物の深度値の格納のみを必要とします。視錐台の外の遮蔽物については,任意の深度値は遮蔽されたサーフェイスの深度値よりも小さくなるようにはたらきます。それゆえライト錐台のファーとニア平面は視認可能なジオメトリを囲む多面体にフィットすることが出来ます。ライトとライト錐台のニア平面間にある遮蔽物による遮蔽情報は深度クランピングを用いて捕捉することができます。深度クランピングが利用できない場合,ライト錐台のニア平面は全ての潜在的な遮蔽物を含むように設定すべきです。ライト自身が視錐台内にあるとき,ライトとライト錐台のニア平面間のサーフェイスは影付けされません。したがって,ニア平面は影にならない領域を十分最小化するために近くが選択されるべきですが,深度分解能を保持するために十分遠くにあるべきです。例えば,最近のNV_depth_buffer_float 拡張によってサポートされるようなクランプされない浮動小数深度バッファは,影付けされない領域を排除することができますが,まだニア平面は十分な深度分解能を得るために注意して選択しなければなりません。 

6.3.1 Fitting face partitions in post-perspective space

フェースパーティショニングについて端面上でのユニフォームパラメータライゼーションを処理するために透視ワープドキューブマップアルゴリズム(Kozlov, 2004)を使用し,側面上に対数パラメータライゼーションの透視部分を使用します。主なアイデアはカメラの透視変換後の空間において視錐台の面をパラメータライズすることです。最初に,ライト\(\bf l\) はカメラ行列 \({\bf M}_c\) によって \({\bf l}’\) へと変換されます。この変換下では,視錐台は単位キューブにマップされます。次に,ライトについての射影行列 \({\bf P}_l\) は面に平行に方向づけされたライト錐台のニア平面を持つ単位キューブの背面にフィットします。\({\bf P}_l\) は\({\bf l’}\)がディレクショナルライト(同次座標 \(l’_w\) が0)の場合単純な正射影であり,または\({\bf l}’\) がポイントライトの場合はカスタマイズされた透視投影です。\(l’_w\)が負である場合,ライトに対して深度の順序は逆になります。適切な深度順序を復元するためには,\(z\)軸に一致する\({\bf P}_l\)の行を \(-1\) でスケールしなければなりません(図6.1参照)。式4.14において面選択基準が前面を選択する時,すなわち \({\hat {\bf z}}_e \cdot ({\bf l} – {\bf e}) > 0\) の時は逆転が発生します。したがって,透視変換後の空間で背面をパラメータライズするときは常に適切な面を選択します。パーティション多面体は単位キューブの背面と,ライトと単位キューブの交差による凸包を求めることによって計算することができます。最終的な行列はカメラ行列を含む各シャドウマップを描画するのに使用されます,つまり \({\bf M}_l = {\bf P}_l {\bf M}_c\)です。
 面分割あるいはシアリングを処理するための座標フレーム調整を使用する時,カメラの透視変換後の空間よりもライト空間で動作させるのが簡単であることが分かりました。
LogPSM_Fig_6_1

※図はLloyd, B. 2007. Logarithmic perspective shadow maps. PhD thesis, University of North Carolina. p.137 より引用。

6.4 Dynamic allocation of texture resolution.

セクション4.4.1で説明したように,利用可能なテクスチャ解像度はパーティションとシャドウマップ方向間の最大誤差のバランスをとるように分配することが出来ます。これを行うために,\(R_s\) と \(R_t\) (式4.5)を計算する必要があります。ディレクショナルライトについて,\(\delta_b\) における項のみが \(d_e\) と異なるので,\(n_l/d_l \rightarrow 1\) で,\(\cos \phi_l\) は定数になります。ユニフォーム,透視そして対数透視パラメータライゼーションについて\(\delta_l\)は減少せず,\(d_e\) は単調であるので,誤差の分配は視錐台の各面にわたって単調となります。これが意味するのは,視錐台の頂点において\(\delta_l / \delta_b\) を評価し,最大値をとることによって \(R_s\) と \(R_t\) を計算することが出来るということです。
 ポイントライトについて,面上の \(\delta_l / \delta_b\) の最大値を計算することはより複雑になる可能性があります。ライトに最も近い各面の点における誤差を評価することはまだかなり正確で安価な近似です。ポイントライトが面に近づくにつれて,面に割り当てされた解像度はゼロにまで落ち込みます。しかしながら,ユニフォーム,透視,そして対数透視パラメータライゼーションはライト付近に局所的に分解能を集中させることができません。ゆえにライト付近の高い誤差は面全域で高解像度を割り当てることにつながり,その他のパーティションのためにシャドウマップから解像度をとります。セクション5.1.4.1で説明した放物空間関数はこの状況をより良く処理することができます。ポイントライトが視錐台内に留まる時は,誤差計算における\(\cos \phi_l\) の項を除外することによってより好ましい結果が得られます。
 現在のGPUドライバーは,必ずしも各フレームとテクスチャの解像度変更のシナリオを処理するために最適化されていません。この論文で示された実験結果について,我々はシャドウマップの次元変化に適合するため充分に大きな単独の固定サイズのテクスチャアトラス上にシャドウマップをレイアウトしました。
 その他よりも1つの方向におけるテクスチャ解像度の割り当てを優先する際に時々有益になります。これは式4.41を修正することによって行うことが出来ます:
\[
r_s = \sqrt{ \frac{(1-\alpha)}{\alpha} \frac{R_s}{R_t} \sigma T},\hspace{1cm} r_t = \sqrt{ \frac{\alpha}{(1-\alpha)} \frac{R_t}{R_s} \sigma T}, \tag{6.1}
\]
ここで,\(\alpha \in [0, 1]\) は\(t\)方向に向かってどのぐらいの多くの解像度割り当てが偏っているかを制御します。
0.5の値が両方向に等しい均衡です。

6.5 Parition culling

パーティショニング技法は実装に応じて,シャドウマップと画像の両方に対する複数描画パスを必要とします。各描画パスは典型的には単一パーティションのみ関係があります。各パスについて描画パフォーマンスを最大化するために,オブジェクトはアクティブなパーティション内に実際に存在する場合のみ描画すべきです。我々はこれをパーティションカリングと呼びます。パーティションカリングはグラフィックスアプリケーション内で使われる既存の視錐台カリングのテクニックの単純な拡張を用いてライトとパーティションのシルエットエッジを含む平面に接触するかどうかをテストすることによって達成することができます。視錐台カリングと同様に,大きなオブジェクトは小さなサブオブジェクトへと分解することができ,シーン全体を境界階層ボリュームに配置することができます。充分に細かいカリング粒度で,複数パーティションをまたぐオブジェクトの数はオブジェクトの総数と比べると比較的に低くなり,大半のオブジェクトが一度のみ描画されます。したがってパーティションカリングで,余分な頂点変換読み込みを著しく減らすことが可能です。単純なシーンについては,パーティションカリングは小さな利益のみで,オーバーヘッドの価値がないかもしれませんが,ジオメトリ的に複雑なシーンについては,これは重要な最適化になる可能性があります。
 各パーティションそれぞれにオブジェクトが接触するかどうかを判定することは冗長な計算を含む可能性があります。これはなぜかというと,パーティション平面が隣接パーティション間でよく共有されるからです。それゆえ,一度に全てのパーティションについてパーティションカリングを実行するほうがより効率的にできます。これは,例えば,バランスのとれたBSPツリーへとパーティション平面を配置することによって実行可能です。
 DirectX 10 の機能をサポートするGPUはシングルパスで複数レンダーターゲットへと描画することが可能です。これの主な利点はGPUに転送する必要のある頂点データが一度のみであるということです。しかしながら,頂点データがすでにGPU上に存在する場合,複数描画によるオーバーヘッド減らすことはほとんどありません。その理由は,頂点変換読み込みが同じままであるからです。だからパーティションカリングはまだここでは同様に重要な最適化である可能性があります。

6.6 Shadow map selection during image rendering

シングルパスで複数シャドウマップを描画する時に,各フラグメントについてクエリし,適切なテクスチャ座標セットを計算するためにどのシャドウマップであるかを決定しなければなりません。我々は最初にシャドウマップとテクスチャ座標の選択周りの一般的な問題を説明し,このときに特定のパーティショニングスキームに対するアプローチを見ていきます。
 現在のGPU上では,シャドウマップはテクスチャサンプラーとテクスチャ座標のセットを引数にとるテクスチャルックアップ機能を用いてフラグメントプログラム上で一般的にアクセスされます。テクスチャサンプラーは通常読み書きのどちらも出来ない曖昧な疑似レジスタに関連付けされています。テクスチャ座標は一般的なレジスタに格納することができます。理想的には,各シャドウマップのテクスチャ座標は補間されるべきです。しかしながら,補間機の数は普通は非常に限られています。充分な補間機がない場合,テクスチャ座標はフラグメントプログラム上で計算する必要があります。これを行う一つの方法は,適切な変換行列によってフラグメントのワールド空間座標を乗算することです。
 最も一般的で単純な方法は複数シャドウマップに対するデータをパーティション番号によりアクセスされる配列に格納することです。しかしながら,フラグメントプログラムについてのプログラミングモデルは,配列の動的なインデックス付けには制限がかけられます。サンプラーは一般的には動的なインデックス付けは不可能であり,最近のGPUのみ補間機が動的なインデックス付けを行えます。多くの古いGPUは任意の動的な配列インデックス付けは全くサポートしません。動的配列のインデックス付けの代替えは,マスク付けされた総和,条件分岐,そしてテクスチャフェッチ依存を含みます。マスク付け総和は全ての入力データの重み付け総和を使用します。ただし,重みは要求するパーティションは1で,要求するパーティション以外は0の重みです。重みはベクトルデータ型の複数チャンネルにマスクとして格納されます。4つのパーティションを持つシャドウマップのテクスチャ座標(TEX0-3で示す)に対してハードウェア補間を使用することを仮定しています。以下のように4つチャンネルマスクを用いて適切な座標セットを選択することができます:

float4 partitionMask = computePartitionMask();
float4 texCoord = partitionMask.x * TEX0 +
                  partitionMask.y * TEX1 +
                  partitionMask.z * TEX2 +
                  partitionMask.w * TEX3;

4パーティション以上のマスクは複数変数に分割することが出来ます。すなわち mask0_3, mask4_7などです。マスクするアプローチはテクスチャサンプラーを選択するのには使うことが出来ません。これはなぜかというと,算術的な操作がこれらのオブジェクト上では許可されないからです。代わりに条件分岐を使用することが出来ます:

sampler2D sampler;
if ( partitionIndex < 2 )
{
    if ( parititionIndex < 1 )
        sampler = partitionSamplers[0];
    else
        sampler = partitionSamplers[1];
}
else
{
    if ( partitionIndex < 3 )
        sampler = partitionSamplers[2];
    else
        sampler = partitionSamplers[3];
}

条件分岐は\(\log(k)\) のみの動的なブランチされたテストを実行する必要があるので,ツリー上に配置されています。ただし,\(k\)はパーティションの数とします。通常動的分岐に関連するパフォーマンスペナルティがあるので,小さな\(k\)についてはマスク付け総和が実際には速くなります。条件分岐もまた命令予測で実装することが可能です。\(k\)のテスト全てが実行されるので両方の条件が実行されます。古いGPUにおける真の動的インデックス付けはテクスチャフェッチで実装することが可能です。パーティションデータはテクスチャ内に配置することができ,テクスチャ座標としてパーティションインデックスを用いて配列としてアクセスされます。このアプローチも同様のいくつかの制限を持ちます。再度になりますが,セマンティック制限のため,テクスチャはテクスチャサンプラーへと格納するために使用することが出来ません。テクスチャは,テクスチャ座標を計算するために行列のために使用されますが,複数テクスチャのフェッチは全てのパフォーマンスペナルティに関連するエントリーを持つすべてに読み出しするために必要とされます。
 DirectX 10 ハードウェアは1つのサンプラーで複数テクスチャへのアクセスを可能とするテクスチャ配列をサポートします。テクスチャはすべて同じサイズでなければなりません。ゆえに,パーティションが自己相似し,同じ誤差を持ち,同じ解像度を必要とする \(\sf ZP_{log}\)アルゴリズム(セクション5.1.7参照)はテクスチャ配列が最も適合します。
 \(\sf ZP_{log}\) の自己相似性もまた,補間が必要となるテクスチャ座標の数を減らすために使用されます。以下の式を用いて,パーティション\(i\) における位置\({\bf x}_i\) は最も小さいパーティション0における一致する位置\({\bf x}_0\) に変換することができます:
\[
{\bf x}_0 = ({\bf x}_i – {\bf e}) \left( \frac{f_e}{n_e} \right)^{-i/k} + {\bf e}, \tag{6.2}
\]
ここで,\(\bf e\)は視点位置で,\(k\) はパーティションの数です。式は線形であるので,射影行列\(\bf M\)によって変換された値もまた保持しています。パーティション\(i\) についてのシャドウマップテクスチャ座標を次のように計算します:
\[
{\bf s}_i = {\bf M}_{l, 0}({\bf x} – {\bf e}) \left( \frac{f_e}{n_e} \right) ^ {-i/k} + {\bf M}_{l, 0} {\bf e}, \tag{6.3}
\]
ここで,\({\bf M}_{l,0}\) はパーティション0についてのシャドウマップ行列です。もし, \({\bf M}_{l,0} ({\bf x} – {\bf e})\) を補間する場合,テクスチャ座標を計算する際にスケールと平行移動のみであることが必要とされます。

6.6.1 \(z\)-partitioning

\(z\)-パーティショニングについてのパーティションインデックスは比較と内積を用いて効率的に計算することができます(Engel, 2007):

float4 zGreaterThanN  = float4( n1_4 < eyePos.z );
float  partitionIndex = dot( zGreaterThanN, 1.0f );

定数 n1_4 は最初の4つの\(z\)-パーティションのニア平面までの距離( \(n_1, n_2, n_3, n_4\) ) を含んでいます。この手法はより多くのパーティションに拡張するのが容易です。パーティションマスクは同様に次のように計算されます:

float4 partitionMask = float4( (n1_4 < eyePos.z) & (eyePos.z <= f1_4) );

ここで,f1_4は最初の4つの\(z\)-パーティションのファー平面までの距離を含んでいます。

6.6.2 Face partitioning

フェースパーティショニングについて,各面において単一テクセルを持つキューブマップを用いてパーティションインデックスまたはマスクを計算します。各面のテクセルにおいて,面に一致するインデックスあるいはパーティションのマスクを格納します。Kozlov(2004)によって述べられた手法を用いてカメラの透視変換後の空間においてキューブマップのルックアップを行います。我々はキューブマップ上に直接シャドウマップを格納しませんでした。なぜかというと,キューブマップは異なる解像度または対数変換に必要となる非正方形テクスチャを現在サポートしないからです。また,我々はキューブマップの各面に側面に一致するのか端面に一致するのかどうかを示すフラグを格納します。このフラグは対数変換を適用するかどうかを決定するために必要となります。
 シアリングを処理するために側面分割が使用される場合,キューブマップの面の両半分にパーティション番号を格納します。2つ目のインデックスは分割されない面のために使用せずとっておきます。適切なインデックスを選択するために,面に対して分割平面が接触するフラグメントのワールド空間位置をテストします。最初の番号が負に一致すると平面の負側であるという規則を適用します。分割なしの面については,平面方程式\( (0, 0, 0, -1)\) を使用します。それは常に負の結果を与えることを保証します。フラグメントプログラム上での計算を保存するために,頂点プログラムで分割平面からの頂点位置の距離を計算し,補間します。このテクニックを用いたコードの一部分を図6.2に示します。
LogPSM_Fig_6_2

※図はLloyd, B. 2007. Logarithmic perspective shadow maps. PhD thesis, University of North Carolina. p.144 より引用。

6.7 Logarithmic rasterization.

LogPSMパラメータライゼーションは対数ラスタライゼーションを必要とします。対数ラスタライゼーションは平面のプリミティブを曲線になるようになります。対数変換は頂点プログラム上で頂点において計算することができますが,現在のGPUは射影変換のみをサポートするため,プリミティブはまだ描画するとき平面三角形へと分解されます。\(f_e/n_e\) の比率が大きいとき,このアプローチが持つ誤差を避けるためにシーンの非常に細かいテッセレーションが必要とされます。我々は現在フラグメントプログラム上でブルートフォースラスタライゼーションを実行することによって対数ラスタライゼーションをシミュレートしています。我々は最初に範囲を\([0, 0] \times [1, 1]\) に設定したビューポートで\({\bf M}_l\) を用いてシーンを描画し,OpenGLのフィードバックメカニズムを使用してクリップされた三角形の読み戻しをします。これにより\({\bf F}_p(u, v)\) によって変換された三角形を得ます。各三角形についてエッジ方程式と,深度補間式を計算します。このとき,\({\bf F}_{lp}\)の対数部分によって各三角形の頂点を変換し,バウンディングクワッドを描画します。図6.3のフラグメントプログラムを使用して各フラグメント位置において\(F_{lp,t}\)の対数部分を逆変換します。このとき,線形三角形エッジ方程式に対する位置を比較し,三角形の外側におちるフラグメントをdiscardします。対数部分 \(F_{lp,t}(v)\) の逆変換についての式は次のように与えられます:
\begin{eqnarray}
v &=& d_0e^{d_1t} + d_2 \tag{6.4} \\
d_0 &=& \frac{1}{c_1(y_1 -y_0)} \\
d_1 &=& \frac{1}{c_0} \\
d_2 &=& -\frac{c_1 y_0 + c_2}{c_1 (y_1 - y_0)}.
\end{eqnarray}
 我々の最適されていないシミュレータを用いてGeForce 6800GTのグラフィックスカードで 2.8GHzのプロセッサを備えたPC上でのフレームレートは2~3FPSを観測しました。時間の多くバウンディングクワッドを計算するのに費やされています。ジオメトリシェーダをサポートするGPUはもっとより効率的に湾曲した三角形のためのバウンディングクワッドを生成することができますが,我々はまだこれを実装していません。しかしながら,ジオメトリシェーダを用いても,対数ラスタライゼーションは線形シャドウマップラスタライゼーションよりも相当遅い可能性があります。深度情報をフラグメントプログラムが出力するときにGPUがもつ多くの最適化が無効化されます。例えば\(z\)-カリングや深度onlyレンダリングのための高等なラスタライゼーションなどです。
 次の章では,線形ラスタライゼーションに基づくその他のアルゴリズムに匹敵する速度でLogPSMを描画するためにどのように対数ラスタライゼーションがグラフィックスハードウェア上で実装可能であるかを示します。
LogPSM_Fig_6_3

※図はLloyd, B. 2007. Logarithmic perspective shadow maps. PhD thesis, University of North Carolina. p.146 より引用。

6.8 Procedural grid shader

この論文を通して,シーンへのシャドウマップテクセルの射影をより良く可視化するためのグリッドを使用しました。我々はこのグリッドをフラグメントシェーダ上でプロシージャルに計算しました。シェーダは与えれらた点ががテクスチャ空間上でのグリッド線上にのるかどうかを決定することによって動作します。これは図6.4に示すようにグリッド線の幅に対するテクスチャ座標の成分比を比較することによって実行されます。しかしながら,シーンへとテクスチャが射影されたとき,グリッド線の幅は引き伸ばされるか圧縮されます。それゆえ,グリッド線をスクリーン空間上の\(s\) または\(t\)の単位ステップ(微分を用いて計算される)の長さによってスケールします。シェーダコードは図6.5で与えられます。
LogPSM_Fig_6_4

※図はLloyd, B. 2007. Logarithmic perspective shadow maps. PhD thesis, University of North Carolina. p.147 より引用。

LogPSM_Fig_6_5

※図はLloyd, B. 2007. Logarithmic perspective shadow maps. PhD thesis, University of North Carolina. p.147 より引用。

コメントを残す

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

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください