335.3K Views
August 24, 22
スライド概要
講演動画:https://youtu.be/ZM96Anj-u3I
Unreal Engine 5と同時に公開されたサンプルプロジェクト「City Sample」では、様々な機能の最適化が行われています。今回は描画関連の機能を中心に機能紹介や最適化のための設定を紹介させて頂きます。
https://cedec.cesa.or.jp/2022/session/detail/228
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
Unreal Engine 5 City Sampleからみる描画の最適化 Epic Games Japan Yutaro Sawada
目次 ・City Sampleとは ・機能紹介 ・City Sampleの最適化 ・開発Tips
目次 ・City Sampleとは ・機能紹介 ・City Sampleの最適化 ・開発Tips
City Sampleとは ・本講演では、Unreal Engine 5と同時に公開されたCity Sampleを用いて、 活用されている機能や最適化について紹介 ・City SampleはUE5の機能をフル活用したサンプル
City Sample Epic Games Launcherからダウンロードが可能 Unreal Engine -> サンプル以下に
City Sample 最初はSmall Cityをおすすめ Content -> Map -> Small_City_LVL 正しく表示されない場合 ・GPUドライバを更新
City Sample 約15平方キロメートルの オープンワールドの街 各アセットは数百万ポリゴン 建物だけでも数十億ポリゴン
City Sample 実現するための... ・Lumen ・Nanite ・Virtual Shadow Map ・World Partition …等
本講演で伝えたい要点 UE5の描画周りの新機能はNaniteがキーとなっているため、 できるだけNaniteアセット化することをおすすめ
目次 ・City Sampleとは ・機能紹介 ・City Sampleの最適化 ・開発Tips
Nanite
Naniteが実現すること 仮想化ジオメトリ ・メッシュをクラスタという単位に分割し階層構造を構築する ・クラスタ単位でLODのように描画メッシュを切り替える ・必要なデータのみをメモリに送るようにストリーミング
Naniteが実現すること ポイント ・高精細なメッシュから欲しい必要な詳細度で描画 ・独自のソフトウェアラスタライザとレンダリングパイプラインにより マルチビューで描画可能
Naniteの有効化 NaniteはStatic Mesh毎に有効化可能 (戻すことも可能)
Nanite ツール ・Naniteを一括設定する ・上部のツールメニューからNaniteツールを選択
Nanite ツール - 最適化 指定ポリゴン数を超えるStatic Meshをリスト化 Nanite化可能なメッシュをフィルタリング (Pixel Depth Offsetを使ってない等)
Nanite ツール - エラータブ Materialエラーが発生しているものを一覧化 エラーを確認したり、Naniteを無効化することが可能
クラスタの作成などのアルゴリズムについて Nanite | Inside Unreal A Deep Dive into Nanite Virtualized Geometry https://www.youtube.com/watch?v=TMorJX3Nj6U https://www.youtube.com/watch?v=eviSykqSUUw
Lumen
Lumenが実現できること 動的なGI:間接光の表現や、リフレクション
従来 Lightmass等でライトを焼き付ける(ライトビルド)必要があった -> 試行錯誤する場合、この処理は非常にコストがかかる
Lumenの基本的な設定 ・プロジェクト設定 - エンジン - レンダリングに含まれる ・ダイナミック グローバルイルミネーション メソッド を Lumen ・反射メソッド を Lumen ・メッシュ距離フィールドの生成 ☑有効化
Lumenの2つのステップ 1. シーン全体の照明情報を作るLumen Sceneを生成 2. Lumen Sceneからライティング情報を取得する
Lumen Scene について 1. メッシュを囲むカードを生成 2. カードにMaterial 情報などを書き出す- Surface Cache 3. カードで構成されるシーンで照明計算を行う
Lumen Scene について Surface Cacheから照明計算が行われたものを元に、 メッシュまたはディスタンスフィールドを表示-> Lumen Scene
Lumen Scene のトレース (1) ソフトウェアレイトレーシング トレースにディスタンスフィールドを利用 (2) ハードウェアレイトレーシング トレースにメッシュを利用(対応GPUが必要)
Lumenの一連のフローについて https://www.docswell.com/s/EpicGamesJapan/5EV87K-UE5_Lumen101
LumenはNanite Meshと相性が良い ・Lumen SceneはNanite Meshにより効率的に構築可能
Lumen Scene構築 - Card Captureの流れ r.LumenScene.SurfaceCache.CardCaptureRefreshFraction=1(デフォルト:0.125) コンソールコマンドを実行したあとRenderDocでキャプチャ
Lumen Scene - Card Captureの場所 ・Scene ->Lumen Scene Update -> MeshCardCapture
Lumen Scene構築 - Lumen Card r.Lumen.Visualize.CardPlacement 1 Cardの可視化
非Nanite Meshの場合
非Nanite Meshの場合
非Nanite Meshの場合
非Nanite Meshの場合
Lumen Scene - Card Captureまとめ Naniteメッシュの利点(1) ・マルチビュー描画により、ドローコールが減る
Lumen Scene - Card Captureまとめ Naniteメッシュの利点(2) ・欲しい詳細度のメッシュで描画が行える 現状すべてがNanite化できる状態ではないので、、、 非Naniteの場合はLODモデルの設定が重要
Lumen Scene - Card Captureまとめ Naniteメッシュの利点 ・マルチビュー描画により、ドローコールが減る ・欲しい詳細度のメッシュで描画が行える ハイポリなメッシュではなくてもNanite化は効果的
Lumen向けメッシュについて 例えば建物を1メッシュで作ってしまったりすると、、、 メッシュを囲むカードが上手く生成できないため不向き 壁、天井などそれぞれパーツを分割することをお勧め 壁、床、天井をマージした状態の屋内のLumen Scene 壁、床、天井が分かれている状態の屋内のLumen Scene
Virtual Shadow Map
Virtual Shadow Map ライトによって多少異なりますが、 基本はタイル状に並べた高解像度のシャドウマップを使用することで品質を向上 仮想テクスチャのように、必要な時に必要な箇所を更新、利用する
Virtual Shadow Map - Nanite Lumenと同様に、Naniteの特性と相性が良くNanite Meshの描画が非常に高速
Virtual Shadow Map - Nanite比較 椅子を1個配置 Shadow Depthの比較 ・非Nanite Mesh 約 0.41 ms ・Nanite Mesh(キャッシュ無効化) 約 0.65 ms ・Nanite Mesh(キャッシュ有り) 約 0.61 ms GeForce RTX 3070計測
Virtual Shadow Map - Nanite比較 椅子を1個配置 Shadow Depthの比較 ・非Nanite Mesh 約 0.41 ms ・Nanite Mesh(キャッシュ無効化) 約 0.65 ms ・Nanite Mesh(キャッシュ有り) 約 0.61 ms GeForce RTX 3070計測
Virtual Shadow Map - Nanite比較 椅子を1万個配置(ドローコールはまとめられている) Shadow Depthの比較 ・非Nanite Mesh 約 4.42 ms ・Nanite Mesh(キャッシュ無効化) 約 1.33 ms ・Nanite Mesh(キャッシュ有り) 約 0.69 ms GeForce RTX 3070計測
Virtual Shadow Map - Nanite比較 非Nanite Meshの場合のProfile結果を見てみると...
Virtual Shadow Map - Nanite比較 椅子を1個配置 椅子を1万個配置 Shadow Depthの比較 ・非Nanite Mesh 約 0.41 ms Shadow Depthの比較 ・非Nanite Mesh 約 4.42 ms ・Nanite Mesh(キャッシュ無効化) 約 0.65 ms ・Nanite Mesh(キャッシュ無効化) 約 1.33 ms ・Nanite Mesh(キャッシュ有り) 約 0.61 ms ・Nanite Mesh(キャッシュ有り) 約 0.69 ms
World Partition
World Partition 大きなマップを構築するためのレベルストリーミングシステム
World Partition - セルで管理
World Partition - HLOD
World Partition - HLOD
目次 ・City Sampleとは ・機能紹介 ・City Sampleの最適化 ・開発Tips
City Sample
メモリの問題 ・大きく問題となっていたのは使用メモリ ランタイムで25GB以上 ・当初PCのみで検証されていたため コンソールなどを考えた時に問題に ・理由 新機能は開発段階 映画品質のアセット 非常に多くのインスタンス ・様々な方法でメモリの削減が行われた
大量のインスタンス 全てのビルは複数の小さなインスタンスで構成 最終的な数値: 街全体で 700万のNaniteインスタンス あるタイミングでは、150万のNaniteインスタンスがロード World Partitionによってストリームイン&アウト 積極的なカリングの後でも、 レイトレーシングのシーン内には10万を超えるインスタンス このようなインスタンス数の場合のメモリ消費例: インスタンス毎に1byte追加しただけで全体で 1.5MB の増加に! Single float4x4をインスタンス毎に追加すると 100MB の増加に!
インスタンスデータ毎の最適化 FPrimitiveInstance のデータをパッキング インスタンス毎のパッキング 385 bytes (UE5.0 EA) から 48 bytes (UE5.0 リリース)に 一部データは他のオブジェクトへ移行 可能な限りGPU Sceneのトランスフォームデータを再利用 最終的なデモでは 500MB のメモリ削減 FPrimitiveInstance Size Original Size 385 Instance Count MBs 1,500,000.00 551 Removed 4x4 -> 4x3 321 1,500,000.00 459 Removed Sign Bit Float 317 1,500,000.00 453 Removed Sphere Radius x2 309 1,500,000.00 442 Removed NaniteInfo 304 1,500,000.00 435 Removed Primitive ID 300 1,500,000.00 429 Removed RenderBounds 276 1,500,000.00 395 Removed LocalToWorld 228 1,500,000.00 326 Removed PrevLocalToWorld 180 1,500,000.00 257 Removed NonUniformScale 164 1,500,000.00 235 Removed InvNonUniformScale 152 1,500,000.00 217 Removed SceneFrameNumber 148 1,500,000.00 212 Removed LightMapAndShadowMapUVBias 132 1,500,000.00 189 Removed PerInstanceRandom 128 1,500,000.00 183 Removed PreLocalToPrimitive 80 1,500,000.00 114 Removed LocalBounds 56 1,500,000.00 80 Removed NaniteHierarchyOffset 42 1,500,000.00 60 Removed Flags 48 1,500,000.00 69
Lumen では ハードウェアレイトレーシングを使用 (1) ソフトウェアレイトレーシング トレースにディスタンスフィールドを利用 ”古代の谷”で使用 (2) ハードウェアレイトレーシング トレースにメッシュを利用(対応GPUが必要)
Lumen - ディスタンスフィールド ディスタンスフィールドの消費メモリが非常に多い メッシュ ディスタンスフィールド
Lumen - ディスタンスフィールドの削減 ディスタンスフィールドを削りメモリを削減(900MB 以上のメモリ改善) r.DistanceFields.SupportEvenIfHardwareRayTracingSupported=0 メッシュ ディスタンスフィールド
Lumen - Cardについて Lumen Sceneはオブジェクトから作られるカードを元に構築 枚数が多いと消費メモリや更新頻度に影響
Lumen - Cardのマージ 建物はInstanced Meshで構築 すべてが個別にCardを生成すると 対象数が莫大に増えてしまう
Lumen - Cardのマージ Ray Tracing Group IDを基準にマージ 建物全体を囲むようなカードを用意
Lumen - Cardのマージ r.LumenScene.SurfaceCache.MeshCardsMergeComponents 1
Lumen - Cardのマージの効果 r.LumenScene.SurfaceCache.MeshCardsMergeComponents 0 r.LumenScene.SurfaceCache.MeshCardsMergeComponents 1 出力コマンド r.LumenScene.DumpStats 1
Lumen - Cardのマージの効果(メモリ) r.LumenScene.SurfaceCache.MeshCardsMergeComponents 0 r.LumenScene.SurfaceCache.MeshCardsMergeComponents 1
Lumen - Group IDによるカリング Ray Tracing Group IDのマージによってカリングも最適化 r.RayTracing.Culling.UseGroupIds 1
Lumen - Lumen SceneのカードLOD Lumen SceneのカードもLODを保持(0と1) ・LOD0は、ほぼBouding boxのような6枚で構成 ・LOD1は、カードの上限値に合わせて生成 r.LumenScene.SurfaceCache.MeshCardsMaxLOD 枚数は更新頻度やメモリに影響
Lumen - Lumen SceneのカードLOD r.LumenScene.SurfaceCache.MeshCardsMaxLOD 1 r.LumenScene.SurfaceCache.MeshCardsMaxLOD 0
Lumen - Lumen SceneのカードLOD(メモリ) r.LumenScene.SurfaceCache.MeshCardsMaxLOD 1 r.LumenScene.SurfaceCache.MeshCardsMaxLOD 0
Lumen - Far Field LumenSceneを構築する際に遠景にHLODを活用 Naniteメッシュ Far Field https://docs.unrealengine.com/5.0/ja/lumen-technical-details-in-unreal-engine/#%E3%83%95%E3%82%A1%E3%83%BC%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89
Lumen - Far Field
Lumen - Far Field関連の設定 Lumen Sceneの距離 ・ポストプロセスボリューム内 - Max Trace Distance デフォルト:20000 (200m) Far Fieldの距離 ・コンソールコマンド r.LumenScene.FarField.MaxtraceDistance デフォルト:100000 (1km) Lumen Sceneに含める基準 ・ポストプロセスボリューム内 - Lumen Scene Detail デフォルト: 1 カードの更新頻度 ・コンソールコマンド r.LumenScene.SurfaceCache.CardCaptureRefreshFraction デフォルト: 0.125
Ray Tracing r.RayTracing.NonBlockingPipelineCreation r.RayTracing.Culling r.RayTracing.Culling.Radius r.RayTracing.Culling.Angle Render/RHI Threadを止めずに裏でレイトレ用パイプラインを生成、シェーダ生成など間に TRUE 合ってない場合は真っ黒になるが、ヒッチは起きない 3 一番アグレッシブなカリング方法。距離と視界からの大きさでカリングをする 15000 City Sample向けにチューニング150m以上奥のオブジェクトをカリング 0.5 City Sample向けにチューニング、デフォルトより小さいオブジェクトのみカリング r.RayTracing.Culling.UseGroupIds 1 レイトレ内でグループ(ID)となっているものがあれば、それ単位でカリング r.RayTracing.Geometry.NiagaraRibbons 0 高速化のためNiagaraをレイトレ界から省く r.RayTracing.Geometry.NiagaraSprites 0 高速化のためNiagaraをレイトレ界から省く r.RayTracing.Geometry.NiagaraMeshes 0 高速化のためNiagaraをレイトレ界から省く r.RayTracing.ExcludeTranslucent r.RayTracing.Geometry.InstancedStaticMeshes TRUE 高速化のため半透明オブジェクトもレイトレ界から省く 0 InstancedStaticMeshも省く
Virtual Textureの活用 可視化コマンド r.VT.Borders 1 r.VT.Flush
Virtual Texture r.VT.MaxUploadsPerFrame r.VT.MaxUploadsPerFrameInEditor r.VT.MaxTilesProducedPerFrame 500 ほぼ全てのテクスチャがVTとなったため、Default: 8から大幅に拡大 1000 ほぼ全てのテクスチャがVTとなったため、Default: 32から大幅に拡大 100 ほぼ全てのテクスチャがVTとなったため、Default: 30から大幅に拡大 r.VT.MaxReleasedPerFrame 5 一フレーム内でのVTの削除を最大5毎に制限 r.VT.NumGatherTasks 6 VT更新リクエストを集めるタスク数を5つに (Default: 1) r.VT.SyncProduceLockedTiles VTのRootPage読み込みを必ず待つ。 0 (待たない場合、間に合わなければ単色の色にフォールバックする ) r.VT.IOPriority_HighPagePri 4 読み込み優先度を高く r.VT.CsvStats 2 CSVProfilerにVTのVerbose情報も出す
Virtual Textureの仕組みについて [UE] Virtual TextureとそのStreamingの仕組み、またよく頂く質問への回答 https://qiita.com/EGJ-Nori_Shinoyama/items/4a2e84dd1d3448e81bed
動的なオブジェクト - 車 車 直前まではNaniteメッシュで、必要な時Skeletal Meshに置換え
動的なオブジェクト - 群衆 群衆 LODによって切り替え ・近いものはSkeletal Mesh ・遠方はStatic Meshで描画 (アニメーション情報はテクスチャにベイク) ベイク用ツール:AnimToTexture Plugin これらはMass Frameworkによって挙動を管理
MassFrameworkについて
その他リソースの最適化 最適化のために持っている複数のBufferを無効化 Reversed index buffers: r.SupportReversedIndexBuffers=False Depth only index buffers: r.SupportDepthOnlyIndexBuffers=False Initial pose, skin weights, cloth, color, …: r.FreeSkeletalMeshBuffers=1 400MB 以上のメモリ削減 今後のエンジンバージョンアップでデフォルト設定にしようと検討中
City Sampleの最適化まとめ ・インスタンスが非常に多い ・Lumen SceneのカードにはNaniteアセットが最適 ・カードは多いほど更新頻度が低くなってしまう -> マージやLODの削減、対象範囲の調整にってカードを削減
目次 ・City Sampleとは ・機能紹介 ・City Sampleの最適化 ・開発Tips
開発Tips
Naniteフォールバックメッシュ生成の改善 プロキシメッシュ -> フォールバックメッシュという名称の変更 (Naniteが利用できない環境や、レイトレ時に使われるメッシュ) ・EA版でフォールバックメッシュを作成する際のパラメータは、 Proxy Triangle Percent(プロクシ三角比率) 元メッシュから何%の三角形を残すかといった値 デフォルト値:0の場合 三角的の数が2000以下になるように調整
NaniteフォールバックメッシュのEA版の動作 ・Proxy Triangle Percent(プロクシ三角比率)を変えた時のEA版の動作 100.0%の場合 - 元メッシュ(百万ポリゴン) 10.0%の場合- 元メッシュの10%の三角形にする(十万ポリゴン) 0%の場合、2000ポリゴン
Fallback Relative Errorパラメータの追加 ・5.0 - Fallback Relative Error(相対誤差)が追加 ・表面積を扱うパラメータ ・重要度が低いところから削除 ・メッシュの密度を保ちつつ削減
Fallback Relative Errorの利点 三角形の%指定だと、ハイポリ、ローポリモデルでそれぞれ調整が必要 例:シーン上同程度の大きさのモデルでポリゴン数に差がある場合で、 同程度のポリゴン数にしたい場合の極端な例 1% 100万ポリゴンモデル 1万ポリゴンモデル 10万ポリゴンモデル 1万ポリゴンモデル 10%
Fallback Relative Errorの利点 ・Fallback Relative Error 同じサイズの同一パラメータの場合、 同程度のポリゴン数(密度)のメッシュを生成可能 1% 100万ポリゴンモデル 約1万ポリゴンモデル 10万ポリゴンモデル 約1万ポリゴンモデル 1%
Megascansの実際のデータ ・Fallback Relative Error:どちらもデフォルト値 1.0 150万 tris -> 16647 tris 100万 tris -> 16708 tris
Fallback Triangle Percent 以前のパラメーターも設定可能(何%の三角形を残すか) EA版ではデフォルト0(下限2000 tris)のところ、 5.0ではRelative Error設定を想定し、デフォルトが100%に
ディスク上のNaniteメッシュ縮小化機能 Naniteメッシュ本体も前項のRelative ErrorとTriangle Percentで調整可能 (Naniteメッシュをリダクションし、パッケージ化する時にサイズ削減が可能)
Unreal Insights - メモリプロファイリング Unreal Insightsでメモリプロファイリング UE5.0から、PC及びコンソール上で動く ・UE5.0.3(Windows)で問題を確認しており修正対応中 有効化には次の引数 -trace=default,memory -tracehost=<ip_address>
RenderGraph Insights Plugin RenderGraph Insights pluginでRenderGraphの挙動を確認可能に 各種スコープ、パス、そしてリソースを表示 Render Threadと同時に表示すると分かりやすい 有効化には次の引数 -trace=rdg,defaults
VRAM Memory - StatsとDump Toolsを改善 Statsのコマンド stat d3d12resources stat d3d12memorydetails stat d3d12bufferdetails RHI resource memoryをCSVにダンプ rhi.DumpResourceMemory all -csv
まとめ
まとめ City Sampleは非常に有用なサンプル UE5の描画周りの新機能はNaniteがキーとなっているため、 できるだけNaniteアセット化することをおすすめします