プロシージャルグリッドシェーダ。
Playing with Real-Time Shadows
Playing with Real-Time Shadows
CrytekのSIGGRAPH 2013のスライドの超雑訳。
Deferred Shadows
Cacaded Shadow Maps
Soft Shadows Approximation
Shadows & Transparency
Contact Shadows / SSDO
Screen Space Self-Shadowing
Volumetric Shadows
Area Light Shadows
Typical Shadows Frame Budgets (典型的なシャドウにかかるフレームに割り当てることができる時間)
典型的なビデオゲームの1フレームあたりの処理コストに割り当てられる時間は33ms(30FPS)
4000 ドローコール(平均的なPC)
~5から7msがシャドウに割り当てることができる時間
シャドウマップのテクスチャプールは10Mb(Xbox360, PS3)
PCはもっと大きくできる。
10 + シャドウをキャストしようとするライトの数。
Deferred Shadows (遅延シャドウ)
太陽光に対するシャドウマスク
シャドウの遮蔽を蓄積するための特別な描画ターゲット。
シャドウマスクは,実際のシェーディングを適用する前に,互いの上で複数のシャドウテクニックを組み合わせます。
VSM(分散シャドウマップ), オブジェクト毎の影, 雲の影
点光源(ポイントライト)のシャドウは,ライトバッファに直接的に描画されます。
Cascaded Shadows Maps (カスケードされたシャドウマップ)
視錐台は,複数のシャドウ錐台にまたがる
ふつうは,距離に基づく分割(distance-based splitting)を用いる
カスケードの分離スキーム
対数的にテクセル密度分布を近似する。
シャドウ錐台は,伝統的にカメラの視錐台を覆うように調整。
シャドウ錐台に対する幾何学的配置はワールド空間に固定する。
もっとカスケードを持つことができる
改善されたテクセル密度は,エイリアシングを低減し,対数分布をよりよく近似するためにより広いシャドウ範囲に対して自己影を向上します。
シャドウマップのテクセルグリッドのために各カスケードはシャドウ錐台のスナップショットを撮ります。
Deferred Shadow Passes (遅延シャドウのパス)
カスケードに対するシャドウパス / 点光源は異なる方法で描画されます。
潜在的にシャドウが落ちるエリアは錐台ボリュームを描画することによってステンシルバッファ上にタグ付けされます。
カスケードへより洗練された分割を持つことができます。
重複領域上では高解像度なテクスチャを持つカスケードを選択します。
シャドウマップの空間をより効率的に使用することができます。
Shadow Cascades Caching (シャドウカスケードのキャッシング)
1フレームでカスケードのすべてが更新されるわけではありません。
いくつかのフレームにわたって更新コストが分散される。
パフォーマンス上の理由。
より多くのカスケードを持つことができる - 良いシャドウマップ密度分布
遠く離れたカスケードは少ない頻度で更新される。
キャッシュされたシャドウマップは更新されませんが,シャドウイングのために使用されます。
メモリを追加することで動的なオブジェクトを扱うことができます。
最後のカスケードはVSMを使用し,シャドウマスクを付加的に伴った状態でブレンドされます。
非常に遠くのオブジェクトから大きな半影を持つことができます。
Point Light Shadows (点光源シャドウ)
我々は常に6つの独立したプロジェクターに無指向性ライト(omni-directional lights)を分割します。
各プロジェクターに対するシャドウマップは,別々にスケーリングされます。
シャドウの投影範囲に基づく。
最終的なスケール値は,対数シャドウマップ密度分布関数の結果であり,その関数はパラメータとして範囲を使用します。
大きなプロジェクターにカスケードを使用する。
スケーリング後の各フレームのシャドウマップすべてをまとめるためのテクスチャアトラス。
テクスチャアトラスはメモリ断片化を避けるために恒久的にアロケートされる。
コンソール上のサイズ:1024 × 1024 (4MB)
シャドウを受け取る領域はステンシルによってタグ付されている。
Per-Object Shadow Maps (オブジェクトごとのシャドウマップ)
カットシーンやゲーム上で非常に大きく詳細なオブジェクトに対して,自己影の詳細度を増加するのに使用する(first person weapon).
専用のオブジェクトに対して別々の高解像度なシャドウマップ。
グローバルやオブジェクトごとのシャドウはmax()フィルタでシャドウマスクにブレンドされます。
グローバルシャドウマップ(CSM, 点光源)で低解像度の自己影を排除するために,非常に大きなオブジェクトごとのシャドウマップバイアス。
オブジェクトは依然としてグローバルな低解像度シャドウをキャストする。
自己シャドウイングのみが高解像度シャドウマップからくる。
First Person Weapon Self-Shadowing
レンダリングとグローバルシャドウマップ生成のための異なるファーストパーソンとサードパーソンモデル。
適切な自己影は分割した各オブジェクトごとのシャドウマップのみで達成することができます。
遅延シャドウイングでの問題
異なる視錐台を使用(近 / 遠平面, FOV).
一般的なケース - "武器"空間からの武器の深度を再射影する必要があります。
FOVの差が大きくない場合 - 単純な深度の再スケーリングで,再射影を近似。
Soft Shadows Approximation (ソフトシャドウ近似)
シャドウ空間上でランダム化された回転でポアッソンPCFタップを使用する。
実行時にカーネルサイズの調整することは,変化する半影でソフトシャドウの近似を良くする。
ソフトシャドウのアイデア: シャドウキャスターへの平均距離の比を推定する。
Percentage-Closer Soft Shadow[Randima05]に類似。
基本アルゴリズム:
ポアッソン分布されたタップはカーネル中からの距離によって事前ソートされています。
初期カーネル半径が最大範囲(=最大 / 最長半影)に一致するように設定。
平均距離比率を推定するために,このカーネルを使用します。
サンプルの量は,平均距離比に比例して低減されます。
タップはソートされているので,カーネル半径に影響を与えます。
最後の影計算に対するサンプルの量を減らすためのみに使用します。
カスケードシャドウマップは,カスケード間の遷移を扱うためにカスタムカーネルスケールの調整が必要になります。
シェーダオプションの計算:コンピュートシェーダの共有メモリへと全てのタップをフェッチし,距離の推定とシャドウ計算に対してそれらを再利用します。
Area Lights Shadowing(エリアライトシャドウイング)
複数解像度均一ボクセルデータ。
非常に大きなボリュームに対する効率的な遮蔽サンプリング
レイのトラバーサルに対する適応解像度。
複数の距離に基づくカスケードはオプション。
動的なサーフェイスボクセル化とダウンサンプリング
"ディレクショナルオクルージョン"値をダウンサンプリング。
適応的ダウンサンプリング
シーンの各フレームの静的な部分の更新を回避します。
ビットマスクの変化を意識しダウンサンプリング(前のフレームのボクセルデータとXOR)
Voxel Data Downsampling (ボクセルデータのダウンサンプリング)
ディレクショナルオクルージョンのコンセプト
ライトオクルージョンをダウンサンプリング
双方向; 3つのコンポーネント
Area Light Shadows(エリアライトのシャドウ)
グループ化されたレイの近似。
異なるボクセル化されたレベルをサンプルする。
レイに沿ってボクセルレベルを調整。
ディレクショナルオクルージョンギャザリング。
サンプリングエラー
コーントレーシングでワールド空間アンビエントオクルージョン。
8つの均一な分散されたコーンで近似。
Shadows & Transparency(シャドウと透過性)
アルファブレンドされたシャドウレシーバーについて
シャドウを適用するためのフォワードパス
透過シャドウキャスター(e.g. 髪,煙)について,我々はキャスターのアルファ値を蓄積します。
8ビットレンダーターゲット上に保存する。
透過マップの生成:
バック射影/漏れを避けるために正規の不透明なシャドウマップからの深度バッファを用いて深度テストを行う。
透過アルファは "不透明な"シャドウではないオブジェクトのみに対して蓄積されます。
透過アルファを蓄積するためのアルファブレンドされたシャドウ生成パス(後ろから前へとソートされる).
カスケードシャドウマップの場合においては,各カスケードに対して透過マップを生成する。
シャドウマップと透過マップからのシャドウ項はmax()演算で,遅延シャドウパスの間,両方とも結合します。
Contact Shadows(密着性シャドウ)
密着性シャドウ/スクリーン空間ディレクショナルオクルージョン
スクリーン空間ベント法線(平均非遮蔽方向)を介して,すべての光源とアンビエントに適用される。
コアアイデアはSSDO[Ritschel 2010]と同じ
計算されたスクリーン空間オクルージョンでライティングを調節する。
やわらかい密着性シャドウを生み出す。
シャドウバイアスの問題を隠すことができる。
SSAOだけよりもかなりの品質を上げる。
ディファードの方法でディレクショナルオクルージョンの情報がアクセス可能。
既存のライティングパイプラインへとよりよく適合する。
各光源に効率的に適用することが可能。
遮蔽情報の生成
SSAOパスの間ベント法線N'の計算と保存。
ベント法線は平均的な非遮蔽方向。
任意の自己遮蔽なし比較的広い半径でクリーンなSSAOを必要とします。
各ライトについて
通常のように N dot L を計算する
N' dot L を計算する
中心深度はフル解像度で,他のすべてのタップはFP16の半解像度の深度です。
クランプされた2つの内積間の差分を遮蔽量に乗算することでライティングを減衰させる。
Screen Space Self-Shadowing(スクリーン空間自己シャドウイング)
単純なトリック / 近似
スクリーン空間のライトベクトルに沿ってレイキャスティングする。
カットシーンのために,影響を受けた深度バッファ範囲を指定します。
レイの長さを追跡することで適切なソフトシャドウイングを計算することができます。
Volumetric Fog Shadows(ボリュームのあるフォグのシャドウ)
TOTH09に基づく: 内部散乱光を蓄積するのではなく,代わりに視線のレイに沿ってシャドウの値を蓄積します。
シャドウ空間でレイキャスティングする。
インタリーブパスは,隣接するピクセルで共有された8x8のグリッド上でビュー方向に沿ってシャドウサンプルを割り当てます。
パフォーマンスのために半解像度の出力ターゲット。
ギャザーパスは,最終的なシャドウの値を計算する。
バイラテラルフィルタティングはゴーストとハローを最小化するために使用されます。
シャドウはアルファに格納し,8ビット深度Rチャンネル上に格納されます。
中心のフル解像度深度と比較するために8タップを使用する。
最大サンプル距離設定(C3レベル上で~150-200m)
雲の影テクスチャは最終的な結果に焼き込まれます。
最終結果は,フォグの高さと放射上の色を変更します。
カスケードされたシャドウマップのレイキャスティング
シャドウ空間上でレイキャスティングを行う。
適応的なレイキャスティング - 近傍の空間でより多くのサンプルをとる
カスケードのための任意のシャドウ錐台
錐台は重なっています。
常に再考のサンプリング密度でカスケードを選ぶ。
シャドウ錐台と現在のレイの交差を保存するためにグローバルなパラメトリック座標を使用します。
カスケード間で再射影する必要はありません。
直接グローバルパラメトリック座標を変更する最適化されたレイクリップ関数。
Cascaded Shadows Maps Split Consideration(カスケードされたシャドウマップ分割の考察)
カスケードされた分割錐台のオーバーラップ。
正確な対数分布を使用することはニア平面に近い分割錐台に対しては難しい。
もっとも近いものは,手動で調整されます。
効率的なカスケードの分割は,カメラのニア平面と垂直画角に非常に敏感です。
垂直画角が大きくなるにつれて,シャドウ錐台の重複部分が増える。
垂直画角が大きくなるにつれて,シーンの見えない部分にシャドウマップの無駄な部分が増える。
ニア平面に近づくにつれて,シャドウ錐台の重複が増える。
限られた深度範囲を持つカットシーンについてよりタイトなカスケードシャドウマップの境界となる。
Light Space vs. View Space Shadow Frustums Alignment(ライト空間 対 ビュー空間シャドウ錐台整列)
ビュー空間で整列
シャドウ空間を使用をより良くする。
錐台の重複がより少ない。
より高いシャドウマップサンプリング密度。
シャドウマップがサンプリング不足の場合はシャドウが安定しない(シャドウエイリアシング - カメラ移動のためちらちら光る)
ライト空間で整列されたシャドウ錐台
錐台の重複が増加するためシャドウマップの使用の効率がより低くなる。
シャドウカスケードキャッシングのためより効率的になる。
シャドウマップのテクセルサイズのスナッピングを使用できるようにする。
カメラが移動する状態でサンプル不足のシャドウマップに対しては安定なシャドウ。
Shadow Aliasing with Cascaded Shadow Maps(カスケードされたシャドウマップを伴うシャドウエイリアシング)
影響要因:
低いシャドウマップのサンプリング密度
深度バッファの精度
カメラに対して相対的な光源の方向
Shadow Aliasing(シャドウエイリアシング)
エイリアシングに打ち勝つための異なるシナリオ
太陽光によるシャドウ:スロープスケールされた深度バイアスを用いて表面を描画する。
点光源シャドウ: 背面レンダリング,インドア環境についてはより良く作用する。
遠い詳細度レベル(LODs)に対する分散シャドウ - シャドウマップへ両面を描画する。
深度バッファの精度問題を克服するために遅延シャドウパスの間,一定の深度バイアスを掛ける。
Current Situation(現在の状況)
今日のゲーム上では大半がサンプリング不足のシャドウが使われている
カスケード分割は効率的ではない。
シャドウマップのテクセルのオブジェクトごとのシャドウのスナッピングのようなトリック。
レベル毎 / カットシーンでは微調整された解決方法。
Main Goals - What We Are Trying to Achieve(主な目標 -達するべきこと)
カスケードシャドウマップの錐台の重複を排除 / 最小化する。
シャドウマップ上の使われていない領域を排除 / 最小化する。
シーンの見えない部分におけるシャドウマップの無駄を最小化する。
非常に高いシャドウマップのサンプリング密度を目標とする - シャドウマップのテクセルをスナッピングすることが不要なトリックを行う。
シーンの範囲すべてに対してシャドウマップのサンプリング密度を一定にするように近づけるのを保証する。
定数に近いシャドウマップ密度を持つことがシャドウのエイリアシング問題を対称するための手助けになる。
Oblique Projection for Cascaded Shadow Maps(カスケードされたシャドウマップに対する斜投影)
平行射影のタイプ。
ターゲットの投影面で3次元の入力から平行レイ(”プロジェクター")に交差している画像を射影します。
プロジェクターは投影面に対して垂直ではない。
プロジェクターは2つの角度にαとλによって定義される。ただしαは線分(x, y, xp, yp)と投影面との間の角度で,λは線分(x, y, xp, yp)と投影面上のx軸との間の角度です。 L = 線分(x, y, xp, yp)の長さです。L1 = L / z
斜投影を使用する
シャドウマップの投影平面として視錐台のクリップ平面を使用する。
投影平面は5つの視錐台平面から選択されます(ファー平面は無関係)
シャドウの射影のために斜投影平面が光源の方向に基づき選択されます。
選択された平面は,最も近い平面として平面の法線とライトの方向間の内積の符号と同じになります。
投影面は対数分布の近似を得るためにセグメントに分割されています。
遠方のセグメントは同じシャドウマップの解像度で,より多くの範囲をカバーしています。
シャドウキャスターのCPUカリングは,斜錐台のまとまりで実行されます。
Shadow Map Parameterization(シャドウマップのパラメータ化)
矩形に対して錐台セグメントを拡張し,長方形のシャドウマップを使用します。
対数分割の許容可能な近似を得るために多くの平面セグメントを必要とします。
無駄なシャドウ空間。
斜投影と共にビューカメラをパースペクティブの歪みを使用します。
仮想ビューカメラはシフトされ引き伸ばされたニア平面を持ちます。
ほとんど無駄のないシャドウ空間。
ちらつきに打ち勝つ十分なシャドウマップサンプリング密度を持つときにうまく使用することができます。
投影面セグメントについては対数分布である。
Oblique Shadow Projection(シャドウ斜投影)
シャドウマップは,適切に視錐台を覆っています。
シャドウマップの小さな部分のみがシーンの見えない範囲上に無駄に使われる。
カスケードの重複はありません。
潜在的に影を受ける範囲は,キャスターが最も適切な平面セグメント上に射影されるので,シャドウサンプリング密度は保証されます。
このアプローチはライト方向に依存しない一定なシャドウマップサンプリング密度に近づくのを保つように設計されています。
シャドウエイリアシングの問題を対処するのに役立ちます。
Implementation Details(実装の詳細)
シャドウマップの描画
各分割された視錐台の平面は独立して処理される。
ジオメトリシェーダは必要な時に平面上のいくつかのセグメント間で三角形を複製します。
適切な面のセグメントはビュー空間におけるZ座標に基づいて選択されます。
Use Cases(ユースケース)
遅延シャドウ描画
結果として,斜めシャドウマップのすべてからのシャドウを適用する。
斜錐台が重ならないようなカスケードされたものとの間の複雑なステンシルは不要である。
グローバルなシャドウマップセグメント / カスケードのインデックスへのテクスチャ配列。
フォワードシャドウ描画
シャドウマップ領域のためのシャドウ付けされた領域に1対1対応するシャドウマップの直接的なインデックス付け。
クラスタ化されたフォワードと遅延シェーディング
シャドウ錐台に対して重複がない。
斜投影でシャドウマップ領域にまとめたものに1対1対応するシャドウマップの直接的なインデックス付け。
Oblique Shadow Projection Features(シャドウ斜投影の特徴)
効率的なテクスチャ空間の使用
より良く対処されたシャドウエイリアシングの問題
保証されたシャドウマップのサンプリング密度に近づくことができる
高解像度なシャドウマップが使われた場合にエイリアシングフリーになる (1-2K, 最適4K)
Summary(まとめ)
遅延シャドウ
カスケードシャドウマップ
ソフトシャドウ近似
ボクセルに基づくエリアライトシャドウ
シャドウ & 透過性
コンタクトシャドウ / スクリーン空間ディレクショナル送るージョン
スクリーン空間自己シャドウイング
カスケードシャドウマップのための斜投影
CrytekのSIGGRAPH 2013のスライドの超雑訳。
Deferred Shadows
Cacaded Shadow Maps
Soft Shadows Approximation
Shadows & Transparency
Contact Shadows / SSDO
Screen Space Self-Shadowing
Volumetric Shadows
Area Light Shadows
Typical Shadows Frame Budgets (典型的なシャドウにかかるフレームに割り当てることができる時間)
典型的なビデオゲームの1フレームあたりの処理コストに割り当てられる時間は33ms(30FPS)
4000 ドローコール(平均的なPC)
~5から7msがシャドウに割り当てることができる時間
シャドウマップのテクスチャプールは10Mb(Xbox360, PS3)
PCはもっと大きくできる。
10 + シャドウをキャストしようとするライトの数。
Deferred Shadows (遅延シャドウ)
太陽光に対するシャドウマスク
シャドウの遮蔽を蓄積するための特別な描画ターゲット。
シャドウマスクは,実際のシェーディングを適用する前に,互いの上で複数のシャドウテクニックを組み合わせます。
VSM(分散シャドウマップ), オブジェクト毎の影, 雲の影
点光源(ポイントライト)のシャドウは,ライトバッファに直接的に描画されます。
Cascaded Shadows Maps (カスケードされたシャドウマップ)
視錐台は,複数のシャドウ錐台にまたがる
ふつうは,距離に基づく分割(distance-based splitting)を用いる
カスケードの分離スキーム
対数的にテクセル密度分布を近似する。
シャドウ錐台は,伝統的にカメラの視錐台を覆うように調整。
シャドウ錐台に対する幾何学的配置はワールド空間に固定する。
もっとカスケードを持つことができる
改善されたテクセル密度は,エイリアシングを低減し,対数分布をよりよく近似するためにより広いシャドウ範囲に対して自己影を向上します。
シャドウマップのテクセルグリッドのために各カスケードはシャドウ錐台のスナップショットを撮ります。
Deferred Shadow Passes (遅延シャドウのパス)
カスケードに対するシャドウパス / 点光源は異なる方法で描画されます。
潜在的にシャドウが落ちるエリアは錐台ボリュームを描画することによってステンシルバッファ上にタグ付けされます。
カスケードへより洗練された分割を持つことができます。
重複領域上では高解像度なテクスチャを持つカスケードを選択します。
シャドウマップの空間をより効率的に使用することができます。
Shadow Cascades Caching (シャドウカスケードのキャッシング)
1フレームでカスケードのすべてが更新されるわけではありません。
いくつかのフレームにわたって更新コストが分散される。
パフォーマンス上の理由。
より多くのカスケードを持つことができる - 良いシャドウマップ密度分布
遠く離れたカスケードは少ない頻度で更新される。
キャッシュされたシャドウマップは更新されませんが,シャドウイングのために使用されます。
メモリを追加することで動的なオブジェクトを扱うことができます。
最後のカスケードはVSMを使用し,シャドウマスクを付加的に伴った状態でブレンドされます。
非常に遠くのオブジェクトから大きな半影を持つことができます。
Point Light Shadows (点光源シャドウ)
我々は常に6つの独立したプロジェクターに無指向性ライト(omni-directional lights)を分割します。
各プロジェクターに対するシャドウマップは,別々にスケーリングされます。
シャドウの投影範囲に基づく。
最終的なスケール値は,対数シャドウマップ密度分布関数の結果であり,その関数はパラメータとして範囲を使用します。
大きなプロジェクターにカスケードを使用する。
スケーリング後の各フレームのシャドウマップすべてをまとめるためのテクスチャアトラス。
テクスチャアトラスはメモリ断片化を避けるために恒久的にアロケートされる。
コンソール上のサイズ:1024 × 1024 (4MB)
シャドウを受け取る領域はステンシルによってタグ付されている。
Per-Object Shadow Maps (オブジェクトごとのシャドウマップ)
カットシーンやゲーム上で非常に大きく詳細なオブジェクトに対して,自己影の詳細度を増加するのに使用する(first person weapon).
専用のオブジェクトに対して別々の高解像度なシャドウマップ。
グローバルやオブジェクトごとのシャドウはmax()フィルタでシャドウマスクにブレンドされます。
グローバルシャドウマップ(CSM, 点光源)で低解像度の自己影を排除するために,非常に大きなオブジェクトごとのシャドウマップバイアス。
オブジェクトは依然としてグローバルな低解像度シャドウをキャストする。
自己シャドウイングのみが高解像度シャドウマップからくる。
First Person Weapon Self-Shadowing
レンダリングとグローバルシャドウマップ生成のための異なるファーストパーソンとサードパーソンモデル。
適切な自己影は分割した各オブジェクトごとのシャドウマップのみで達成することができます。
遅延シャドウイングでの問題
異なる視錐台を使用(近 / 遠平面, FOV).
一般的なケース - "武器"空間からの武器の深度を再射影する必要があります。
FOVの差が大きくない場合 - 単純な深度の再スケーリングで,再射影を近似。
Soft Shadows Approximation (ソフトシャドウ近似)
シャドウ空間上でランダム化された回転でポアッソンPCFタップを使用する。
実行時にカーネルサイズの調整することは,変化する半影でソフトシャドウの近似を良くする。
ソフトシャドウのアイデア: シャドウキャスターへの平均距離の比を推定する。
Percentage-Closer Soft Shadow[Randima05]に類似。
基本アルゴリズム:
ポアッソン分布されたタップはカーネル中からの距離によって事前ソートされています。
初期カーネル半径が最大範囲(=最大 / 最長半影)に一致するように設定。
平均距離比率を推定するために,このカーネルを使用します。
サンプルの量は,平均距離比に比例して低減されます。
タップはソートされているので,カーネル半径に影響を与えます。
最後の影計算に対するサンプルの量を減らすためのみに使用します。
カスケードシャドウマップは,カスケード間の遷移を扱うためにカスタムカーネルスケールの調整が必要になります。
シェーダオプションの計算:コンピュートシェーダの共有メモリへと全てのタップをフェッチし,距離の推定とシャドウ計算に対してそれらを再利用します。
Area Lights Shadowing(エリアライトシャドウイング)
複数解像度均一ボクセルデータ。
非常に大きなボリュームに対する効率的な遮蔽サンプリング
レイのトラバーサルに対する適応解像度。
複数の距離に基づくカスケードはオプション。
動的なサーフェイスボクセル化とダウンサンプリング
"ディレクショナルオクルージョン"値をダウンサンプリング。
適応的ダウンサンプリング
シーンの各フレームの静的な部分の更新を回避します。
ビットマスクの変化を意識しダウンサンプリング(前のフレームのボクセルデータとXOR)
Voxel Data Downsampling (ボクセルデータのダウンサンプリング)
ディレクショナルオクルージョンのコンセプト
ライトオクルージョンをダウンサンプリング
双方向; 3つのコンポーネント
Area Light Shadows(エリアライトのシャドウ)
グループ化されたレイの近似。
異なるボクセル化されたレベルをサンプルする。
レイに沿ってボクセルレベルを調整。
ディレクショナルオクルージョンギャザリング。
サンプリングエラー
コーントレーシングでワールド空間アンビエントオクルージョン。
8つの均一な分散されたコーンで近似。
Shadows & Transparency(シャドウと透過性)
アルファブレンドされたシャドウレシーバーについて
シャドウを適用するためのフォワードパス
透過シャドウキャスター(e.g. 髪,煙)について,我々はキャスターのアルファ値を蓄積します。
8ビットレンダーターゲット上に保存する。
透過マップの生成:
バック射影/漏れを避けるために正規の不透明なシャドウマップからの深度バッファを用いて深度テストを行う。
透過アルファは "不透明な"シャドウではないオブジェクトのみに対して蓄積されます。
透過アルファを蓄積するためのアルファブレンドされたシャドウ生成パス(後ろから前へとソートされる).
カスケードシャドウマップの場合においては,各カスケードに対して透過マップを生成する。
シャドウマップと透過マップからのシャドウ項はmax()演算で,遅延シャドウパスの間,両方とも結合します。
Contact Shadows(密着性シャドウ)
密着性シャドウ/スクリーン空間ディレクショナルオクルージョン
スクリーン空間ベント法線(平均非遮蔽方向)を介して,すべての光源とアンビエントに適用される。
コアアイデアはSSDO[Ritschel 2010]と同じ
計算されたスクリーン空間オクルージョンでライティングを調節する。
やわらかい密着性シャドウを生み出す。
シャドウバイアスの問題を隠すことができる。
SSAOだけよりもかなりの品質を上げる。
ディファードの方法でディレクショナルオクルージョンの情報がアクセス可能。
既存のライティングパイプラインへとよりよく適合する。
各光源に効率的に適用することが可能。
遮蔽情報の生成
SSAOパスの間ベント法線N'の計算と保存。
ベント法線は平均的な非遮蔽方向。
任意の自己遮蔽なし比較的広い半径でクリーンなSSAOを必要とします。
各ライトについて
通常のように N dot L を計算する
N' dot L を計算する
中心深度はフル解像度で,他のすべてのタップはFP16の半解像度の深度です。
クランプされた2つの内積間の差分を遮蔽量に乗算することでライティングを減衰させる。
Screen Space Self-Shadowing(スクリーン空間自己シャドウイング)
単純なトリック / 近似
スクリーン空間のライトベクトルに沿ってレイキャスティングする。
カットシーンのために,影響を受けた深度バッファ範囲を指定します。
レイの長さを追跡することで適切なソフトシャドウイングを計算することができます。
Volumetric Fog Shadows(ボリュームのあるフォグのシャドウ)
TOTH09に基づく: 内部散乱光を蓄積するのではなく,代わりに視線のレイに沿ってシャドウの値を蓄積します。
シャドウ空間でレイキャスティングする。
インタリーブパスは,隣接するピクセルで共有された8x8のグリッド上でビュー方向に沿ってシャドウサンプルを割り当てます。
パフォーマンスのために半解像度の出力ターゲット。
ギャザーパスは,最終的なシャドウの値を計算する。
バイラテラルフィルタティングはゴーストとハローを最小化するために使用されます。
シャドウはアルファに格納し,8ビット深度Rチャンネル上に格納されます。
中心のフル解像度深度と比較するために8タップを使用する。
最大サンプル距離設定(C3レベル上で~150-200m)
雲の影テクスチャは最終的な結果に焼き込まれます。
最終結果は,フォグの高さと放射上の色を変更します。
カスケードされたシャドウマップのレイキャスティング
シャドウ空間上でレイキャスティングを行う。
適応的なレイキャスティング - 近傍の空間でより多くのサンプルをとる
カスケードのための任意のシャドウ錐台
錐台は重なっています。
常に再考のサンプリング密度でカスケードを選ぶ。
シャドウ錐台と現在のレイの交差を保存するためにグローバルなパラメトリック座標を使用します。
カスケード間で再射影する必要はありません。
直接グローバルパラメトリック座標を変更する最適化されたレイクリップ関数。
Cascaded Shadows Maps Split Consideration(カスケードされたシャドウマップ分割の考察)
カスケードされた分割錐台のオーバーラップ。
正確な対数分布を使用することはニア平面に近い分割錐台に対しては難しい。
もっとも近いものは,手動で調整されます。
効率的なカスケードの分割は,カメラのニア平面と垂直画角に非常に敏感です。
垂直画角が大きくなるにつれて,シャドウ錐台の重複部分が増える。
垂直画角が大きくなるにつれて,シーンの見えない部分にシャドウマップの無駄な部分が増える。
ニア平面に近づくにつれて,シャドウ錐台の重複が増える。
限られた深度範囲を持つカットシーンについてよりタイトなカスケードシャドウマップの境界となる。
Light Space vs. View Space Shadow Frustums Alignment(ライト空間 対 ビュー空間シャドウ錐台整列)
ビュー空間で整列
シャドウ空間を使用をより良くする。
錐台の重複がより少ない。
より高いシャドウマップサンプリング密度。
シャドウマップがサンプリング不足の場合はシャドウが安定しない(シャドウエイリアシング - カメラ移動のためちらちら光る)
ライト空間で整列されたシャドウ錐台
錐台の重複が増加するためシャドウマップの使用の効率がより低くなる。
シャドウカスケードキャッシングのためより効率的になる。
シャドウマップのテクセルサイズのスナッピングを使用できるようにする。
カメラが移動する状態でサンプル不足のシャドウマップに対しては安定なシャドウ。
Shadow Aliasing with Cascaded Shadow Maps(カスケードされたシャドウマップを伴うシャドウエイリアシング)
影響要因:
低いシャドウマップのサンプリング密度
深度バッファの精度
カメラに対して相対的な光源の方向
Shadow Aliasing(シャドウエイリアシング)
エイリアシングに打ち勝つための異なるシナリオ
太陽光によるシャドウ:スロープスケールされた深度バイアスを用いて表面を描画する。
点光源シャドウ: 背面レンダリング,インドア環境についてはより良く作用する。
遠い詳細度レベル(LODs)に対する分散シャドウ - シャドウマップへ両面を描画する。
深度バッファの精度問題を克服するために遅延シャドウパスの間,一定の深度バイアスを掛ける。
Current Situation(現在の状況)
今日のゲーム上では大半がサンプリング不足のシャドウが使われている
カスケード分割は効率的ではない。
シャドウマップのテクセルのオブジェクトごとのシャドウのスナッピングのようなトリック。
レベル毎 / カットシーンでは微調整された解決方法。
Main Goals - What We Are Trying to Achieve(主な目標 -達するべきこと)
カスケードシャドウマップの錐台の重複を排除 / 最小化する。
シャドウマップ上の使われていない領域を排除 / 最小化する。
シーンの見えない部分におけるシャドウマップの無駄を最小化する。
非常に高いシャドウマップのサンプリング密度を目標とする - シャドウマップのテクセルをスナッピングすることが不要なトリックを行う。
シーンの範囲すべてに対してシャドウマップのサンプリング密度を一定にするように近づけるのを保証する。
定数に近いシャドウマップ密度を持つことがシャドウのエイリアシング問題を対称するための手助けになる。
Oblique Projection for Cascaded Shadow Maps(カスケードされたシャドウマップに対する斜投影)
平行射影のタイプ。
ターゲットの投影面で3次元の入力から平行レイ(”プロジェクター")に交差している画像を射影します。
プロジェクターは投影面に対して垂直ではない。
プロジェクターは2つの角度にαとλによって定義される。ただしαは線分(x, y, xp, yp)と投影面との間の角度で,λは線分(x, y, xp, yp)と投影面上のx軸との間の角度です。 L = 線分(x, y, xp, yp)の長さです。L1 = L / z
斜投影を使用する
シャドウマップの投影平面として視錐台のクリップ平面を使用する。
投影平面は5つの視錐台平面から選択されます(ファー平面は無関係)
シャドウの射影のために斜投影平面が光源の方向に基づき選択されます。
選択された平面は,最も近い平面として平面の法線とライトの方向間の内積の符号と同じになります。
投影面は対数分布の近似を得るためにセグメントに分割されています。
遠方のセグメントは同じシャドウマップの解像度で,より多くの範囲をカバーしています。
シャドウキャスターのCPUカリングは,斜錐台のまとまりで実行されます。
Shadow Map Parameterization(シャドウマップのパラメータ化)
矩形に対して錐台セグメントを拡張し,長方形のシャドウマップを使用します。
対数分割の許容可能な近似を得るために多くの平面セグメントを必要とします。
無駄なシャドウ空間。
斜投影と共にビューカメラをパースペクティブの歪みを使用します。
仮想ビューカメラはシフトされ引き伸ばされたニア平面を持ちます。
ほとんど無駄のないシャドウ空間。
ちらつきに打ち勝つ十分なシャドウマップサンプリング密度を持つときにうまく使用することができます。
投影面セグメントについては対数分布である。
Oblique Shadow Projection(シャドウ斜投影)
シャドウマップは,適切に視錐台を覆っています。
シャドウマップの小さな部分のみがシーンの見えない範囲上に無駄に使われる。
カスケードの重複はありません。
潜在的に影を受ける範囲は,キャスターが最も適切な平面セグメント上に射影されるので,シャドウサンプリング密度は保証されます。
このアプローチはライト方向に依存しない一定なシャドウマップサンプリング密度に近づくのを保つように設計されています。
シャドウエイリアシングの問題を対処するのに役立ちます。
Implementation Details(実装の詳細)
シャドウマップの描画
各分割された視錐台の平面は独立して処理される。
ジオメトリシェーダは必要な時に平面上のいくつかのセグメント間で三角形を複製します。
適切な面のセグメントはビュー空間におけるZ座標に基づいて選択されます。
Use Cases(ユースケース)
遅延シャドウ描画
結果として,斜めシャドウマップのすべてからのシャドウを適用する。
斜錐台が重ならないようなカスケードされたものとの間の複雑なステンシルは不要である。
グローバルなシャドウマップセグメント / カスケードのインデックスへのテクスチャ配列。
フォワードシャドウ描画
シャドウマップ領域のためのシャドウ付けされた領域に1対1対応するシャドウマップの直接的なインデックス付け。
クラスタ化されたフォワードと遅延シェーディング
シャドウ錐台に対して重複がない。
斜投影でシャドウマップ領域にまとめたものに1対1対応するシャドウマップの直接的なインデックス付け。
Oblique Shadow Projection Features(シャドウ斜投影の特徴)
効率的なテクスチャ空間の使用
より良く対処されたシャドウエイリアシングの問題
保証されたシャドウマップのサンプリング密度に近づくことができる
高解像度なシャドウマップが使われた場合にエイリアシングフリーになる (1-2K, 最適4K)
Summary(まとめ)
遅延シャドウ
カスケードシャドウマップ
ソフトシャドウ近似
ボクセルに基づくエリアライトシャドウ
シャドウ & 透過性
コンタクトシャドウ / スクリーン空間ディレクショナル送るージョン
スクリーン空間自己シャドウイング
カスケードシャドウマップのための斜投影
リファクタリング。
過去のプログラムのリファクタリングを開始しました。
Githubの方に順次アップしていっています。
ホームページの方にも上げようかと思ったのですが,
今さら感がありますし,今あげるなら現在のOpenGL 4系に合わせるべきだと思うのです。
…となると結構な数のサンプルがありますし,すべてのプログラムを修正してすべての記事を直すのは,かなり時間がかかりますし,そもそもそんな時間取れません。
そんなわけで,現在のホームページの方にはアップロードしません。
また以前のホームページの方にもアップロードしません。
…というか諸事情で以前のホームページのサーバーにアクセスできなくなってしまったんですね。
変えたくても変えられないんです、実は。
最近,分散シャドウマップのサンプルのバグ報告をして頂いたんですね。
で,アップロードしてほしいと言われたのですが,その時に「あ、アクセスできないじゃん」って気づいたんですよね~。
私ったらうっかりさん。
分散シャドウマップのサンプルよく見てみたら,線形深度の計算も頂点シェーダでやっていて「あ、これだめだよね」と。ラスタライズ後の位置座標全く使っていないから,シャドウマップに書き込まれた深度値がポリゴン単位になっているので,深度判定でバグっている感じがします。
他にもフォーマット違うよ~って言われてみてみたら,整数フォーマット使っていて,昔はずいぶん無駄なことをしていたなぁーと思い,ちょっと反省しました。
そういうへぼいコードを見ていて,そういうのがわかるようになって少しは成長したのかなぁーと思う今日この頃です。
Githubの方に順次アップしていっています。
ホームページの方にも上げようかと思ったのですが,
今さら感がありますし,今あげるなら現在のOpenGL 4系に合わせるべきだと思うのです。
…となると結構な数のサンプルがありますし,すべてのプログラムを修正してすべての記事を直すのは,かなり時間がかかりますし,そもそもそんな時間取れません。
そんなわけで,現在のホームページの方にはアップロードしません。
また以前のホームページの方にもアップロードしません。
…というか諸事情で以前のホームページのサーバーにアクセスできなくなってしまったんですね。
変えたくても変えられないんです、実は。
最近,分散シャドウマップのサンプルのバグ報告をして頂いたんですね。
で,アップロードしてほしいと言われたのですが,その時に「あ、アクセスできないじゃん」って気づいたんですよね~。
私ったらうっかりさん。
分散シャドウマップのサンプルよく見てみたら,線形深度の計算も頂点シェーダでやっていて「あ、これだめだよね」と。ラスタライズ後の位置座標全く使っていないから,シャドウマップに書き込まれた深度値がポリゴン単位になっているので,深度判定でバグっている感じがします。
他にもフォーマット違うよ~って言われてみてみたら,整数フォーマット使っていて,昔はずいぶん無駄なことをしていたなぁーと思い,ちょっと反省しました。
そういうへぼいコードを見ていて,そういうのがわかるようになって少しは成長したのかなぁーと思う今日この頃です。
教えてもらった。
どもこんにちわ。
Pocolです。
いよいよPS4もうすぐ発売ですね~。
すごくワクワクしています。
そういえば先日会社の先輩たちと蔵王にスノボにいってきまして,
新幹線で行ってきたのですが,車内で雑談している際にレイトレの話になりまして…
『そういえばAVXとか使っているんですか?』と聞かれまして,
「え?それ美味しいんですか?」と言ってしまいました。
調べてみたら,Adavanced Vector Extensionの略で, 通常SSE2とかだとfloa4つを一気に演算してくれると思うのですが,
こやつはfloat8個を一気に演算してくれるのです!
「すげぇ~!!」と車内で一人テンションあがっていました。
早速スノボの帰りに新幹線内でAVXを使って交差判定やらを組み始めました。
そもそもQBVH用にSIMDで組んでいたので,交差判定の実装等は東京駅に着くまでに大体完了しました。
で,実際に交差判定の時間を計ってみたら思ったとおりに半分の時間になりました。
AVX使っていない人はおススメです。
Pocolです。
いよいよPS4もうすぐ発売ですね~。
すごくワクワクしています。
そういえば先日会社の先輩たちと蔵王にスノボにいってきまして,
新幹線で行ってきたのですが,車内で雑談している際にレイトレの話になりまして…
『そういえばAVXとか使っているんですか?』と聞かれまして,
「え?それ美味しいんですか?」と言ってしまいました。
調べてみたら,Adavanced Vector Extensionの略で, 通常SSE2とかだとfloa4つを一気に演算してくれると思うのですが,
こやつはfloat8個を一気に演算してくれるのです!
「すげぇ~!!」と車内で一人テンションあがっていました。
早速スノボの帰りに新幹線内でAVXを使って交差判定やらを組み始めました。
そもそもQBVH用にSIMDで組んでいたので,交差判定の実装等は東京駅に着くまでに大体完了しました。
で,実際に交差判定の時間を計ってみたら思ったとおりに半分の時間になりました。
AVX使っていない人はおススメです。
高速化してみた。
以前に実装したReal-Time Local Reflectionですが,綺麗に見せるためレイの進めるステップ数を最大256回にしていたのですが,テクスチャフェッチの回数も最大256回になるのでパフォーマンスが落ちまくって使い物にならないので,少し手を加えて16ステップで済むようにしてみました。70~80 FPSで動いていたものが300~400 FPS程度でるようになりました。
その分クオリティは落ちていますが… まぁ反射ないよりかはマシですかね。

その分クオリティは落ちていますが… まぁ反射ないよりかはマシですかね。

賞味期限。
最近,ネタを仕入れたので来年まで賞味期限切れしないようであれば,
CEDEC用のネタが出来上がるかも知れないっす。
ここの所オオカミ少年化しているので,来年こそは!…と思う今日この頃です。
CEDEC用のネタが出来上がるかも知れないっす。
ここの所オオカミ少年化しているので,来年こそは!…と思う今日この頃です。
Mantle APIまだ?
AMDが発表したMantle APIを触れることを心待ちにしているのですが,一般ユーザーが使える日はまだまだ先ですか?
PSL1GHTのように直接コマンドバッファをいじれるAPIが早く欲しいです。
NDAとか無しで早く使えるようにしてくれ!…と毎日思うばかりです。
Mantleがあればコンソールは事足りるから十分なような気がします。
(※ちなみに,ここで言うコンソールはPS4とXBoxOneですからね!!)
あとは願うのはNVIDIAがMantleライクな変なAPIを出さないことです。
Cg ToolkitでさえUser Guideとかドキュメントまともに更新できていないんだから絶対に出すなよ?
…と個人的には思います。
Mantleの今後の動向には要チェックですね!!!
あぁ早く使いたい。
PSL1GHTのように直接コマンドバッファをいじれるAPIが早く欲しいです。
NDAとか無しで早く使えるようにしてくれ!…と毎日思うばかりです。
Mantleがあればコンソールは事足りるから十分なような気がします。
(※ちなみに,ここで言うコンソールはPS4とXBoxOneですからね!!)
あとは願うのはNVIDIAがMantleライクな変なAPIを出さないことです。
Cg ToolkitでさえUser Guideとかドキュメントまともに更新できていないんだから絶対に出すなよ?
…と個人的には思います。
Mantleの今後の動向には要チェックですね!!!
あぁ早く使いたい。
12月から活動再開します。
12月の第1週目までは忙しいので,第2周目ぐらいからぼちぼち活動を再開します。
Real-Time Local Reflectionを実装してみた。
Real-Time Local Reflectionを実装してみました。
とりあえず現時点での実装は,完全鏡面反射で1次反射のみ…といった限定状態です。

よく見ると,全然正しくありません。
…が,無いよりかはマシに見えます。とりあえず現時点での実装はミップマップ使っておらず,また完全鏡面反射なので,きちんとマテリアルを考えていません。要するにオブジェクトに適用しているBRDFと一致していないです。
さらに言うと,いわゆるグレイジングアングルに近くなると全然綺麗に出ませんし,スクリーンスペースでレイトレしているので,背中が移るような場面だとスクリーンスペースに情報が乗っからないので,背中を映すとかできません。
どせいさんの鼻の下側がきちんと映り込んでいないのもそのせいです。
更に言うと,深度バッファを使ってあたり判定をしているのですが,あたり判定は正しくできるのですが,衝突点の正しい算出が深度バッファを使った判定だと厳密にできません。
だから,ちろっと実装をいじるとセルフヒットしてしまって,本来ありえない場所に色がついてしまったりと色々と厄介です。
地面と設置しているキューブとか円柱とかそういう類のものは綺麗に出そうですが,逆円錐とか変な形のものだとたぶんうまく出ないです。
実際にゲームエンジンとかで組み込んでいる人ってどんな感じで,その辺をうまくごまかしているんでしょうか?
最近RLRと騒いでいるのに,あんまり実装コードが出てこないのはこの辺りのせいかな?…なんて個人的には思っています。
自分のプログラムでも,うまく見るようにかなり小細工を加えています。
本当,ほかの人のコードがどうなっているのか…
「私、気になります!!」
もんしょさんが,今週末にRLRのサンプル上げるとか呟いていたので,後で見てみようっと。
とりあえず現時点での実装は,完全鏡面反射で1次反射のみ…といった限定状態です。

よく見ると,全然正しくありません。
…が,無いよりかはマシに見えます。とりあえず現時点での実装はミップマップ使っておらず,また完全鏡面反射なので,きちんとマテリアルを考えていません。要するにオブジェクトに適用しているBRDFと一致していないです。
さらに言うと,いわゆるグレイジングアングルに近くなると全然綺麗に出ませんし,スクリーンスペースでレイトレしているので,背中が移るような場面だとスクリーンスペースに情報が乗っからないので,背中を映すとかできません。
どせいさんの鼻の下側がきちんと映り込んでいないのもそのせいです。
更に言うと,深度バッファを使ってあたり判定をしているのですが,あたり判定は正しくできるのですが,衝突点の正しい算出が深度バッファを使った判定だと厳密にできません。
だから,ちろっと実装をいじるとセルフヒットしてしまって,本来ありえない場所に色がついてしまったりと色々と厄介です。
地面と設置しているキューブとか円柱とかそういう類のものは綺麗に出そうですが,逆円錐とか変な形のものだとたぶんうまく出ないです。
実際にゲームエンジンとかで組み込んでいる人ってどんな感じで,その辺をうまくごまかしているんでしょうか?
最近RLRと騒いでいるのに,あんまり実装コードが出てこないのはこの辺りのせいかな?…なんて個人的には思っています。
自分のプログラムでも,うまく見るようにかなり小細工を加えています。
本当,ほかの人のコードがどうなっているのか…
「私、気になります!!」
もんしょさんが,今週末にRLRのサンプル上げるとか呟いていたので,後で見てみようっと。
レイトレイベントに参加してきました。
レイトレ合宿イベントに参加してきました。
レンダラーを書くのは今回初めてです。超レイトレ素人。
…だもんで,頑張って下記のような画像しか作れなかったです。
せめて,メッシュとトーンマッピングは実装したかったのですが,バグに悩まされて結局見送り。
見た目だけでも,すこし整えようと思いテクスチャマッピングだけは対応しました。
まぁ,中身がないので順位は最下位でしたw
他の参加者の方は,フォトンマッピング系を実装していたり,
BVHを工夫されていたりと何かオリジナルさがあってすごくよかったのですが,
自分はそういうものを全く出せなかったので,来年参加する際にはもうちょいまともなプログラムを書きたいです。
フォトンマッピング系実装したいし,トーンマッピングも掛けたいし,メッシュも表示したい,SIMD化もさせたいし,GPUコンピューティングもさせたいし,カメラシミュレーションもちゃんとやりたいですね。

ちなみにソースはGithub(https://github.com/ProjectAsura/Salty/releases/tag/rendering1h_alpha1.1)に挙げていますが,へぼプログラムだし,バグあるからあんまり参考にされないほうがよろしいです。
…来年頑張ろう。
レンダラーを書くのは今回初めてです。超レイトレ素人。
…だもんで,頑張って下記のような画像しか作れなかったです。
せめて,メッシュとトーンマッピングは実装したかったのですが,バグに悩まされて結局見送り。
見た目だけでも,すこし整えようと思いテクスチャマッピングだけは対応しました。
まぁ,中身がないので順位は最下位でしたw
他の参加者の方は,フォトンマッピング系を実装していたり,
BVHを工夫されていたりと何かオリジナルさがあってすごくよかったのですが,
自分はそういうものを全く出せなかったので,来年参加する際にはもうちょいまともなプログラムを書きたいです。
フォトンマッピング系実装したいし,トーンマッピングも掛けたいし,メッシュも表示したい,SIMD化もさせたいし,GPUコンピューティングもさせたいし,カメラシミュレーションもちゃんとやりたいですね。

ちなみにソースはGithub(https://github.com/ProjectAsura/Salty/releases/tag/rendering1h_alpha1.1)に挙げていますが,へぼプログラムだし,バグあるからあんまり参考にされないほうがよろしいです。
…来年頑張ろう。