Skip to content
Go back

Secrets of CryENGINE 3 Graphics Technology

· Updated:

url

拙訳

物理ベースレンダリング(Physically Based Rendering)

  • 線形補正HDRレンダリング[Gritz and d'Eon 2008Gritz, L. and d'Eon, E. 2008. The Importance of Being Linear. GPU Gems 3. https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear.; Reinhard et al. 2010Reinhard, E., Ward, G., Pattanaik, S., Debevec, P., Heidrich, W. and Myszkowski, K. 2010. High dynamic range imaging: Acquisition, display, and image-based lighting.]
  • 最小Gバッファ: 深度と法線
    • 不透明度、デカール、def. decals、地形terrainレイヤー
  • ディファードライティング
    • アンビエント、環境光プロブ
    • GI、SSDO、RLR、ライト
    • 物理ベースシェーディング
  • 不透明/透明パス
  • HDR/LDR後処理

Gバッファ/Lバッファ/シーンターゲット(G-Buffer/L-Buffers/Scene Targets)

  • スリムなGバッファ
    • A8B8G8R8のワールド空間のBF1法線+光沢度glossiness
    • リードバックD24S8深度+屋内の表面をタグ付けするためのステンシルビット
  • ディフューズとスペキュラバッファ用の2つのA2B10G10R10F_EDRAM
    • X360: A2B10G10R10に解決される[Cook 2008Cook, D. 2008. Xbox Textures – Formats, Conversion, Fetching and Performance.]
    • PS3: 2つのA8B8G8R8はRGBMにエンコードされる。
      • エンコード ⇔ 使えるHWブレンディングがない。ワークアラウンド: dstRTから読み書きする。
    • PC: 2つのA16B16G16R16F(最も一般的なフォーマット)
  • シーンターゲット用のA2B10G10R10F_EDRAM
    • PS3: 不透明ではA8B8G8R8 RGBM、透明ではFP16にエンコードされる。
    • PC A16B16G16R16F

Zバッファ深度の注意(Z-Buffer Depth Caveats)

  • 双曲線hyperbolic分布
    • シェーダで使う前に線形に変換を必要とする。
// 定数
g_ProjRatio.xy = float2(zfar / (zfar - znear), znear / (znear - zfar));

// HLSL関数
float GetLinearDepth(float fDevDepth) {
    return g_ProjRatio.y / (fDevDepth - g_ProjRatio.x);
}
  • 問題: 一人称視点オブジェクト
    • 深度バッファは一人称視点オブジェクトをシーンの残りとオーバーラップしないようにするために使われる。
    • 異なるFOVとニア/ファー面(アート固有の選択)
    • 実際のオーバーラッピングを抑制するための異なる深度範囲
    • ⇒ ディファードテクニックはそのようなオブジェクトに対して100%正常に動作しない。

一人称視点オブジェクトの対処(Addressing First Person View Objects)

  • 我々の最終解:
    • 深度再構築関数を修正する。
    • ハードウェア深度を線形に変換する。
    • 一人称視点オブジェクトに対する異なる深度スケール
    • 深度に基づく選択
float GetLinearDepth(float fDevDepth) {
    float bNearDepth = step(fDevDepth, g_PS_DepthRangeThreashold);
    float2 ProjRatio.xy = lerp(g_PS_ProjRatio.xy, g_PS_NearestScaled.xy, bNearDepth);
    return ProjRatio.y / (fDevDepth - ProjRatio.x);
}

深度から位置の再構築(Reconstructing Position from Depth)

  • アイデア: スクリーン空間Sから対象の同次空間W(シャドウ空間かワールド空間)へ直接的にVPOSを線形に変換する。
float4 HPos = (vStoWBasisZ + (vStoWBasisX * VPos.x) + (vStoWBasisY * VPos.y)) * fSceneDepth;
HPos += vCamPos.xyzw;
  • スクリーンクリップ空間から同次行列に直接変換する。
  • VPOSはディファードライトボリュームをレンダリングするための最も単純な方法である。
  • s3Dのための調整を分割する。

カバレッジバッファ(Coverage Buffer)

  • Crysis2ではほとんど屋外
    • おおよそ70%
    • そのような所ではポータルやPVSは効率的でない。
  • 主なオクルージョンカリングシステムとしてのカバレッジバッファ
    • 本質的には低解像度の深度バッファ
    • 可視性Zテスト用の物体のAABB/OBBの粗いCPUラスタライゼーション
  • 十分に詳細なカバレッジバッファをCPUで準備するのは遅すぎる。
    • 巨大な計算コスト
    • カバレッジバッファにすべての詳細を得るため、完全なレンダリングパイプラインをソフトウェアに複製しなければならない。
  • 前フレームのGPU深度バッファをCPUにリードバックする。
    • GバッファのあとにGPUでZバッファをダウンスケールする(maxフィルタ)。
    • 分割したCPUスレッドでバウンディングボックスをラスタライズすることによりカリングが行われる。
  • X360/PS3とDX11ハードウェアで用いられる。
    • これについてはコンソールが完璧(1フレームのレイテンシー)
    • PCでのリードバックのレイテンシーはより大きいがまだ許容範囲内である(最大4フレーム)。
  • カバレッジバッファサイズはコンソールのCrysis2では256x128に制限される。
  • 問題: 前/現フレームのカメラの間のミスマッチ
    • 結果として誤った可視性テストになる。

カバレッジバッファの再投影(Coverage Buffer Reprojection)

  • 結局の所、前フレームのカメラからカバレッジバッファのCPU再投影を用いることになる。
    • 再投影されたフラグメントのポイントスプラッティング
    • カメラ情報はカバレッジバッファデータにエンコードされる。
  • 個別のスレッドでのCPUリードバックと再投影
    • SPUでは約2ms、ベクトル化したXbox360では約3-4ms
  • 再投影後のカバレッジバッファ内の穴埋めstitching of holes
    • 3x3の膨張パス
    • 残っているカバレッジバッファの穴: オブジェクトが可視であると仮定する。
  • 再投影はカリング効率を大幅に改善する。
    • すべての種類のオクルージョンテストのアーティファクトを解決し、不正なエリアを特定する。
    • より大きなフレームレートでより効率的に動作する。

ディファードライティング: アンビエント(Deferred Lighting: Ambient)

  • 屋外/屋内
    • Gバッファパスでのステンシルでタグ付けされた領域
    • フルスクリーンクアッドと屋内ボリュームのバウンディングボックス
    • 加算ブレンディング

ディファードライティング: 環境プロブ(Deferred Lighting: Ambient)

  • 正確なディフューズライティングとスペキュラライティング
    • アーティストがインポータンスサンプリングの位置を選び取る。
    • (RGBMに)エンコードされるHDR
    • ディフューズ及びスペキュラキューブマップに対する線形ブレンディング
    • 球ライトボリューム
  • Gバッファのマテリアルの光沢度はMIPレベルの選択に用いられる。
    • IBLと通常のライトの間の矛盾のないスペキュラの振る舞い
  • アルファブレンドされたパスでは?最近傍のプロブを選び取る。

ディファードライティング: GI、SSDO、RLR、ライト(Deferred Lighting: GI, SSDO, RLR, Lights)

  • GI[Kaplanyan 2010Kaplanyan, A. 2010. Real-time Diffuse Global Illumination in CryENGINE 3. ACM SIGGRAPH. https://cgg.mff.cuni.cz/~jaroslav/gicourse2010/giai2010-07-anton_kaplanyan-slides.pdf.]を加える(加算ブレンド)。
  • SSDO(乗算ブレンド)とRLR(アルファブレンド)を適用する。
  • 光源を加える。
    • ライトレンダリングはスクリーンカバレッジヒューリスティクスに依存する。
      • ステンシルボリュームを持つフルスクリーンクアッドのプリパス、凸状ライトボリューム、または、2Dクアッド
    • 正規化済みBlinn-Phong[Hoffman et al. 2010Hoffman, N., Gotanda, Y., Snow, B. and Martinez, A. 2010. Physically-Based Shading Models in Film and Game Production. SIGGRAPH 2010 Course: Physically-Based Shading Models in Film and Game Production. https://renderwonk.com/publications/s2010-shading-course/.]
    • Crysis2では、プロジェクターと点ライト
    • コンソールではシャドウキャスタ数を制限する --- PCではそりゃもうヤバイ。

ディファードシャドウ(Deferred Shadows)

  • 太陽のためのシャドウマスク
    • シャドウオクルージョンを累積するための特別なレンダターゲット
    • シャドウマスクは実際のシェーディングで使う前にお互いの上に複数のシャドウテクニックを組み合わせる。
  • ポイントライトシャドウはライトバッファに直接レンダリングされる。

カスケードシャドウマップ(Cascaded Shadows Maps)

  • カスケードシャドウマップはCrysis1の頃から使われている。
  • カスケード分割スキーム
    • 対数テクセル密度分布を近似する。
    • シャドウ錐台を保守的にカメラ視錐台をカバーするように調整する。
    • シャドウ錐台の向きはワールド空間で固定される。
  • より多くのカスケードでできること
    • 対数分布のより良い近似による広いシャドウ範囲に対する、テクセル密度の改善、アクネの減少、セルフシャドウの改善
  • カスケードごとに、シャドウ錐台をシャドウマップのテクセルグリッドにスナップする。

ディファードシャドウパス(Deferred Shadow Passes)

  • カスケード/点ライトのシャドウパスはディファード法でレンダリングされる。
  • 潜在的にシャドウを受け取るエリアは錐台ボリュームをレンダリングすることによってステンシルバッファにタグ付けされる。
    • カスケードにより洗練された分割を持つことが可能になる。
    • オーバーラップする領域で最高解像度を持つカスケードを選び取る。
    • シャドウマップのスペースを無駄にするのを避ける。

シャドウカスケードキャッシング(Shadow Cascades Caching)

  • すべてのカスケードがひとつのフレームの間に更新されるわけではない。
    • 数フレームにまたがって更新コストを分散する。
    • パフォーマンス的な理由(特にPS3)
  • より多くのカスケードを持てるようにする --- より良いシャドウマップ密度分布
  • キャッシュされたシャドウマップはキャッシュされたシャドウ行列を使う。
  • 遠くのカスケードは頻度を下げて更新する。
  • 最終カスケードは分散シャドウマップを用いて、シャドウマスクで加算ブレンドする。
    • 巨大な遠いオブジェクトからの大きな半影を持てるようになる。

点ライトシャドウ(Point Light Shadows)

  • 多方向ライトを6つの独立のプロジェクターに常に分割する。
  • プロジェクターごとのシャドウマップは個別にスケールされる。
    • シャドウプロジェクションカバレッジに基づいて
    • 最終スケールはパラメータとしてカバレッジを用いる対数シャドウマップ密度分布関数の結果である。
  • スケーリング後に各フレームのすべてのシャドウマップをパックするための大きなテクスチャアトラス
    • テクスチャアトラスはメモリフラグメンテーションを回避するために永続的に割り当てられる。
    • コンソールでのサイズ: 1024x1024 (4MB)
  • 受け取るエリアはステンシルでタグ付けされる。

ソフトシャドウ近似(Soft Shadows Approximation)

  • シャドウ空間での無作為化randomizeした回転を伴うPoisson PCFタップを用いる。
  • 実行時カーネルサイズ調整は変化する半影を持つソフトシャドウの良い近似を持てるようになる。
  • ソフトシャドウのアイデア: シャドウキャスターへの平均距離の割合を推定する。
  • 基本のアルゴリズム:
    • カーネル中心からの距離でPoisson分布のタップを事前にソートする。
    • 最大範囲に合うように初期カーネルサイズを設定する(= 最大/最長の半影)。
    • このカーネルを用いて、平均距離の割合を推定する。
    • 平均距離の割合に比例してサンプル数を減らす。
      • タップはソートされているので、これはカーネルの半径に影響を与える。
    • 最終的なシャドウ計算には削減したサンプル数のみを用いる。
  • カスケードシャドウマップはカスケード間の遷移を扱うためにカスタムのカーネルスケール調整を必要とする。
  • コンピュートシェーダのオプション: すべてのタップをCSの共有メモリにフェッチして、距離推定とシャドウ計算の両方で再利用する。

シャドウ&透明(Shadows & Transparency)

  • アルファブレンドされるシャドウレシーバーでは
    • シャドウを適用するフォワードパス
  • キャスターのアルファ値を累積する透明なシャドウキャスターでは
    • 8ビットのレンダターゲットに格納する。
  • 半透明マップの生成:
    • バックプロジェクション/リークを避けるための通常の不透明シャドウマップからの深度バッファを用いる深度テスト
    • 半透明アルファを累積するためのアルファブレンドされるシャドウの生成パス(後ろから前にソートされる)。
    • カスケードシャドウマップの場合、カスケードごとに半透明マップを生成する。
    • シャドウマップと半透明マップのシャドウ項はディファードシャドウパス中にmax()命令で両方組み合わされる。

リアルタイムローカルリフレクション(Real Time Local Reflections)

  • 反射はラスタライゼーションのために高価である。
    • 通常は平面反射planar reflectionかキューブマップ
    • シーンの再レンダリングを必要とする。
  • 標準の反射は限定される。
    • 平坦な表面planar surface、か
    • キューブマップでの小さなエリア、のいずれか
    • 通常、曲面ではできない
  • レイトレーシングでの反射は素直
    • 局所的な反射を近似するためにスクリーン空間でレイトレーシングする。
    • 初のイテレーションはGDC2009で実証された。
  • 基本のアルゴリズム
    • ピクセルごとに反射ベクトルを計算する。
      • ディファード法線と深度ターゲットを用いる。
    • 反射ベクトルに沿ってレイマーチする。
    • 深度をサンプルし、レイ深度がシーン深度に対するしきい値内であるかを確認する。
    • ヒットならば、前フレームのフレームバッファに再投影して色をサンプルする。
  • 結果
    • 比較的安価
    • どこでもローカルリフレクション(複合的な表面でも)
    • 動作している所はすごくカッコイイ:)
    • スクリーン空間での限定されたデータゆえの問題となるケースが沢山ある。
  • 実装Tips
    • かなり限定されたスクリーン空間データ
      • 破綻して見えるより反射なしの方が良い。
      • 反射ベクトルがビュアーの方を向いている場合、使えるデータが無いので、滑らかにフェードアウトする。
    • 目立つステップアーティファクトを隠すためにステップサイズに対してジッタリングを加える。
    • Crysis2ではHDR色ターゲットをサンプルする。
    • 表面の光沢度に応じてジッターまたはブラーする。

コンタクトシャドウ(Contact Shadows)

  • 発想の中核はSSDO[Grosch and Ritschel 2010Grosch, T. and Ritschel, T. 2010. Screen-Space Directional Occlusion. GPU Pro.]と同じ。
    • 計算されたスクリーン空間オクルージョンでライティングを調整する。
    • ソフトなコンタクトシャドウを生み出す。
    • シャドウバイアスの問題を隠すこともできる。
    • 唯のSSAO以上の相当な品質向上
  • ただし、方向のオクルージョン情報はディファード法で利用可能
    • 既存のライティングパイプラインに良く合致する。
    • すべての光源に効率的に適用できる。
  • オクルージョン情報の生成
    • SSAOパス中にベント法線bent normalNN'を計算して格納する。
      • ベント法線は遮蔽されていない方向の平均である。
    • 自己遮蔽と比較的大きい半径を持たない綺麗なSSAOを必要とする。
  • ライトごとに
    • いつものようにNLN \cdot Lを計算する。
    • NLN' \cdot Lを計算する。
    • 2つの内積の間のクランプした差で乗算した遮蔽量でライティングを減衰する。

ディファードスキンシェーディング(Deferred Skin Shading)

  • 主なアイデア: ディフューズライティングの累積を再利用する。
    • プロジェクト開始以来の概念実証(2008年初頭)
  • スクリーン空間での表面下散乱
    • ジオメトリパス中にライティングタップを収集する。
    • Poisson分布を使う。
  • 一番良い所best bits
    • アトラスに追加のメモリを必要としない。
    • 冗長な処理なし
    • 概念はUV空間に拡張できる[Borshukov and Lewis 2003Borshukov, G. and Lewis, J. P. 2003. Realistic human face rendering for "The Matrix Reloaded". ACM SIGGRAPH 2003 sketches & applications 1. 10.1145/965400.965470. https://scribblethink.org/Work/Pdfs/Face-s2003.pdf.]
    • スクリーンエリアカバレッジに比例するコスト

スクリーン空間セルフシャドウ(Screen Space Self-Shadowing)

  • キャラクター毎のシャドウマップに対する余裕はないかもしれない。
    • どのようにコンソールでのメモリ不足に対処する?
  • 単純なトリック/近似
    • スクリーン空間のライトベクトルに沿ってレイマーチする。
    • コンソールでさえも、すべてのキャラクターに対するマクロなセルフシャドウのディテール

ソフトアルファテスト(Soft Alpha-Test)

  • 効率的な髪レンダリングは今世代のハードウェアではうんざりすることa painである。
  • ロバストな解決法:
    • アルファテストはとても1999年に見える2。4xSSAA以上に?。未だにコンシューマーハードウェア向きではない。
    • ATOC3はあまり良いようには見えず、ハードウェアMSAAを必要とする。
    • 点描stippling+フィルタリング?ある程度機能するが、半分の解像度のような見た目になる。
  • アイデア: アルファテストのような見た目をアンチエイリアシングするためのポストプロセス
    • プロジェクト開始からのもうひとつの古株(2008年初頭)
    • スクリーン空間でタンジェントベクトルに沿った方向ブラー(8タップ)
    • 透明度のためのビジュアルヒントと滑らかな髪のルック
    • 追加の髪ジオメトリパス
  • 毛皮レンダリング?スクリーン空間で法線ベクトルに沿った方向ブラー

カメラ&オブジェクトモーションブラー(Camera & Object Motion Blur)

  • 静的オブジェクトに対する再投影+動的オブジェクトに対する速度バッファ
    • フル解像度は少なくとも約3msかかることを意味する。(コンソール)
  • ハーフ解像度でRGBMにエンコードされる。
    • トータルで16xより少ない帯域幅 VS 太いfatフォーマット
  • フル解像度のブレンディングのための合成マスク
  • オンザフライのオブジェクト速度バッファ膨張[Sousa 2008Sousa, T. 2008. CRYSIS Next-Gen Effects. Game Developers Conference. https://www.gdcvault.com/play/247/CRYSIS-Next-Gen.]
  • トーンマッピング前に線形空間ですべて行われる。
    • 明るい筋bright streakは維持され、伝播される[Debevec and Malik 1997Debevec, P. E. and Malik, J. 1997. Recovering high dynamic range radiance maps from photographs. Proceedings of the 24th annual conference on computer graphics and interactive techniques 369–378. 10.1145/258734.258884. https://www.pauldebevec.com/Research/HDR/debevec-siggraph97.pdf.]
    • コンソール: 9タップ。高性能PC: 24タップ。

最大バッチ処理(Maximum Batching)

  • 我々が本当に欲しいブラーだけ
    • どうやってすべてのタップ/帯域幅を再利用したり、すべてのGPU処理を共有しTたりする?
  • アイデア: ブラータイプに基づいてモーフィングをオフセットする。
    • カメラ/オブジェクトの移動?方向 VS ディスクカーネル
    • さらなる使い方: マスクしたブラー、放射状ブラー、など。
  • 最終的な合成はトーンマッピングパスで直接行われる。
  • コンソールでは1ms。PCだと1080pでも超高速。
    • すべてのポストプロセスを個別にやるよりほぼ10倍速い(フル解像度で)。

Ultra仕様: モーションブラー(Ultra Specs: Motion Blur)

  • フルスクリーン解像度でのシングルパス
    • 12タップ+アンダーサンプリングを制限するために最大範囲をクランプする。
    • アルファチャンネルはオブジェクトIDを格納する。
  • 速度とIDに基づくブラーマスキングスキーム
    • $\|V\|$ > しきい値ならば、にじませる。そうでなければ、タップを破棄する。
    • $\|V\|$ < しきい値ならば、早期脱出する。

Ultra仕様: ボケDOF(Ultra Specs: Bokeh DOF)

  • Go Bananas: ピクセルごとにクアッド/スプライトをレンダリングする[Cyril et al. 2005Cyril, P., Sylvain, M. and Olivier, T. 2005. Photographic Depth of Field Blur Rendering. SHORT papers. WSCG. https://igm.univ-mlv.fr/~pichard/paper-wscg2004.pdf.]
    • CoCファクタでクアッドをスケールするジオメトリシェーダ
  • フォアグラウンド/バックグラウンドターゲットに結果を累積する。
    • レイヤーごとにクアッドをソートすることによるマスキング
    • アルファチャンネルはクアッド数を格納する。
    • 精度の損失を最小化するディザリング
  • 最終シーンと合成する。
    • レイヤーのアルファでレイヤーの結果を分割する。
  • 素晴らしいクオリティ!(ただし、とても遅い)
  • 高速化
    • ハーフ解像度でレンダリングする。
    • インターリーブしたパターンでクアッドをリジェクトする。
    • VS/PSのための早期脱出
    • ALUを用いた円形絞り
    • 将来: ジオメトリシェーダの使用を避ける。
  • 最終シーンと合成する。
    • 後ろのレイヤーはフル解像度のCoCを用いて合成する。
    • 前のレイヤーはどうにじんでも大丈夫。

S3D画像生成(S3D Image Generation)

  • 標準的なアプローチ: シーンを2回レンダリングする。
    • 素晴らしいクオリティ、とても素直
    • GPUヘビーなゲームでは問題になる。
      • フレームレートが半分になったりする。
    • Crysis2では大幅なクオリティ削減を必要とするだろう。
      • 解像度、LOD、ビュー距離、効果の品質/量
  • 画像空間アプローチ: 再投影
    • ビュー/ワールド空間のピクセル位置を再構築して、左/右目の空間に投影する。
    • 基本的にpoint splatting
    • 拡散はD3D9/10のGPUでは効率的に実現できない。
    • 第2穴埋めパスを必要とする。
  • ピクセルシェーダでの画像オフセティング
    • 収集ベースのアプローチ
    • ピクセルごとに、深度バッファから像差disparityを計算する。
    • 歪んだ画像を生成するオフセットとして正/負の像差を用いてバックバッファをサンプルする(バイリニアフィルタリングを用いる)。

タレスの定理Thales theoremを用いて計算される像差

像差: 左/右のビューでの投影された点の位置の間の距離

MS: 最大分割maximum separation (例、スクリーンの3%)

ZPD: ゼロ視差面の距離zero parallax plane distance

Disparity=MS(1ZPD/Depth)Disparity = MS * (1 - ZPD / Depth)
  • オフセット付きでバックバッファをサンプルするアルゴリズム
    • メインビューにおけるデータの欠落による問題
  • 問題: オクルージョン
    • バックグラウンドはサンプルされるべきだが、フォアグラウンドのオブジェクトが画像中にある。
    • バックグラウンドを再現するより、より近い深度を調査して見つけるほうがやりやすい。
    • 我々の解決法: 最小深度を見つけ、像差の計算に使用する。
      • 深度が小さいと、オフセットも小さくなる。
      • 再現にいくつかの無作為化を加える。

S3D画像生成: シェーダサンプル(S3D Image Generation: Shader Sample)

const float samples[3] = {0.5, 0.66, 1};
float minDepthL = 1.0, minDepthR = 1.0;
float2 uv = 0;

for (int i = 0; i < 3; ++i) {
    uv.x = samples[i] * MaxSeparation;
    minDepthL = min(minDepthL, GetDepth(baseUV + uv));
    minDepthR = min(minDepthR, GetDepth(baseUV - uv));
}

float parallaxL = MaxSeparation * (1 - ZPD / min DepthL);
float parallaxR = MaxSeparation * (1 - ZPD / min DepthR);

left = tex2D(backBuf, baseUV + float2(parallaxL, 0));
right = tex2D(backBuf, baseUV - float2(parallaxL, 0));

S3D画像生成(S3D Image Generation)

  • 単純でとても効率的。コンソールで約1ms。
    • 負と正の視差の、標準のステレオパラメータで動作する。
    • 全体の結果は2回レンダリングしたのとかなり似ている。
  • 非遮蔽disocclusionを扱えない。
    • 疎な輪郭を持つシーン(例えば、巨大な建物のある街のシーン)や慎重に選択されたステレオパラメータで十分うまく動作する。
    • 一人称武器のようなとても近いオブジェクトでさらに問題になる。
      • 情報の欠けたより大きなエリア
      • オブジェクトまわりに若干の後光が見える(再現されたバックグラウンド)。
  • 透明のオブジェクトで正常に動作しない。(深度バッファにない)
    • (シーン全体の深度が制限される場合、許容範囲内でどうにかして)バックグラウンドの分割を得る。
  • 左/右のスクリーンのエッジは特別な配慮considerationが必要である。
    • 例えば、画像のクロッピング。
  • 結論
    • テクニックは完璧には程遠い。
      • 多くの潜在的な問題
      • 良好な調整量が必須
    • Crysis2、とくにコンソールではとても良く受け入れられている。
      • S3Dでのビジュアル的な実現可能性を失わない。
    • アーティファクトや制限された深度範囲を我慢できるならば、選択肢となり得る。
  • いくつかのルールに配慮するのは快適な経験を生み出すのに必須である。
    • Crysis2ではすべてがスクリーンに入る。
      • window violationをできるだけしない
      • extreme refocusingの必要なし
    • depth conflictの回避
      • 知覚される3D深度はレンダリングと一致しない。
      • 例えば、クロスヘアは壁より奥にあるが、それより前にレンダリングされる。
      • とても迷惑で、ビュアーに対して不快な副次的効果を引き起こす。
  • 3D HUD
    • ワールドとの交差を避けるために3D空間に慎重に配置されるコア要素
  • クロスヘア
    • プレイヤーの前面にいるようにワールドに押し出される。
    • しばしばdepth conflictを引き起こし得る。
    • ワールドにレイをキャストして、交差を調べる。
    • 交差する場合には、滑らかに位置を適応させる。
  • あるZPDが許容できる視差分布を得るために必要とされる。
    • FPSのゲームで問題になる。
    • 武器はスクリーンの外に出るだろう。
  • 解決法
    • ステレオ画像生成中には武器をスクリーンの中へ押し込む。
    • しかし、壁に近いとdepht conflictを引き起こす可能性がある。
    • これを回避するため、近いオブジェクトを調べ、ステレオ効果を滑らかにフェードアウトするためにZPDを減らす。

おわりに(Conclusion)

  • 3.5年 ⇔ 膨大な仕事量
    • ここではごく一部のみをカバーした。
  • 次のCryENGINEは?
    • より大きく、より良く、より速く。リアルタイムでAvatarクオリティ?
      • リアルタイム用アセットを適切に行えば、そうおかしい話でもない。
    • 大きな”次世代”への一歩のためのより高速なコンソールを必要とする。
      • 大きい = FarCryからCrysis1のような、大きなビジュアル的な進歩。
      • 常軌を逸したGPUパワー量 (4x NV 590)
      • 常軌を逸したメモリ量 (>= 8GB)

Bonus Slides

HDR&線形補正(HDR & Linear Correctness)

VPOSワープ基底の計算(Computing VPOS warp basis)

float fProjectionRatio = fViewWidth / fViewHeight;  // アスペクト比

//すべての値はカメラ空間にある。
float fFar = cam.GetFarPlane();
float fNear = cam.GetNearPlane();
float fWorldHeightDiv2 = fNear * cry_tanf(cam.GetFov() * 0.5f);
float fWorldWidthDiv2 = fWorldHeightDiv2 * fProjectionRatio;
float k = fFar / fNear;
Vec3 vStereoShift = camMatrix.GetColumn0().GetNormalized() * cam.GetAsymL();

//行列の向きを適用する。
Vec3 vZ = (camMatrix.GetColumn1() * fNear + vStereoShift) * k; // vZの大きさはカメラ位置からニア面への距離
Vec3 vX = camMatrix.GetColumn0() * fWorldWidthDiv2 * k;
Vec3 vY = camMatrix.GetColumn2() * fWorldHeightDiv2 * k;
vZ = vZ - vX;
vX *= (2.0f / fViewWidth);
vZ = vZ + vY;
vY *= -(2.0f / fViewHeight);

// 基底をいずれかのローカル空間に変換する。(ここではシャドウ空間)
vWBasisX = mShadowTexGen * Vec4(vX, 0.0f);
vWBasisY = mShadowTexGen * Vec4(vY, 0.0f);
vWBasisZ = mShadowTexGen * Vec4(vZ, 0.0f);
vCamPos =  mShadowTexGen * Vec4(cam.GetPosition(), 1.0f);

再構築の幾何的な意味合い(Geometrical Meaning of Reconstruction)

シャドウアクネ(Shadow Acne)

  • 2つの主要因
    • 低いシャドウマップのテクセル密度
    • 深度バッファの精度
  • アクネに対処するさまざまなシナリオ
    • 太陽光シャドウ: 傾斜縮尺slope-scaledの深度バイアス付きで前面をレンダリングする。
    • 点ライトシャドウ: 背面レンダリングが屋内のシーンでより良く動作する。
    • 遠いLOD用分散シャドウ --- シャドウマップに両面をレンダリングする。
  • 深度バッファの精度に対処するためのディファードシャドウパス中に一定の深度バイアス

光のにじみの最小化(Minimizing Light Bleeding)

  • コンソールでは各ライトがシャドウをキャストする余裕は作れない。
  • ボックス/ボリュームをクリップする。
    • ステンシルカリングを用いてライトブリーディングを取り除くためのライティングアーティスト用ツール
    • 各ディファードライトは完全に生成されるシャドウマップを持つ必要はない。
    • アーティストは任意の凸状ボリュームを生成するかデフォルトのプリミティブを用いることができる。

ディファードデカール(Deferred Decals)

  • フォワードデカールはかなりの問題がある。
    • 追加のメモリ、メモリフラグメンテーションを引き起こすメッシュの再割り当て、動的メッシュ生成のためのCPU時間、など
  • ディファードデカールで解決![Krassnigg 2010Krassnigg, J. 2010. A Deferred Decal Rendering Technique. Game Engine Gems 271--280. https://gameenginegems.com/gemsdb/article.php?id=20.]
    • ディファードライトにかなり似ていて、デカールのボックスボリュームとしてレンダリングする。
    • ディフューズレイヤーの分割+法線マップバッファのブレンディング
    • ディフューズテクスチャのフェッチとシェーディング用減衰率の計算
    • ここではライティング/シェーディングを計算しない。
    • 静的なジオメトリのみに適用される。
  • 問題
    • デカールが法線マップを持つ場合に、タンジェント空間の結果が通常のデカールと不釣り合いになる。
    • ディファードデカールのリーク
  • リークに対する解決法
    • 調整可能なデカールボリュームとデカール減衰関数
    • シーン法線とデカールタンジェント空間法線の間の内積
      • デカールが法線マップ自身を用いる場合に問題になる。
      • X360: EDRAMにレンダリングして、常に解決済みシーン法線テクスチャに分割コピーを持つ。
      • PS3: 凸状ボリュームのラスタライゼーション中に対象の読み/書きをレンダリングする。

Footnotes

  1. 訳注:backface?

  2. 訳注:1999年はNVIDIAがGeForce 256を発売した年。

  3. 訳注:Alpha TO Coverage