Skip to content
Go back

Rendering of Call of Duty: Infinite Warfare

· Updated:

url

拙訳

Voxel Tree

  • ワールドスペース八分木。
  • 遮蔽を含めて事前計算する。
    • ライトは影付けされ、影響のある範囲だけが含まれる。
  • 事前計算/キャッシュされた錐台外の3Dルックアップが簡単にできる。
    • 動的反射プロブのライト、動的ライトマップされたパーティクル、四面体GIライトグリッドで使われる。
  • 高価な走査。
    • 階層の走査の必要性、複数のキャッシュミス、間接読み出し。
    • 非同期コンピュートが良い候補となる。
  • 重大な事前計算時間。
  • リーフのペイロード。
    • ライト。
    • ライトグリッドキャッシングのためのルート。
    • 可視性。
  • 色は各ピクセルにヒットするライトの量を表す。
  • 各ボクセルは事前にカリングされたライトを格納する。

Frustum Space

  • タイルベースビットマスク。
    • 8x8のピクセルサイズ。
    • 不透明ジオメトリで使われる。
  • クラスタベースビットマスク。
    • ボリューム換算で4x4x4のカーネルと一致するサイズ。
      • 160/4 * 90/4 * 128/4 = 40x25x32 @ 1080p
    • 不透明ジオメトリとボリューメトリックスで使われる。
  • アイテムはビット列でインデックス付けされる。
    • ライト。
    • 反射プロブ。
    • 密度ボリューム。
    • デカール[Sousa and Geffroy 2016Sousa, T. and Geffroy, J. 2016. The Devil is in the Details: idTech 666. Advances in Real-Time Rendering in Games course. ACM SIGGRAPH. https://advances.realtimerendering.com/s2016/.]

Mesh Rendering

Smodels / Xmodels

  • 静的モデルと動的モデル。
  • 標準のゲームエンジンメッシュと似ている。
  • 小道具props、キャラクター、車両、武器、などで使われる。

BSP

  • 放射状ブラシベースのジオメトリ。
  • 大雑把に示されたblocking outレベル。
  • 地形terrain
  • 環境の静的な構造部分。
  • 個々のマテリアルを持つ複数のブラシは最適化されたサブメッシュとサブシェーダに一緒にマージされる。
  • 高いパフォーマンスで世界のユニークなディティール付けを可能にする。
  • テッセレーションとディスプレースメントマッピングをサポートする。
  • ベースBSPは物理やAIのレイキャストにふさわしい。
  • 単純なジオメトリで、イテレーションが簡単。

Tessellation & Displacement

  • ベースBSPは適応型テッセレーションとディスプレースメントマッピングを適用できる。
  • 適応型テッセレーションはディスプレースメントデルタ、カメラへの距離、カメラへのパッチ角度に基づく。
  • 生成されたサブパッチはGPUで錐台、オクルージョン、背面のかリングを通る。
  • テッセレーションとディスプレースメントは適度な適応的パフォーマンスヒットで大きなビジュアル的インパクトを作る。

Shadow Map Cache

ESM Shadow Map Cache : Motivation

  • テッセレーションしたジオメトリはシャドウマップレンダリングでは高価になる。
  • 大多数のライトは動かないstationary
  • 多くのライト。
    • 視錐台の中に256個以下。
  • 多くのシャドウ。
    • 視錐台の中に128個以下。

ESM Shadow Map Cache

  • PCFはF+では高価すぎる(VGPRプレッシャー)。
  • 静的で高品質な影付けされたライトキャッシング を重要視。
  • 指数シャドウマップ
    • 512x512の16ビットUNORM。
    • 1024x1024のシャドウマップからダウンサンプリングした。
    • 3x3のガウスフィルタをかける。
      • フィルタリングに対するアーティスト的な制御。
    • 一度だけ事前にフィルタリングして、キャッシュする。

Caching algorithm

  • ビューごとにシャドウマップを要求する。
    • カリングテストを通過したビューで見えているすべてのシャドウマップを得る。
  • 更新の必要がないシャドウマップの古くなったStaleキャッシュをチェックする。
    • ライトがStaleキャッシュにあるresidentか?
      • 最後のフレームでライトが移動したか?
      • 最後のフレームでライト錐台内で何かが移動したか?
      • 更新が強制されたか?
  • 4から8つの最も重要なシャドウマップを選び出す。
    • 優先順位でソートする。
      • アーティスト駆動の優先順位(プレイヤーのフラッシュライトなど)。
      • 距離、射影サイズ、強度。
  • 選んだライトごとに、
  • シャドウマップのStaleキャッシュをチェックする --- Staticキャッシュは実際には静的ジオメトリのみを含むD16のシャドウマップを持つ。
    • ライトがStaticキャッシュにキャッシュされている場合、
      • Staticキャッシュから静的シャドウマップをActiveキャッシュにコピーする。
    • ライトがStaticキャッシュにキャッシュされていない場合、
      • 静的ジオメトリをActiveキャッシュにレンダリングする。
      • 静的ジオメトリのシャドウマップをStaticキャッシュにコピーする。
  • 動的ジオメトリをActiveシャドウマップにレンダリングする --- Activeキャッシュは4から8つのD16シャドウマップである。
  • 技術的には、必要なのは1つだけだが、実際のシャドウマップのレンダリングでは、シャドウキャッシュシステムから複数の非同期コンピュートジョブがオーバーラップする(つまり、コピーして、ESMフィルタリングして、ダウンサンプリングして、クリアする)。そして、シャドウマップ0のCSジョブはシャドウマップ1のレンダリングとオーバーラップさせる。
  • ActiveシャドウマップをStaleキャッシュにコピーしてESM処理する。

ESM Shadow Map Cache : Performance

  • キャッシュのコピーやESMジョブは非同期コンピュートを使う。
  • ‘次’のシャドウマップ生成処理とオーバーラップする。
  • 平均のリアルコスト:レンダリングを除いたシャドウマップあたり0.1ms以下。
  • Forward+ではサンプリングコストが下がる。
    • ALUは完全に償却される。
    • レジスタ(VGPR)インパクトがない。

Deferred Sun Shadows

  • 以下では高品質なシャドウが必要である。
    • シネマティックのキャラクター。
    • ビューモデル。
  • 複数の高解像度のオブジェクトスペースのシャドウマップが必要である。
    • 標準のシャドウマップキャッシュではプレッシャーが強すぎる。
      • 多くのアクティブスロットが必要である。
  • スクリーンスペースシャドウ。
    • 光源の方向にデプスバッファレイトレースを行う。
  • 太陽のみのディファードパス。
    • ビューモデルに最適化される(深度境界/ステンシルテスト)。
    • シーン全体で実行すると、うまく働く。

SS Shadows

  • F+に統合される。
    • ピクセルごとの一番強い光源を格納する。
      • キーライトとしてアーティストにより設定されたり、最大値として実行時計算から導いたりする。
    • キーライト方向に単一のトレースを行う。

Particle Lighting

Particle Lighting with lightmaps

  • 各quadは自動的に1x1から32x32のライトマップタイルに割り当てる。
    • 解像度は射影されるスクリーンスペースのquadサイズに依存する。
  • 各テクセルごとに、
    • 各サンプリングポイントの位置を格納する。
    • CSはアンビエントの寄与のライトグリッドをサンプリングする。
    • CS主体のライティング。
      • ワールドスペースのボクセルツリー。
      • サンプリングポイントは錐台境界の外にすることができる。
      • RGB SH1として変換して格納する。

Deferred Lightmap

  • 512x512のRGBのFP11_11_10
    • 全方向ライティング。
    • 単純なパーティクル。
  • 3つの512x512のRGBAのFP16_16_16_16
    • ディレクショナルライティング。
    • RGB x SH1として格納される(RGBAに係数4つが格納される)。
    • 法線マップを持つ複雑なパーティクル。
  • 法線マッピングされたパーティクルはF+を通したスペキュラ反射をサポートする。
  • 以下をサポートする。
    • VFX impact marks
    • デカールメッシュ。

Simple Lit Particles

  • 全方向ライティングを伴う単純に照らされたパーティクル。
  • 複雑なラティングシナリオ。
    • 明るい天球ライティングと反対の色調を持つ強い太陽光。
  • 合わさって、平坦なレンダリングになる。

Normal Mapped SH Lit Particles + Extinction Transmittance Map for Sun

[Gautron et al. 2011Gautron, P., Delalandre, C. and Marvie, J.-E. 2011. Extinction transmittance maps. SIGGRAPH asia 2011 sketches. 10.1145/2077378.2077387. http://gautron.pascal.free.fr/publications/sasia2011/extinctionTransmittanceMaps.pdf.]

  • SHディファードライトマップは、法線マッピングされたパーティクルを用いており、正確にライティング方向と奥行き感を与える色を分けている。
  • これは太陽でのみ使われるExtinction Shadow Mapによってさらに改善される。

No Scattering

  • スクリーン上のパーティクルとアンダーサンプリングの結果によるライトマップのテクセルサイズとの間の相対的なサイズの違いのためにブロックのような拡大アーティファクトが発生する可能性がある。
  • ライトのマルチスキャッタリングが失われている(ライトマップは主要なスキャッタリングのみを格納する)。
  • これらの問題はライトマップスキャッタリングパスで改善できる。

Scattering

  • ライトマップライティングスキャッタリング。
    • 各タイルごとに、
      • CSスキャッタリングぱす。
        • スキャッタリングをシミュレートするためにブラ―をかける。
        • アンチエイリアシングのための逆トーンマッピング。
    • CSでパッキングして、最も高い占有率に対するタイルサイズでソートする。
  • 加えて、(または、スキャッタリングの代わりに、)パーティクルをレンダリングしている間に高価なキュービックフィルタリングを実装する。
    • パーティクルのレンダリングごとに最大10%遅くなる。
    • 出荷しなかった。

Particle Lighting : Performance

  • すべての処理は非同期コンピュートを利用している。
    • ほとんどの場合、非透明ジオメトリパス上で償却される。
RGB SH1 512 CS Job時間[ms] @ PS4
ライティング0.1〜0.7
スキャッタリング0.1

Multi-Res Rendering

  • 密なVFXは著しいオーバードローをもたらす --- 最適化する必要がある。
  • VFXチームはソートを’そのままas is’にしておくことを望んでいた。
    • クラシックな低解像度レンダリングはレンダリング中に注入されるマージパスを必要とする。
    • ソート順が変化する/複雑化する。
  • MSAAベースのマルチ解像度レンダリングパイプライン。
    • レンダリングを’そのまま’にしておくことを可能にする。
    • 個別のエフェクト/マテリアルに’低解像度レンダリング’のためのタグを付けることができる。
    • 現時点ではコンソールのみ(MSAA拡張のIHVサポート待ち)。

Full Res : 5ms VFX

Multi Res : 2.8ms VFX

Low Res : 2.4ms VFX

Multi-Res Algorithm

  • 4xMSAAのハーフ解像度のバッファとしてエイリアスされたフレームバッファにレンダリングする。
  • 事前乗算アルファレンダリングを使う。
  • 使うMSAAレベルを描画ごとに決める。
    • 1サンプル => フル解像度の深度テストを伴うハーフ解像度レンダリング。
    • 4サンプル => フル解像度レンダリング。
  • PSは正しい再構築手法をえらぶためにFMask[Drobot 2015Drobot, M. 2015. Hybrid Reconstruction Anti-Aliasing. GPU Pro 6. https://michaldrobot.com/publications/.]を読み出す。
    • すべてのサブサンプルを読み出す。
      • エッジ/複数サンプルに近い。
    • バイリニアでサンプル0をアップサンプリングする。
      • エッジ/複数サンプルのproximityなし。
  • メインバッファに合成する。
  • GCNのレンダターゲットフォーマットは直接のエイリアシングを妨げる。したがって、実際にはCSでデプスバッファを手動で再書き込みと再swizzleを行う必要がある。
  • このステップは他の深度関連の処理で償却される。

Color Buffer

Color Buffer FMask

  • ジオメトリのエッジが複数サンプルでマークされていることに注目する。
  • 灰 -> 1サンプル。ブレンディングのためにCMaskに触る。
  • 青/緑 -> 2/3サンプル。深度交差のためにラスタライザに渡される。
  • 赤 -> 4サンプル。フル解像度レンダリング、または、すべてのサブサンプルが深度交差ヒット。

Alpha Buffer

Alpha Buffer FMask

  • ジオメトリのエッジが複数サンプルでマークされていることに注目する。
  • 異なるブレンドモードの可能性があるため、色のFMaskとの違いにも注目する。

Dilated Combined Compacted FMask Buffer

  • コンパクト化されたFMASK。
  • カラーのFmask > 0 || アルファのFmask > 0
  • 16ビットバッファにパッキングされる --- ピクセルあたり16個のブール値。

  • FMask/CMask --- 色とアルファで異なることができる。
    • ブレンドモードセットアップとハードウェアセットアップに依存する。
      • アルファブレンド。
      • 加算。
      • 高速ブレンドモード(ハードウェア固有)。

Full Res Glass : 1.3ms

  • プレイヤーのヘルメット、バイザー、車両のフロントガラスwindshieldといった、フル解像度の透明物はとても高価になる可能性がある。

Multi Res Glass : 0.4ms

  • レンダラは透明物と通常のメッシュの解像度を混ぜることができる。
    • 車両のフロントガラス。
    • ガラス。
    • 重大なパフォーマンス改善(1.3ms -> 0.4ms)。
    • 質の劣化 --- 主にガラスの傷のような高周波で詳細が見える。

Multi-Res Issues

  • ‘ポイントサンプルされたビジュアル’になる可能性がある。
    • 低解像度のピクセルは単一の色サンプルとして格納される。
    • ブレンディングはレンダリング中にハードウェアで起こる。
    • 多いサンプルでのブレンディングが必要とするならば、ブレンダーは少ないサンプルを複製する。
  • サンプル0に対してのみ実行した場合、ピクセルごとのシェーディングはエイリアシングを含むことがある。
    • Z-Feather
  • 問題を和らげるためテンポラルディザリングを使う。
    • 色ビット深度color bit-depthの問題に役立つ。

Low Res Effect Seen Through Low Res Grass | Low Res Effect Seen Through High Res Grass

  • ピクセルの失敗ケース:
  • 低解像度の描画をレンダリングする --- サンプル0(火のエフェクト)を書き込む。
  • FMaskが1サンプルにセットされる --- まだバイリニアでアップサンプリングできる。
  • 高解像度の描画をブレンドしてレンダリングする --- サンプル0をソースとして複製して、サンプルごとにブレンドする(火のエフェクトの前のガラス)。
  • FMaskが1サンプル以上にセットされる --- バイリニアでアップサンプリングできない。

Multi-Res Performance

  • 3から3.8倍の低解像度のタグ付けされたマテリアルによるパフォーマンススケーリング。
    • 分散は以下に依存する。
      • レンダターゲットのマイクロタイルのヒット量。
      • スクリーン上でのフル解像度と低解像度のパーティクル間のオーバーラップ。
        • 高速ブレンド/MSAA帯域幅の利点はMRTマイクロタイルが伸長のタグが付けられる == フル解像度レンダリングが発生するとすぐに失われる。
    • 常にピクセル処理が少ない。
  • 0.3から0.4msのアップサンプリング/解決/再構築パス。
    • 分散はすべてのサブサンプルを必要とするマイクロタイルの量に起因する。
  • 燃費mileageはGPUのMSAA効率に依存して変化する。

Multi-Frequency Rendering : R & D

  • 8xMSAAでの実験。
  • 1、2、4、8サンプルが可能。
    • テンポラルスーパーサンプリングを伴う結合conjunctionでサンプルパターンを変化する。
  • OITに基づくテンポラル確率的MSAA。
  • MFRを用いて不透明シーンをレンダリングする。
    • キャラクターといった、高解像度で関心のあるオブジェクトを選び取る。
    • 重要性の低いオブジェクトでサンプルカウントを無作為に変化する。

Reflections & Refractions

  • 反射プロブは一級市民である。
  • 静的にも動的にも統一的な方法ですべてのジオメトリにF+を通して適用される。
  • 箱射影された反射プロブBox Projected Reflection Probs
    • オブジェクトスペースまたはワールドスペースで可能。
      • オブジェクトと一緒に移動と回転する --- 輸送機dropshipの内部。
    • さまざまな優先順位でネストできる。
    • GPUのGGXフィルタで畳み込まれる。
    • XYZブレンドゾーン。
  • 64x128x128のBC6テクスチャのキューブ配列として格納される。
  • ピクセルごとに任意のプロブ数のブレンディングが可能。
  • 反射プロブボリュームごとに定義されるXYZブレンド領域をサポートする。
  • 画像はオーバーラップする反射プロブとその重みを示している。
  • 画像はキューブマップオーバーラップの効果的なカリング後の領域を示している。

Reflection Probes

  • CSのGPUカリング: 分離軸理論Separating Axis Theorem
    • ビューに最大64個のキューブマップ。
    • 32x24x48 x 64ビット。
    • 毎ピクセル: PS内の追加のカリングステップ。
  • コストは非同期コンピュートパイプラインで完全に償却される。
シェーダ時間[ms] @ PS4
32x24x48の平均オープンシーンでの64個の反射プロブのSATカリング0.185

Relightable Reflection Probes

  • ベイク中 --- パックされたキューブマップGバッファを生成する。
    • 組み合わせたアルベド+スペキュラ。
    • 深度。
    • 法線。
    • エミッシブ/ベースアンビエントライティング。
  • 各フレーム
    • 再ライティングが必要なN個の反射プロブを選び出す。
    • 各キューブGバッファでのCSワールドスペースボクセルツリーライティング。
    • 反射プロブをCSフィルタする。[Manson and Sloan 2016Manson, J. and Sloan, P.-P. 2016. Fast filtering of reflection probes. Computer Graphics Forum 35, 4, 119–127. 10.1111/cgf.12955. https://www.ppsloan.org/publications/ggx_filtering.pdf.]
      • SH2のアンビエントライトデータを計算する。
    • 反射キューブマップのBC6h配列へのCS圧縮コピー。
  • 通常の反射プロブとして使われる。
  • マップのひとつは、ライトがひとつもない状態full blackout situationを含めた、任意の動的ライト数の動的順列を必要とした。
  • 反射プロブが隣の部屋への連続的なライト変化にどのように反応するかを見ることができる。
  • 天井での銃に備え付けられたライトの反射とその反射プロブに注目。
  • キャラクターが動くと、リアルタイムで反射が更新したのが分かる。

Relightable Reflection Probes : Performance

  • レンダラは1フレームにプロブを1つ更新する。
  • すべての処理は非同期コンピュートを利用する。
128x128キューブマップでのコンピュート処理時間[ms] @ PS4
再ライティング(動的ライト数に依存)0.1-0.2
全MIPのフィルタリング0.31
全MIPのBC6圧縮0.18

Local directional normalization

[Lazarov 2013Lazarov, D. 2013. Getting More Physical in Call of Duty: Black Ops II. Physically Based Shading in Theory and Practice course. ACM SIGGRAPH. https://blog.selfshadow.com/publications/s2013-shading-course/.]

localNormalization = Luma(GetSHLightgrid(worldPos, reflectionDIr));  // refDir方向でGIのSH2を評価する。
probeNormalization = GetProbeNormalization(probeIdx, sampleDir);  // sampleDir方向でプロブのSH2を評価する。
normalizationFactor = localNormalization / probeNormalization;
result *= normalizationFactor;  // 局所化されたライティングデータに反射を合わせる。
  • ライトグリットSHによる局所的方向正規化。
    • 生成時の各プロブは自身のSH輝度を格納する。
    • フィルタリング処理中に再ライティング可能なプロブはSH輝度を計算する。
    • ライトグリッド輝度SH値はシェーディング中にGIのためにすでにサンプルされたデータからスペキュラ反射の方向で評価される。
    • サンプルされた反射プロブのデータは評価されたライトグリッド値に合うようにスケールされる。

Probe Only

  • エアダクトの金色のフォイルが不均等に照らされていることに注目。コンソールでも同様。

Probes + LG+ Normalization

  • 局所的正規化により、シーンの統合がより改善される。

  • 再ライティング可能な反射プロブはさらなる利点を持つ。
  • すでに各プロブでSH2のアンビエント寄与を計算して正規化で使った。
  • 再ライティング可能な反射プロブはさらなる利点を持つ。
  • 正規化で使ったSH2のアンビエント寄与を再利用する。
  • 動的アンビエントライティングのSH2データでライトグリッドを上書きできる。
    • 粗い動的GI。
    • プロブは移動するオブジェクトや影響のある環境にアタッチできる。
      • 局所化された動的GIを伴う移動する車両の中のプロブを使うことができる。
  • 反射プロブに基づく粗い動的GI。
  • プロブからアンビエント項(ライトマップ/ライトグリッド)へデルタライトSH2を追加する。

粗い動的GIの他の視点。無効化した場合。

粗い動的GIの他の視点。有効化した場合。

Probe Assignment

  • すべての単一のピクセルは少なくとも1つの反射プロブをサンプルする。

Probe Assignment w/ low gloss optimization

  • 低光沢表面に対する反射プロブのLOD最適化。
    • あるしきい値で反射プロブのルックアップをスキップする(ラフネスが0.1より小さい)。
    • ライトグリッドデータからスペキュラを導く(evalSH(reflectionDir))。
    • 遷移しきい値で反射プロブをブレンドする。
    • 最大平均0.5msの節約(キューブマップの低MIPのフィルタリングはキューブのWRAPフィルタリングモードを使うと本当に高価である --- どんなことをしてでも避けたい)。
    • 画像は様々なラフネスの金属マテリアルの大多数を持つシーンを表す。

Screen Space Reflections / Refractions

  • トーンマップの解決に先立ってシーンのMIPチェーンを生成する。
    • MIPをキューブマップと同様の光沢BRDFに合わせるためにBRDFスクリーンスペースフィルタを使う。
    • 前のフレームのMIPチェーンを再投影する。
  • 反射。
    • 箱射影反射プロブからの交差を再利用する。
    • 追加のトレーシングを必要としない。
    • マテリアルの光沢やレイの長さに基づいてMIPを選び取る。
    • 反射は箱投影が一致すればするほど良くなる。
  • すべて混ざって一緒に動作するテクニックを表している。
  • 箱投影された反射プロブ。
  • 再ライティング可能な反射プロブ。
  • 箱投影されたスクリーンスペース反射。
  • 屈折。
    • 深度ピラミッドをサンプルする。
      • 表面のラフネスに基づいてMIPを選び取る。
      • アンダーサンプリングを隠すためにジッタリング/ディザリングしたサンプリングを用いる。
    • 深度のヒットポイントへのレイの長さにより2Dでレイを射影する。
    • レイの長さとマテリアルの光沢に基づくシーンMIPを選び取る。
    • 2つの屈折を解決する:
      • ビューモデルの不透明、シーンの不透明。
  • くもりガラスからプラスチックのカーテンまでの範囲の複数の表面で使われる。
  • 武器アーティストとユーザは、スクリーンスペースの光沢反射を用いた半透明部品を通して見える内部武器パーツの動作を見ることを愛している。

Screen Space Ref/Raf : Performance

シェーダ時間[ms] @ PS4 @ 1080p
シーンMIP生成0.25
フルシーンSS反射表面+0.3
フルシーンSS屈折表面+0.5
  • 完全なトレースによる手法と比べてとても安価である。

Volumetric Renderer

  • ボリューメトリクスはCoD:IWのルックの重要な部分であった。これなしでは出荷できなかっただろうし、品質設定として使うこともできなかっただろう。

Base Scene

Ambient Lightgrid + Volumetrics

  • 静的ライティングとGIはライトグリッドを再サンプルする。

Primary Lights + Ambient Lightgrid + Volumetrics

  • すべてのライトタイプをサポートする。
    • 静的/アンビエントライト。
      • ライトグリッドをサンプルする。
    • 動的ライト。
      • シーンレンダリングの一元的なコード経路を使って評価する。
  • 安定化のためのテンポラルリプロジェクション。
    • 2倍のメモリと帯域幅の消費。

Density Volumes with High Irradiance

  • アーティストは局所化された密度(フォグ)ボリュームを手動で配置できる。
  • 各密度ボリュームは以下を持つ。
    • ワールドスペースのバウンディングボックス
    • ベースとなる密度
    • 照度
  • スクリーンショットは高照度の密度ボリュームのレンダリングを示す。

Density Volumes and sun interaction

  • マップにフォグを’局所化’するために使われる。
    • グローバルのフォグ設定に影響を与えないので、しばしばインテリアに配置される。
  • スクリーンショットは様々な密度の太陽に照らされる密度ボリュームを示す。
  • 密度は最大4つの軸に平行な射影テクスチャでマスクすることができる。
  • UVスクロールでアニメーションする(膝高さフォグをアニメーションさせる)。
  • スクリーンショットはさまざまな密度ボリュームを生成するために使われる複数のテクスチャを示す。

Clustered Density Volumes

  • クラスタリングのCS処理。
    • 4x4x4のメインCSカーネルにマッチするクラスタ。
    • 錐台内で密度ボリュームをインデックスする最大256ビット。
  • スクリーンショットは密度ボリュームのクラスタ化した視点を示す。

Volumetrics Only

  • ボリューメトリックレンダリングにより低周波なビジュアルが提供される。

Particles Only

  • 照らされるパーティクルにより高周波なビジュアルが提供される。

Combined

  • ブレンディングはボリューメトリクスの3D特徴のためにシームレスである。
  • 不透明/透明は統合されたin-scatter光と統合されたextinctionを伴って3Dテクスチャを単にサンプルする。

Initial Implementation

  • 複数の順次CS処理。
    • 密度の注入。
      • スカラ化で最適化されたCS : 4x4x4スレッドカーネルで実行する。
        • クラスタ化した密度ボリュームバッファから単一のフロクセルサイズを一致させる。
      • 書き込む(密度バッファ)。
    • ライティングパス。
      • スカラ化で最適化されたCS : (4x4x4スレッドカーネル)。
        • クラスタ化されたライトバッファから単一のフロクセルサイズを一致させる。
      • 読み込む(密度バッファ) / 書き込む(In-scatterバッファ / Extinctionバッファ)。
    • 積分パス。
      • Zスライスで反復する(8x8x1スレッドカーネル)。
      • スキャッタリングとextinctionを足し合わせる。
      • 読み込む(In-scatterバッファ / Extinctionバッファ) / 書き込む(統合したIn-scatter / 統合したExtinctionバッファ)。

Volumetric Renderer : Initial Implementation

  • 112x90x128
    • 11_11_10F --- (5150KB) | In-scatterと積分バッファ。
    • 16F --- (2580KB) | 密度とExtinctionバッファ。
  • 各パスは帯域幅/レイテンシー限界であることを示す。
CS処理コンスタントな読み書きの帯域幅実行時間VGPR最適なカーネル
密度注入5150KB~0.4ms364x4x4
ライティングパス10310KB~1.1ms484x4x4
積分パス15460KB~0.5ms428x8x1
総計30920KB2.0ms (ALUのみだと1.2ms)MAX(48)
  • 各パスは帯域幅/レイテンシー限界であることを示す。
    • 3Dテクスチャの読み書きは高レイテンシーである。
    • CS処理の読み書きパターンを一致させるためにタイルモードを選び取る。
      • TILE_MODE_1D_THIN -> スライスごとの読み書き(8x8x1)
      • TILE_MODE_1D_THICK -> 3Dブロックの読み書き(4x4x4)
  • 帯域幅束縛。
    • より広いVGPRで動作する。
      • すでに高い占有率。
    • レイテンシー束縛。
      • より多くのALUで補う。
    • 冗長なメモリ転送を取り除く。
  • 実験。
    • すべてのパスを48個のVGPRでキャップする。
      • パフォーマンスは変化しなかった。
      • 依然としてレイテンシー束縛。
    • 64個のVGPR(4 occupancy)を強制すると、帯域幅により20%のパフォーマンスロスが発生する。
    • 最適な占有率である。

Optimized Implementation

  • すべてのパスをマージする。
    • 各パスは’コードブロック’として存在する。
      • 知られたVGPRプレッシャーやサイクル。
    • すべての入力メモリ読み込みは帯域幅に最適化される。
    • 書き込むだけ。
      • In-scatteringの積分。
      • Extinctionの積分。
    • スカラ化でカーネルサイズを一致させる必要がある。
    • 4x4x4の3Dクラスタで動くためにすべてのブロックを切り替える。
      • TILE_MODE_1D_THICK
      • キャッシュ中で、グループ化したテクスチャはロードとストアを行う。
    • 積分CSは4x4x4のグループで処理するために新しいアルゴリズムを必要とした。
      • Inclusive Prefix Sum
      • Lane Swizzleを使って実装した。
// 8x8x1の積分(XYZ順)
float accumulate = 0;
for(i = 0; i < sliceCount; i++) {
    accumulate += ReadData(xy, i);
}
// 4x4x4の積分(ZXY順)
float accumulate = 0;
uint lane = __XB_GetLaneID();
bool laneMask0 = (lane >> 0) & 1;
bool laneMask1 = (lane >> 1) & 1;
for (i = 0; i < sliceCount; i++) {
    data = ReadData(xy, i);
    // 包括的prefix-sum
    sumData = data;
    // スレッド: 4番 = 4番 + 3番、2番 = 2番 + 1番
    addData0 = QuadSwizzle(sumData, 0, 0, 2, 2);
    sumData += laneMask0 ? addData0 : 0.0f;
    // スレッド: 4番 + 2番 = 3番 + 4番 + 1番 + 2番
    addData1 = QuadSwizzle(sumData, 0, 0, 1, 1);
    sumData += laneMask1 ? addData1 : 0.0f;
    accumulate += sumData;
    // 4番スレッドを1、2、3番にばらまく。
    accumulate = GetLastLane(accumulate);
}
// GetLastLaneとQuadSwizzleはLaneSwizzleのマクロである。
// QuadSwizzle(v, n0, n1, n2, n3) --- レジスタVの1番、2番、3番、4番すべてのレーンで、1番をn0に、2番をn1に、3番をn2に、4番をn3のレーンにswizzleする。
// GetLastZLane(v) --- 各カーネルでの最後のレーンを返す(今回の場合は4番)。
#define __LANE_SWIZZLE_MASK(_and, _or, _xor) ((_and & 0x1F) << 0) | ((_or &
0x1F) << 5) | ((_xor & 0x1F) << 10)
#define __QUAD_SWIZZLE_MASK(_o0, _o1, _o2, _o3) ((_o0  & 0x3) << 0) | ((_o1
& 0x3) << 2) | ((_o2  & 0x3) << 4) | ((_o3 & 0x3) << 6) | (0x1 << 15)
#define LaneSwizzle(_x, _and, _or, _xor) __LaneSwizzle(_x, __LANE_SWIZZLE_MASK(_and, _or, _xor))
#define QuadSwizzle(_x, _o0, _o1, _o2, _o3) __LaneSwizzle(_x, __QUAD_SWIZZLE_MASK(_o0, _o1, _o2, _o3))
  • いくつかのシェーダコンパイラはすぐにQuadSwizzle機能を提供する。

Volumetric Renderer : Final Implementation

  • 重要な最適化はこのテクニックが実行可能であることを可能にする。
CS処理固定読み書き帯域幅実行時間コストVGPRカーネル
複数パス30920KB~2.0ms100%MAX(48)混合
マージ7730KB1.2ms60%484x4x4
  • カスケードのサポート。
    • Zスライスは32個のスライスのディープカスケードに分割される。
    • 各カスケードはランタイムで再構成できる線形範囲にマップする。
  • シェーダの並べ替えをサポート。
  • ビュー距離は問題だった。我々のビュー範囲は、細い通路、開けた景色、宇宙空間での戦闘の間を動的にスケールできる。
  • スライスの再構成は実行時に起こることがあり、トランジション、つまり、建物の中からに屋外へ出るときに役立つ。
  • ボリューメトリクスは、太陽のみ、ライトのみ、アンビエントのみ、又はその順列をサンプルできる、異なる最適化されたシェーダを選び取ることができる。これはあるシチュエーションで最大20%のパフォーマンスブーストをもたらす。

Texture Packer

Texture Packer : Motivation

  • ディスクとランタイムメモリは限られている。
  • アーティストに対するアセットパイプラインを複雑にしたくない。
  • 以下は複数のテクスチャサンプルに向いていない。
    • 異方性フィルダリング。
    • フォワード+
  • 増大するテクスチャ。
    • アンチエイジング。

Core Texture Slots

セマンティックスロット圧縮タイプバイト毎ピクセル
ディフューズ(RGB)+アルファ(A)BC1 / BC30.5 / 1.0
スペキュラ(RGB)+光沢(A)BC31.0
法線(XY)BC51.0
遮蔽(A)BC40.5
Reveal(A)BC40.5
総計:4-5テクスチャサンプル4.0-4.5

Additional Texture Slots

セマンティックスロット圧縮タイプバイト毎ピクセル
厚さBC40.5
吸収BC10.5
蛍光BC10.5
輝き(sheen)と布BC10.5
異方性BC71.0
RevealBC40.5

Converter

  • ルールセットに従ってテクスチャをパックする。
  • 表現の間を変換する。
    • Specular ColorモデルからMetalnessモデルへ。
  • 最適なデータ圧縮スキームを選び取る。
    • すなわち、法線マップのパッキング。
  • 統計的なモーメントを計算する(X及びY上の1次、2次モーメント)。
  • さまざまな誤差尺度error metricsを計算する。
    • データにマッチする最適な圧縮スキームを選び取るために誤差尺度を使う。
    • データに関係する尺度を選ぶ --- つまり、法線マップの標準偏差。
  • 色の差分の代わり。
  • 最適なテクスチャ圧縮フォーマットを選ぶ。
    • BC4 / BC1 / BC7

Diffuse

  • SpecularモデルからMetalnessへのコンバータ。
  • SpecularとMetalnessのモデルの間を変換するために範囲のカーブを合わせる。

Specular

  • 誘電体/絶縁体の範囲を保存する。
    • 分離した反射率/F0が必要ない。

Fused Diffuse Specular

Metalness

  • 絶縁体の範囲について仮定する。
    • 0.0-0.1の絶縁体 => 単色のスペキュラ。
    • 0.1以上の誘電体 => 有色のす終えキュラ。
  • シェーダでの伸長処理はALUが5つのみ。
###define INSULATOR_SPEC_RANGE 0.1f
void DeriveMetalnessAndFusedAlbedoSpecMap(float3 albedo, float3 specular, out float3 fusedAlbedoSpec, out float metalness) {
    float nonmetal = (1.0f / 3.0f) * (albedo.r + albedo.g + albedo.b);
    float metal = (1.0f / 3.0f) * (specular.r + specular.g + specular.b);

    nonmetal = saturate(nonmetal, DATA_FORMAT_FP16_MIN_FLT);
    float specE = saturate(metal - INSULATOR_SPEC_RANGE);
    float specI = min(metal, INSULATOR_SPEC_RANGE);
    metalness = specE / (specE + nonmetal);
    fusedAlbedoSpec = (saturate(specular - INSULATOR_SPEC_RANGE)) + albedo;
    metalness = specI + (1.f - INSULATOR_SPEC_RANGE) * metalness;
}
void DeriveAlbedoAndSpec(float3 fusedAlbedoSpec, float metalness, out float3 albedo, out float3 specular) {
    float m = saturate(metalness, - INSULATOR_SPEC_RANGE);
    m = m * (1.0f / (1.0f - INSULATOR_SPEC_RANGE));
    float r0 = min(metalness, INSULATOR_SPEC_RANGE);
    albedo = saturate(1.0f - m) * fusedAlbedoSpec;
    specular = r0 + m * (fusedAlbedoSpec);
}

Data Analysis & Normal Maps

  • 半八面体法線マップ圧縮。[Cigolle et al. 2014Cigolle, Z. H., Donow, S., Evangelakos, D., Mara, M., McGuire, M. and Meyer, Q. 2014. A survey of efficient representations for independent unit vectors. Journal of Computer Graphics Techniques (JCGT) 3, 2, 1–30. https://jcgt.org/published/0003/02/01/.]
  • データ解析。
    • “ほぼ平坦”な法線マップに対して二次のスケーリングを使う。
    • 法線ベクトルのスケーリング値はデータパイプラインで決定される。
      • シェーダで再スケールされる。
// xは[-1, 1]の範囲
float EncodeSNormQuadraticScaling(float x) {
    float sqrtX = sqrt(abs(x));
    return x > 0.0f ? sqrtX : -sqrtX;
}

// xは[-1, 1]の範囲
float DencodeSNormQuadraticScaling(float x) {
    float x2 = x * x;
    return x > 0.0f ? x2 : -x2;
}
  • 0.0の周りの二次スケーリング。
  • ‘平坦な法線’にさらなる精度を与える。

Texture Packer

第1セット(packed_CS)第2セット(packed_NOG)第3セット(packed_ART)
R融合したディフューズとスペキュラ色グロス --- 分散と融合(コンバータにより生成される)アルファ
G融合したディフューズとスペキュラ色法線XReveal
B融合したディフューズとスペキュラ色遮蔽厚さ
AMetalnessマスク(コンバータにより生成される)法線Y

Packed Texture Sets

最終的に変換したテクスチャ圧縮タイプバイト毎ピクセル
CS(第1セット)BC71.0
NOG(第2セット)BC71.0
A/R/T<optional>(第3セット)BC4/BC1/BC70.0-1.0
総計:2-3テクスチャサンプル2.0-3.0
セマンティックスロット圧縮タイプバイト毎ピクセル
総計:4-5テクスチャサンプルBC1-BC54.0-4.5
テクスチャサンプル節約率メモリ節約率
50%-40%50%-33%

Real world results

  • モデルのテクスチャ節約率: 最大30%のメモリ。
  • BSP(静的マップジオメトリ/地形)節約率: 最大15-20%のメモリ。
  • シェーダパフォーマンス改善: 最大5%。
  • 償却される起泡性フィルタリングレベル: 4xAF
  • マップ節約率の例:
    • PHStreets: 11Gb -> 9Gb = ~19%
    • Metropolis: 5Gb -> 4Gb = ~20%
  • 現実世界の結果は理論データからはいくらか異なる。
  • あるケースではアートにより的供されるテクスチャ解像度のミスマッチのためパッキングを使えない。これはパッキングルールの曖昧さ故である。

Bonus Slides

Directional SH Occlusion Lightmap

  • ディレクショナルSH1オクルージョンライトマップ。
    • 高いメモリコスト。
      • 追加の4チャンネルが必要。
      • 2xBC5(質重視)か1xBC7(パフォーマンスとメモリ重視)
    • 各’コーン’は格納されたSH1の係数から計算したベントコーンを表す。
  • 出荷しなかった --- 将来の仕事のための準備はできている。

Probes Only

  • 反射シャドウが欠落した右の木枠に注目。

Probes + Directional SH Occlusion Lightmap

  • 部屋の隅近くの大幅な改善をみせる局所的なシャドウに注目。
// 半球八面体にパックする。
// +Zの半球で正規化された入力を仮定する。[-1, 1]を出力する。
void EncodeHemiOctaNormal(const float3 v, inout float2 encV) {
    // 半球を半八面体へ射影し、XY平面に入れる。
    float rcp_denom = 1.0f / (abs(v[0]) + abs(v[1]) + v[2]);
    float tx = v[0] * rcp_denom;
    float ty = v[1] * rcp_denom;
    encV[0] = tx + ty;
    encV[1] = tx - ty;
}

void DecodeHemiOctaNormal(const float2 encV, inout float3 v) {
    // 単位スクエアを中心ダイアモンドに戻すように回転と拡大縮小する。
    v[0] = (encV[0] + encV[1]) * 0.5f;
    v[1] = (encV[0] - encV[1]) * 0.5f;
    v[2] = 1.0f - abs(v[0]) - abs(v[1]);
}

Footnotes

  1. 訳注:froxel = frustum + voxel