Skip to content
Go back

Graphics Gems from CryENGINE 3

· Updated:

slides web

アンチエイリアシング \ ディファードMSAAのレビュー(ANTIALIASING \ DEFERRED MSAA REVIEW)

  • 問題: マルチパス+マルチサンプルRTからの読み書き
  • SV_SampleIndex
    • サブサンプルごとにピクセルシェーダ実行を強制して、現時点で実行されたサブサンプルのインデックスを提供する
    • インデックスはマルチサンプルRTからサブサンプルをフェッチするのに使える。例:FooMS.Load(UnnormScreenCoord, nSampleIndex)
  • SV_Coverage
    • ラスタステージ中にどのサブサンプルが遮蔽したかをピクセルシェーダに示す
    • カスタムカバレッジマスクでサブサンプルのカバレッジを修正できる
  • DX11.0のコンピュート・タイルベース・ディファードシェーディング/ライティングのMSAAはより単純になる
    • サブサンプルでタグ付けされたMSAAを介したループloop through MSAA tagged sub-samples

ディファードMSAA \ 用心せよ!(DEFERRED MSAA \ HEADS UP!)

  • 単純な理論、面倒な実践
    • 少なくとも複雑なディファードレンダラを伴う
  • 非MSAAフレンドリーなコードは高速に蓄積する
    • MSAAを考慮しないで新しいテクニックが追加されるため、定期的に壊れる
    • まだイケるとしても…これらはビジュアルアーティファクトを引き起こすので、頻繁に非MSAAフレンドリーなテクニックを特定して修正する必要があるだろう
    • 例えば、白/黒のアウトライン、または、AAまったくなし
  • 前もって行おう。ディファードMSAAをサポートするためにレンダラを改造retrofitすることはそれなりに手間がかかるsome work
    • そして、とても気難しいfiniky

ディファードMSAA \ カスタム解決&サンプル毎マスク(DEFERRED MSAA \ CUSTOM RESOLVE & PER-SAMPLE MASK)

  • Gバッファの後にはカスタムMSAA解決を処理する
    • ライティング/他のMSAA依存パスのようなピクセル頻度パスに対して、サンプル0を事前解決する
    • 同じパスで、サブサンプルマスクを生成する(サンプルの類似性を比較し、不一致ならばマークする)
      • MSAAを必要としない領域を無駄に処理してしまうことになるので、デフォルトのSV_Coverageを避ける

ディファードMSAA \ ステンシルバッチング[Sousa13](DEFERRED MSAA \ STENCIL BATCHING [SOUSA13])

[Sousa et al. 2013Sousa, T., Wenzel, C. and Raine, C. 2013. The Rendering Technologies of Crysis 3. Game Developers Conference. https://gdcvault.com/play/1017626/Advanced-Visual-Effects-with-DirectX.]

  • 通常のステンシルバッファの使い方でサンプル毎ステンシルマスクをバッチ処理する
    • ステンシルバッファから1ビットを予約する
    • サブサンプルマスクで更新する
    • 単一のピクセルだけではなくピクセルクアッドpixel-quad全体をタグ付けする → ステンシルカリング効率が改善する
    • サンプル毎ビットのオーバーライドを避けるためにステンシル読み/書きビットマスクを使う
      • StencilWriteMask = 0x7f
    • ステンシルクリアが起こるたび復元する
  • 極端にステンシルを使うため可能ではない?
    • clip/discardを使う
    • サンプル毎マスクに対する追加のテクスチャ読み込みに由来する余分なオーバーヘッドもある

ディファードMSAA \ ピクセルおよびサンプル頻度パス(DEFERRED MSAA \ PIXEL AND SAMPLE FREQUENCY PASSES)

  • ピクセル頻度パス
    • ピクセル毎領域に対する予約済みビットにステンシル読み込みマスクをセットする(~0x80
    • 解決前(非マルチサンプル)ターゲットSRVをバインドする
    • 普段通りにパスをレンダリングする
  • サンプル頻度パス
    • サンプル毎領域に対する予約済みビットにステンシル読み込みマスクをセットする(0x80
    • マルチサンプルターゲットSRVをバインドする
    • SV_SampleIndex経由で現在のサンプルをインデックス付けする
    • 普段通りにパスをレンダリングする

ディファードMSAA \ アルファテストSSAA(DEFERRED MSAA \ ALPHA TEST SSAA)

  • アルファテストにはアドホックな解決策が必須となる
    • デフォルトのSV_Coverageはトライアングルのエッジに適用されるだけ
  • 独自のサブサンプルカバレッジマスクを生成する
    • 例えば、現在のサブサンプルがアルファテストを使うかどうかを確認してビットをセットする
static const float2 vMSAAOffsets[2] = {float2(0.25, 0.25), float2(-0.25, -0.25)};
const float2 vDDX = ddx(vTexCoord.xy);
const float2 vDDY = ddy(vTexCoord.xy);
[unroll] for (int s = 0; s < nSampleCount; ++s) {
    float2 vTexOffset = vMSAAOffsets[s].x * vDDX + vMSAAOffsets[s].y * vDDY;
    float fAlpha = tex2D(DiffuseSmp, vTexCoord + vTexOffset).w;
    uCoverageMask |= ((fAlpha - fAlphaRef) >= 0) ? (uint(0x1) << i) : 0;
}

ディファードMSAA \ パフォーマンスショートカット(DEFERRED MSAA \ PERFORMANCE SHORTCUTS)

  • ディファードカスケード太陽シャドウマップ
    • ピクセル頻度で通常通りシャドウをレンダリングする
    • ディファードシェーディングの合成パス中にバイラテラルアップスケールする

ディファードMSAA \ パフォーマンスショートカット (2)(DEFERRED MSAA \ PERFORMANCE SHORTCUTS (2))

  • 深度にアクセスする不透明でないテクニック(例、ソフトパーティクル)
    • サンプル毎頻度を経由して対処するという推奨事項は現実の事例ではかなり低速である
    • 最大深度を使うとほとんどのケースでちゃんと動作し、N倍速い

ディファードMSAA \ パフォーマンスショートカット (3)(DEFERRED MSAA \ PERFORMANCE SHORTCUTS (3))

  • 多くのゲームは以下も行っている
    • アルファテストスーパーサンプリングをスキップする
      • 代わりにAlpha to Coverageを使う、または、アルファテストAAを使わない(morphological AAに任せる)
    • 不透明のみをMSAAありでレンダリングする
      • その後、MSAAなしで透明をレンダリングする
      • HDRレンダリングを仮定すると: トーンマッピングは暗黙的に行われ、解決後の結果はハイコントラストの領域で詳細が失われることに注意する

ディファードMSAA \ MSAAの馴染みやすさ(DEFERRED MSAA \ MSAA FRIENDLINESS)

  • これらに注意しよう
    • MSAAが目立って働かない、または、明るい/暗いシルエットが目立つ

ディファードMSAA \ 要約(DEFERRED MSAA \ RECAP)

  • マルチサンプルRTにアクセスする、および/または、レンダリングする?
    • その後、正しいサブサンプルに対するアクセスと出力について注意する必要がある
  • 一般に、帯域幅を最小化するよう常に努力する
    • そのままのディファードライティングを避ける
      • 完全なディファード、ハイブリッド、ディファードをまるまるスキップ、などを推奨する
    • ディファードの場合、薄いGバッファを推奨する
      • Gバッファに対する追加の各ターゲットはエクスポートレートのオーバーヘッドを負う[Thibieroz 2011Thibieroz, N. 2011. Deferred shading optimizations. Game Developers Conference. https://web.archive.org/web/20120518025936/http://developer.amd.com/gpu_assets/Deferred%20Shading%20Optimizations.pps.]
      • NV/AND(GCN):エクスポートコスト = RT0のコスト + RT1のコスト…、AND(旧世代): エクスポートコスト = (RT数) * (最遅RT)
      • きなfatフォーマットはGCNにおいてバイリニアフィルタリングモードに対するサンプリングコストを半分のレートにする[Thibieroz and Gruen 2013Thibieroz, N. and Gruen, H. 2013. DirectX11 Performance Reloaded. Game Developers Conference. https://www.gdcvault.com/play/1031882/Advanced-Visual-Effects-with-DirectX.]
      • ライティング/いくつかのHDRポストプロセスに対して: 殆どの場合、32ビットのR11G11B10Fフォーマットで十分

アンチエイリアシング+4K解像度 \ 結局MSAAは必要なのだろうか?(ANTIALIASING + 4K RESOLUTIONS \ WILL WE NEED MSAA AT ALL?)

  • ここが創造性の発揮しどころだろう

アンチエイリアシング \ 優秀(で高速)なAAの探求(ANTIALIASING \ THE QUEST FOR BETTER (AND FAST) AA)

テンポラルSSAA \ SMAA 2TX/4Xのレビュー[JIMENEZ11][OUSA11](TEMPORAL SSAA \ SMAA 2TX/4X REVIEW [JIMENEZ11][SOUSA11])

[Jimenez et al. 2011Jimenez, J., Gutierrez, D., Yang, J., Reshetov, A., Demoreuille, P., Berghoff, T., Perthuis, C., Yu, H., McGuire, M., Lottes, T., Malan, H., Persson, E., Andreev, D. and Sousa, T. 2011. Filtering approaches for real-time anti-aliasing. ACM SIGGRAPH 2011 courses. 10.1145/2037636.2037642. https://www.iryoku.com/aacourse/.; Sousa 2011Sousa, T. 2011. Anti-Aliasing Methods in CryENGINE 3. Filtering Approaches for Real-time Anti-aliasing course. ACM SIGGRAPH. https://www.iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf.]

  • モーフォロジカルAA+MSAA+テンポラルSSAAの組み合わせ
    • コスト/クオリティのトレードオフの釣り合いが取られ、テクニックが互いに補い合う
    • テンポラル要素は2つのサブピクセルバッファを使う
    • 各フレームは2xSSAAのサブピクセルジッターを加える
    • 前フレームを再投影し、速度の長さの重み付けを介して現フレームと前フレームをブレンドする
    • 画像のシャープネス+合理的なテンポラル安定性を保持する
w=0.5max(0,1Kvcvp)c=(1w)cc+wcp\begin{align} w &= 0.5 \max \left( 0, 1 - K \sqrt{\left| \|v_c\| - \|v_p\| \right|} \right) \\ c &= (1 - w) c_c + w c_p \end{align}

テンポラルAA \ 一般的なロバスト性の欠陥(TEMPORAL AA \ COMMON ROBUSTNESS FLAWS)

  • 不透明ジオメトリ情報に依存している
    • シグナル(色)変化や透明を扱うことができない
    • 正しい結果のため、すべての不透明ジオメトリは速度を出力しなければならない
  • 異常なathologicalケース
    • アルファブレンドされた表面(例えば、パーティクル)、ライティング/シャドウ/反射/UVアニメーション/など
    • AA解決前の、散乱や同様のポストプロセス
  • 気の散るエラーになり得る
    • 例えば、透明、ライティング、シャドウの”ゴースト”
    • 散乱や同様のポストプロセス(例、ブルーム)によりシルエットが現れる
  • マルチGPU
    • 最も単純な解法: リソース同期を強制する
    • NVIDIAはNVAPI経由でリソースを強制同期するためのドライバヒントを開示している。これはNVIDIAのTXAAで使われた解法である
      • ハードウェアベンダへのメモ: すべてのベンダがこのようなものを開示すればそれは素晴らしいことだろう(マルチGPUのAPI機能で汎用化されればなお良い)

SMAA 1TX \ よりロバストなテンポラルAA(SMAA 1TX \ A MORE ROBUST TEMPORAL AA)

  • コンセプト: シグナル変化のみを追跡して、ジオメトリ情報に依存しない
cmax=max(cTL,cTR,cBL,cBR)cmin=min(cTL,cTR,cBL,cBR)cacc=clamp(cacc,cmin,cmax)wk=(CTL+cTR+cBL+cBR)0.25cMwrgb=clamp(1Klowfweq(1wk)+Khifreqwk,0,1)c=cM(1wrgb)+caccwrgb\begin{gather} c_{max} = \max(c_{TL}, c_{TR}, c_{BL}, c_{BR}) \\ c_{min} = \min(c_{TL}, c_{TR}, c_{BL}, c_{BR}) \\ c_{acc} = \text{clamp}(c_{acc}, c_{min}, c_{max}) \\ w_k = |(C_{TL} + c_{TR} + c_{BL} + c_{BR}) * 0.25 - c_M| \\ w_{rgb} = \text{clamp} \left( \frac{1}{K_{lowfweq} * (1 - w_k) + K_{hifreq} * w_k}, 0, 1 \right) \\ c = c_M * (1 - w_{rgb}) + c_{acc} * w_{rgb} \end{gather}
float3 cM = tex2D(tex0, tc.xy);
float3 cAcc = tex2D(tex0, reproj_tc.xy);

float3 cTL = tex2D(tex0, tc0.xy);
float3 cTR = tex2D(tex0, tc0.zw);
float3 cBL = tex2D(tex0, tc1.xy);
float3 cBR = tex2D(tex0, tc1.zw);

float3 cMax = max(cTL, max(cTR, max(cBL, cBR)));
float3 cMin = min(cTL, min(cTR, min(cBL, cBR)));

float3 wk = abs((cTL + cTR + cBL + cBR) * 0.25 - cM);

return lerp(cM, clamp(cAcc, cMin, cMax), saturate(rcp(lerp(k1, kh, wk))));

被写界深度(DEPTH OF FIELD)

被写界深度 \ もっともらしいDOF: パラメータ化(DEPTH OF FIELD \ PLAUSIBLE DOF: PARAMETERIZATION)

  • アーティストフレンドリーなパラメータはゲームのDOFが間違って見える傾向にある理由のひとつである
    • フォーカス範囲focus range”と”ブラー量blur amount”などのような一般的な制御方法には物理的な意味合いがあまりない
    • 錯乱円CoCは主にF値、焦点距離、フォーカス距離focal distanceに依存する。後ろの2つは直接FOVに影響する
    • もっとボケが欲しい場合、焦点距離を最大にして絞りapertureを広げる必要がある。これは適切なフレーミングframingのために対象物に近づいたり離れたりすることを意味する
      • ゲームアーティスト/プログラマーがDOFについて考える一般的な方法ではない

被写界深度 \ 焦点距離(DEPTH OF FIELD \ FOCAL LENGTH)

被写界深度 \ F値(DEPTH OF FIELD \ F-STOPS)

被写界深度 \ フォーカス距離(DEPTH OF FIELD \ FOCAL DISTANCE)

被写界深度 \ もっともらしいDOF: ボケ(DEPTH OF FIELD \ PLAUSIBLE DOF: BOKEH)

  • 写真において焦点外の領域は一般に”ボケ”と呼ばれる(日本語でブラーのこと)
  • ボケ形状はカメラの絞りサイズ(F値)と絞り羽根の枚数に直接関係を持つ
    • 大きな絞り=“円形”ボケ、小さな絞り=多角形ボケ
      • 多角形ボケの見た目は絞り羽根の枚数に依存する
      • 羽根の枚数はレンズの特徴で変化する
    • 大きな絞り=入る光が多い、小さな絞り=入る光が少ない
      • 夜景の撮影では、円形ボケとモーションブラーがしばしば多くなることに気付くかもしれない
  • ボケのカーネルは平坦である
    • ほぼ同じ光量がすべての方向からカメラの虹彩irisに入る
      • edgeは影になるかもしれない。これは一般に口径食vignettingとして知られる
      • レンズの製造が粗悪だと、無数の光学収差optical aberrationを引き起こすかもしれない
    • これはガウシアンブラー、拡散diffusionDOF、派生テクニックが間違って/ビジュアル的に不快に見える主な理由である

被写界深度 \ 最新技術の概要(DEPTH OF FIELD \ STATE OF THE ART OVERVIEW)

被写界深度 \ 最新技術の概要 (2)(DEPTH OF FIELD \ STATE OF THE ART OVERVIEW (2))

被写界深度 \ もっともらしく効率的なDOF再構築フィルタ(DEPTH OF FIELD \ A PLAUSIBLE AND EFFICIENT DOF RECONSTRUCTION FILTER)

  • 分割可能な柔軟性のあるフィルタ: 要求される帯域幅が小さい+様々なボケ形状が可能
    • 第1パス N2N^2タップ(例:7x7)
    • 第2パス 形状を塗りつぶすflood-fillするためのN2N^2タップ(例:3x3)
    • R11G11B10F: ダウンスケールしたHDRシーン、R8G8: CoC
    • 半分の解像度で行われる
    • 遠/近フィールドは同じパスで処理される
    • アンダーサンプリングを最小化するためにオフセット範囲を制限する
    • スペックの高いハードウェアではタップ数をより多く取れる
  • 絞りと光学収差のシミュレーション
  • 物理ベースCoC

被写界深度 \ レンズのレビュー(DEPTH OF FIELD \ LENS REVIEW)

  • ピンホール”レンズ”
    • レンズのないカメラ
    • 光は像平面に当たる前に単一の小さな絞りを通らなければならない
    • 典型的なリアルタイムレンダリング
  • 薄レンズ
    • カメラレンズは有限の大きさを持つ
    • 光は像平面に当たるまでにレンズを通って屈折する
    • FF = 焦点距離
    • PP = 焦点の合う面plane in focus
    • II = 像距離

被写界深度 \ レンズのレビュー (2)(DEPTH OF FIELD \ LENS REVIEW (2))

  • 薄レンズの式は以下の関係を与える:
    • FF = 焦点距離(光が集まり始める所)
    • PP = 焦点の合う面(カメラのフォーカス距離)
    • II = 像距離(像がピントが合って投影される所)
1P+1I=1F\frac{1}{P} + \frac{1}{I} = \frac{1}{F}
  • 錯乱円[Potmesil and Chakravarty 1982Potmesil, M. and Chakravarty, I. 1982. Synthetic image generation with a lens and aperture camera model. ACM Trans. Graph. 1, 2, 85–108. 10.1145/357299.357300. https://doi.org/10.1145/357299.357300.]
    • ff = F値
    • DD = 物体距離
    • AA = 絞りの直径
CoC=FDDFFPPFDFfDf=FA\begin{gather} CoC = \left| \frac{FD}{D-F} - \frac{FP}{P-F} \right| \frac{D-F}{fD} \\ f = \frac{F}{A} \end{gather}
  • 単純化すると
    • 注: ffFFはカメラ設定からの既知の変数である
    • シェーダでは単一のMAD命令に落とし込む
CoC=AF(PD)D(PF)CoC = \left| A \frac{F(P-D)}{D(P-F)}\right|
  • カメラのFOV:
    • 一般的なフィルムフォーマット(または、センサー)、35mm/70mm
    • 代わりにFOVから焦点距離を導き出せる
θ=2arctanwidthfilm2F,F=0.5widthfilmtan(θ/2)\theta = 2\text{arctan} \frac{width_{film}}{2F}, F = \frac{0.5width_{film}}{\tan(\theta/2)}

被写界深度 \ サンプリング(DEPTH OF FIELD \ SAMPLING)

  • 同心円マッピング[Shirley and Chiu 1997Shirley, P. and Chiu, K. 1997. A low distortion map between disk and square. Journal of Graphics Tools 2, 3, 45–52. 10.1080/10867651.1997.10487479.]は一様サンプル分布に対して使われる
    • 単位四角形を単位円にマップする
    • 四角形は(a,b)[1,1]2(a, b) [1, 1]^2にマップされ、a=ba=ba=ba=-bの直線で4つの領域に分割される
    • 第1領域は以下で求められる
r=aθ=PIb4a\begin{gather} r = a \\ \theta = \frac{PIb}{4a} \end{gather}
  • サンプルをN角形に変形することによる絞りシミュレーション
    • 修正した通常の多角形の式を介して
f=fstopsfstopsminfstopsmaxfstopsminθ=θ+fθshuttermaxrngon=r(cos(PIn)cos(θ2PInfloor(nθ+PI2PI)))f\begin{gather} f = \frac{f_{stops} - f_{stops_min}}{f_{stops_max} - f_{stops_min}} \\ \theta = \theta + f\theta_{shutter_max} \\ r_{ngon} = r \left( \frac{\cos(\frac{PI}{n})}{\cos(\theta - \frac{2PI}{n}\text{floor}(\frac{n\theta + PI}{2PI}))} \right)^f \end{gather}

被写界深度 \ サンプリング: 2回目の反復(DEPTH OF FIELD \ SAMPLING: 2ND ITERATION)

  • 最終的な形状を塗りつぶすため、[McIntosh et al. 2012McIntosh, L., Riecke, B. E. and DiPaola, S. 2012. Efficiently simulating the bokeh of polygonal apertures in a post-process depth of field shader. Computer Graphics Forum 31, 6, 1810–1822. 10.1111/j.1467-8659.2012.02097.x. http://ivizlab.sfu.ca/papers/cgf2012.pdf.]と同じように、二値の和集合boolean unionで合成する

被写界深度 \ 分割可能なフィルタパス(DEPTH OF FIELD \ SEPARABLE FILTER PASSES)

被写界深度 \ リファレンス vs 分割可能なフィルタ(DEPTH OF FIELD \ REFERENCE VS SEPARABLE FILTER)

被写界深度 \ 動作中の絞りシミュレーション(DEPTH OF FIELD \ DIAPHRAGM SIMULATION IN ACTION)

被写界深度 \ タイル最大/最小CoC(DEPTH OF FIELD \ TILE MIN/MAX COC)

  • タイル最大/最小CoC
    • CoCターゲットをk回だけダウンスケールする(kはタイル数)
    • 遠方場far fieldのための最小フラグメントと近接場near fieldのための最大フラグメントを取る
    • R8G8のストレージ
  • 近接/遠方場を同じパスで処理するために使う
    • 両場のタイル最大/最小CoCを用いる動的分岐
    • 遠/近の間のコストのバランスを取る
    • 近接場に対するscatter as gather近似でも使われる
  • 他のポストプロセスにコストを畳み込むfoldことができる
    • 最初のダウンスケールコストはブルームのためのHDRシーンのダウンスケールに畳み込まれ、近接/遠方場のHDR入力をR11G11B10Fにパックする --- オールインワンパス

被写界深度 \ 遠方+近接場処理(DEPTH OF FIELD \ FAR + NEAR FIELD PROCESSING)

  • 両方の場は半分の解像度の入力を使う
    • 注意: ダウンスケールはバイリニアフィルタリングにより誤差のもとになる
    • ダウンスケールにカスタムのバイリニア(バイラテラル)フィルタを使う
  • 遠方場
    • カーネルサイズをスケールして、遠方CoCでサンプルを重み付けする[Scheuermann and Tatarchuk 2004Scheuermann, T. and Tatarchuk, N. 2004. Improved Depth of Field Rendering. ShaderX3. http://www.shaderx3.com/index.htm.]
    • 遠方CoCでレイヤを事前乗算する[Gotanda 2009Gotanda, Y. 2009. STAR OCEAN 4: Flexible Shader Management and Post-Processing. Game Developers Conference. https://gdcvault.com/play/965/STAR-OCEAN-4-Flexible-Shader.]
      • バイリニア/分割可能フィルタからのブリーディングアーティファクトを軽減する
  • 近接場
    • scatter as gather近似
    • カーネルサイズをスケールして、近接CoCに対するタイル最大CoCでフラグメントを重み付けする
    • 近接CoCで事前乗算する
      • 近接場のフラグメントをブラーしたいだけ(安価な部分的な遮蔽の近似)

被写界深度 \ 最後の合成(DEPTH OF FIELD \ FINAL COMPOSITE)

  • 遠方場: バイラテラルフィルタを経由してアップスケールする
  • 近接場: 気にせずアップスケールする
    • ハーフ解像度の近接場CoCがブレンディングに使われる
    • できるだけにじませるbleedことができる
    • バイキュービックフィルタを使うことも
  • ブレンディングに注意
    • 線形ブレンディングはいい感じに見えない(信号周波数がまぜこぜにsignal frequency soup
      • Crysisシリーズを含め、色んなゲームで見られる(お恥ずかしい話ですがputs hat of shame
    • 単純な対処法: 代わりに非線形のブレンドファクタを使う

モーションブラー(MOTION BLUR)

モーションブラー \ シャッタースピードとF値のレビュー(MOTION BLUR \ SHUTTER SPEED AND F-STOPS REVIEW)

  • モーションブラーの量はカメラのシャッタースピードとF値の使い方に関連する
    • 露出が長い(シャッターが遅い)と、より多くの光を受け取る(そして、モーションブラー量が多くなる)。逆もまた然り
    • F値が小さいと、露出が速くなる(そして、モーションブラーが少なくなる)。逆もまた然り

モーションブラー \ 最新技術の概要(MOTION BLUR \ STATE OF THE ART OVERVIEW)

モーションブラー \ 最新技術の概要 (2)(MOTION BLUR \ STATE OF THE ART OVERVIEW (2))

モーションブラー \ もっともらしいモーションブラーのための再構築フィルタ [MCGUIRE12]《OTION BLUR \ RECONSTRUCTION FILTER FOR PLAUSIBLE MB [MCGUIRE12])

[McGuire et al. 2012McGuire, M., Hennessy, P., Bukowski, M. and Osman, B. 2012. A reconstruction filter for plausible motion blur. Proceedings of the ACM SIGGRAPH symposium on interactive 3D graphics and games 135–142. 10.1145/2159616.2159639. https://casual-effects.com/research/McGuire2012Blur/McGuire12Blur.pdf.]

  • タイル最大速度Tile Max Velocityタイル近傍最大速度Tile Neighbor Max Velocity
    • 速度バッファをk倍ダウンスケールする(kはタイル数)
    • 各ステップで速度の最大長を取る
  • モーションブラーパス
    • 早期脱出のためのタイル近傍最大速度
    • 中心速度タップとしてのタイル最大速度
    • 各反復ステップで、フル解像度のV\|V\|と深度に対して重み付けする

モーションブラー \ 改善された再構築フィルタ(MOTION BLUR \ AN IMPROVED RECONSTRUCTION FILTER)

  • パフォーマンスの品質
    • 内部ループの重み計算を単純化してベクトル化する(最終的にいくつかのMAD命令になる)
    • 大きいfatバッファのサンプリングはGCNハードウェアでバイリニアを伴うとレートが半分になる(ポイントフィルタリングはフルレートだが、エイリアシングのせいで良い感じに見えない)
    • 入力: シーンでR11G11B10F、V\|V\|と8ビット深度をR8R8ターゲットに焼き込む
    • 分割可能、2パスにする[Sousa 2008Sousa, T. 2008. CRYSIS Next-Gen Effects. Game Developers Conference. https://www.gdcvault.com/play/247/CRYSIS-Next-Gen.]

モーションブラー \ 改善された再構築フィルタ (2)(MOTION BLUR \ AN IMPROVED RECONSTRUCTION FILTER (2))

float2 DepthCmp(float2 z0, float2 z1, float2 fSoftZ) {
    return saturate((1.0f + z0 * fSoftZ) - z1 * fSoftZ);
}

float4 VelCmp(float lensq_xy, float2 vxy) {
    return saturate((1.0f - lensq_xy.xxxx * rcp(vxy.xyxy)) + float4(0.0f, 0.0f, 0.95f, 0.95f));
}

const float2 tc = min_tc + blur_step * s;
const float lensq_xy = abs(min_len_xy + len_xy_step * s);
const float2 vy = tex2Dlod(tex1, float4(tc.xy, 0, 0));  // x = ||v||, y = depth

const float2 cmp_z = DepthCmp(float2(vx.y, vy.y), float2(vy.y, vx.y), 1);
const float4 cmp_v = VelCmp(lensq_xy, float2(vy.x, lensq_vx));
const float w = (dot(cmp_z.xy, cmp_v.xy) + (cmp_v.z * cmp_v.w) * 2);

acc.rgb += tex2Dlod(tex0, float4(tc.xy, 0, 0)) * w;

モーションブラー \ 改善された再構築フィルタ (3)(MOTION BLUR \ AN IMPROVED RECONSTRUCTION FILTER (3))

  • Gバッファにオブジェクトの速度を出力する(必要な場合のみ)
    • 別のジオメトリパスを避ける
    • リジッドrigidジオメトリ: オブジェクト距離 < 距離しきい値
    • 変形可能deformableジオメトリ: 移動量 > 移動しきい値の場合
    • 移動するジオメトリは最後にレンダリングされる
    • R8G8フォーマット
  • カメラ速度で合成する
    • 速度はガンマ2.0空間でエンコードされる
    • 精度はまだ十分ではないが、実践ではそれほど目立たない
  • エンコード
venc=vxysgn(vxy)(127.0/255.0)+0.5v_{enc} = \sqrt{|v_{xy}|} * \text{sgn}(v_{xy}) * (127.0 / 255.0) + 0.5
  • デコード
venc=(venc127.0/255.0)/255.0v=(vencvenc)sgn(venc)v_{enc} = (v_{enc} - 127.0 / 255.0) / 255.0 v = (v_{enc} * v_{enc}) * \text{sgn}(v_{enc})

モーションブラー \ MBとDOFのどちらが先?(MOTION BLUR \ MB OR DOF FIRST?)

  • 現実世界では、MB/DOFは同時に起こる
    • 夢の実装: 大きなN2N^2カーネル+バッチ化されたDOF/MB
    • または、MBクアッド伸縮stretchingに基づくスプライト
    • フル解像度!十億タップ!FP16!複数レイヤ!:)
  • だけど、パフォーマンスは依然として重要である(コンソール)
    • MB前DOFは、合焦のところでMBが起こるとき、より少ない誤差を引き起こす
      • これはMBがジオメトリデータに依存したscatter as gather処理であるため
      • その後の他の同じような処理は誤差を引き起こす。そして、逆もまた然り
      • DOF後MBによる誤差はより目立ちにくい
    • 逆順order swapだとDOFを他のポストエフェクトに畳み込むのが難しくなる
      • 追加のオーバーヘッド

最後の備考(FINAL REMARKS)

  • 実践的MSAAの詳細
    • すること、しないこと
  • SMAA 1TX: 更にロバストなテンポラルAA
    • 4つの追加のテクスチャ処理といくつかのALU
  • もっともらしく高性能なperformantDOF再構築フィルタ
    • 分割可能で柔軟性のあるフィルタ、どんなボケカーネル形状も可能
    • 1stパス: 0.426ms、2ndパス: 0.094ms。再構築フィルタで合計: 0.52ms(1080p+AMD7970)
  • もっともらしいモーションブラーのための改善された再構築フィルタ
    • 分割可能、1stパス: 0.236ms、2ndパス: 0.236ms。再構築フィルタで合計: 0.472ms(1080p+AMD7970)