Skip to content
Go back

Rendering the Hellscape of Doom Eternal

· Updated:

slides

拙訳

Hybrid binning

  • clusterベースとtileベースのライトカリングを組み合わせる
    • Drobot [2017Drobot, M. 2017. Improved Culling for Tiled and Clustered Rendering. Advances in Real-Time Rendering in Games course. ACM SIGGRAPH. https://advances.realtimerendering.com/s2017/index.html.] の“Improved Culling for Tiled and Clustered Rendering”に触発された
  • コンピュートシェーダでbinned rasterization [Abrash 2009Abrash, M. 2009. Rasterization on Larrabee: A First Look at the Larrabee New Instructions (LRBni) in Action. Game Developers Conference. https://gdcvault.com/play/1402/Rasterization-on-Larrabee-A-First.]を行う
    • セットアップおよびカリング
      • ニア面で六面体をカリングする
      • 辺とともにパッキングした頂点とエッジのインデックスをemitする
      • エッジと頂点で面の表裏を分類する
      • ニア面にある辺を取り除く
      • スクリーン空間のタイル境界を計算する
      • 粗ラスタのためのワークを生成する
    • ワークの分け方
      • スクリーン空間の四角いカバレージに基づいてカバーし得るタイルごとにラスタライゼーション・スレッドを走らせたい
      • 64タイルを[8,8,1]のスレッドグループで実行して、各スレッドがbinningされた六面体をループ処理すると、スレッド使用率が悪くなるので非常に遅い
      • 代わりに、カバーし得るタイルごとにスレッド1つを走らせる
    • 粗ラスタcoarse raster
      • 粗タイル1つで256x256ピクセル
      • クラスタにもbinningする
      • 細ラスタのためのワークを生成する
        • 六面体と交差する粗タイルに対してワークを生成するだけ
        • カバーし得る細タイルごとにスレッド1つ
        • 粗タイルごとに独自のワークリストがあり、タイルごとにスクリーン空間の境界が決まる
    • 細ラスタfine raster
      • 細タイルごとに32x32ピクセル
      • 保守的なmin/maxデプスバッファダウンサンプリングによるリジェクションを行う
      • タイルごとに六面体に対する最大および最小深度値をCSで計算する
      • ポイントライトでは、球をタイル錐台でカリングする工程を挟む
    • ビットフィールドを解いてリストへ
      • タイル/クラスタごとにスレッドグループ1つで解く
      • スレッドグループ1つに64ビット、スレッドあたり1ビットをチェックする
      • タイル/クラスタごとに(maxLights + 63) / 64回繰り返す
      • コンパクションのためサブグループ命令を使う
  • ライトリストを選択する
    • 深度の不連続性が大きいと、細タイルは上手くいかない
    • クラスタとタイルの両方で行って、エントリ数の少ないリストの方を使う
  • ハッシュのスカラー化
    • 前作と同様にライトデータのスカラー読み出しをやりたいが、以前より細かくbinningされているのが問題になる
    • リストごとにライトのインデックスのハッシュをCSで計算する
    • 24ビットのハッシュと8ビットのタイル/クラスタ毎ライト数を格納する
    • ハッシュ値でuniformityを確認する
    • fragment thread groupがクラスタおよびタイルリストを使用しても機能する

Geometry Decals

  • ジオメトリによって定義される小さなデカール
    • ワールド空間からテクスチャ空間への投影行列(float2x4)を使う
    • ディスク上では、オブジェクト空間からテクスチャ空間への行列として保持する
      • モデル行列をかけて、ワールド→テクスチャ行列を得る
    • 各インスタンスが自身のデカールに関するメモリを必要とする
  • R8バッファにインデックスをレンダリングする
    • ポストデプスパスで、GREATER_EQUAL比較する
    • Z-fightingを回避するため、深度バイアスを付ける
    • デカールは共面coplanarである必要がある
  • フラグメントシェーダでサブメッシュごとにprojectionリストをインデックス付けする
    • リストはインスタンスのデスクリプタセットにバインドされる
    • Gバッファを通らないので、任意のブレンディングが使える
  • 制限
    • projectionはサブメッシュあたり254個まで
    • デカール1つにprojectionが複数必要になることもある
    • 曲面では上手くいかない
    • インスタンスごとにprojection用ストレージが必要になる
      • 現時点では、レベルごとに最大で1M個
    • デカールは常に最前面にbinningされる
    • アニメーションするジオメトリのprojectionは毎フレーム計算される

Geometry Caches

TODO

Material Blending

TODO

GPU Triangle Culling

  • [Wihlidal 2016Wihlidal, G. 2016. Optimizing the Graphics Pipeline With Compute. Game Developers Conference. https://gdcvault.com/play/1023109/Optimizing-the-Graphics-Pipeline-With.]に似た背面・錐台・微小トライアングルのカリングを行う
  • UmbraのSWバッファから深度ミップチェインを生成して、オクルージョンカリングを行う
  • 標準的なCPUカリングも追加で行う

GPU Geometry Merging

  • 要件
    • ジオメトリをマージするには、PSOを同じくする
    • シェーダリソースを番号で参照できるようにする
      • 頂点データは単一のプールから割り当てる
      • テクスチャはグローバルなデスクリプタ列で管理する
      • 定数バッファはレイアウトごとにプールを1つ
        • ゲーム中にあるレイアウトはワールド用、キャラクター用、ジオメトリキャッシュ用の3つのみ
  • カリング
    • CPUでシーンを探索して、GeometrySetを作る
      • GeometrySetあたり、PSOを同じくするメッシュを最大256個
      • 間接インデックスバッファを事前に確保する
    • GeometrySetごとにカリング処理を1回ディスパッチする
    • 生き残ったトライアングルをマージした間接インデックスバッファに出力する
      • 頂点IDとインスタンスIDをまとめて32ビットのインデックスとする
      • レンダリング時にインスタンスデータをフェッチできるようにする
  • レンダリング
    • GeometrySetごとにドローコール1つ
    • インデックス値から頂点IDとインスタンスIDを取り出す
    • インスタンスIDを使ってすべてのインスタンスプロパティを計算する
      • 頂点プールにおけるベースオフセット
        • 頂点属性に変わってバッファをフェッチする
      • インスタンスの定数バッファのオフセット
        • マテリアルデータやテクスチャ番号を含む
    • divergentなテクスチャ/バッファのフェッチはスカラな繰り返しになる
      • NonUniformResourceIndex
    • マージ可能なシェーダバリエーションはコンパイラによって自動的に生成される
  • 詳細
    • カリング・マージ処理は、シャドウ前に、非同期に実行される
      • GeometrySetごとに同期を取るので、カリングと描画がオーバーラップすることもある

Gore System

SUSPENDED

Water Rendering

  • “Simulating Ocean Water” [Tessendorf 2001Tessendorf, J. 2001. Simulating Ocean Water. Simulating nature: realistic and interactive techniques. SIGGRAPH 1, 2, 5. https://people.computing.clemson.edu/~jtessen/reports/papers_files/coursenotes2002.pdf.]に従ってディスプレイスメントマップとノーマルマップを生成する
  • “Real-Time Water Rendering, Introducing the Projected Grid Concept” [Johanson 2004Johanson, C. 2004. Real-time water rendering - introducing the projected grid concept. https://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/.]
    • スクリーン空間のグリッドを水面に投影する
      • スクリーン空間のグリッドと同じサイズで水面の深度画像をレンダリングする
    • ワールド空間でグリッドの頂点をディスプレイスする
      • 深度画像にディスプレイスメントマップを適用して、グリッド頂点のワールド位置の画像(頂点画像)を作る
      • 頂点画像にTAAを適用する
    • グリッドをラスタライズして水面をレンダリングする
      • 頂点画像を使ってスクリーン空間のグリッドメッシュをラスタライズして、深度と法線を含むGバッファを作る
      • Gバッファを使って水面のSSRを計算する
      • 水面をライティングする
      • 水面の内外でピクセルを分けたバッファを作り、半透明をその深度に応じたバッファの方にレンダリングする
        • 水中にレンダリングするときはアルファを追加情報として残しておく
      • [Sousa 2008Sousa, T. 2008. CRYSIS Next-Gen Effects. Game Developers Conference. https://www.gdcvault.com/play/247/CRYSIS-Next-Gen.]のdistorted texcoord lookupで水中バッファを歪ませて最終結果を合成する
  • 接する水のシミュレーション
    • “Fast Water Simulation for Games Using Height Fields” [Müller-Fischer 2008Müller-Fischer, M. 2008. Fast Water Simulation for Games Using Height Fields. Game Developers Conference. https://gdcvault.com/play/203/Fast-Water-Simulation-for-Games.]
    • カメラを中心にしたグリッドでシミュレーションを行い、トップダウン的に投影する [Sousa 2011Sousa, T. 2011. CryENGINE 3 Rendering Techniques. Gamefest. https://www.slideshare.net/slideshow/cryengine-3-rendering-techniques/8766164.]
      • カメラが動いたら、前フレームのハイトフィールドをフェッチするときにテクスチャ座標を再投影する
      • グリッドのセルサイズの倍数にグリッド位置をあわせることで、再投影のエイリアシングを回避する
      • すべての水面に対して512x512のグリッド1つ
    • 出来上がったハイトフィールドは水の頂点に追加のディスプレイスメントとして加えられる
  • コースティクス
    • コースティクス画像をディスプレイスメントマップから生成する
    • ディスプレイスメントマップに沿ったグリッドメッシュをラスタライズして、ある一定の距離の屈折をシミュレーションすることで各頂点を摂動させる
    • 出来上がったコースティクス画像は次のフレームで使って、水中や直上のジオメトリに投影する
  • 水流
    • 流れる水面をGバッファに直接ラスタライズする
    • 流れる水面の法線は法線マップとアーティストが作ったフローマップで摂動させる
    • 流れる水面にはディスプレイスメントは適用していない(改良の余地あり)