63.

UE5 シェーダコンパイルを高速化(DDC 共有 / スレッド数 / プレビュー品質 / マテリアル軽量化)

編集
この記事の要点
  • UE5 のシェーダコンパイルはマテリアルの組み合わせ爆発で重くなる。複数の最適化を組み合わせて短縮する
  • DDC (Derived Data Cache) を共有: チームでネットワーク DDC を立てて同じコンパイル結果を再利用
  • スレッド数を最大化: BaseEngine.iniNumUnusedShaderCompilingThreads を調整。CPU コア数を使い切る
  • 不要なシェーダ順列を減らす: マテリアルの Usage を必要な分だけ ON、Quality Switch を活用
  • プレビュー品質を下げる: Engine Scalability Settings を Low に — 開発中の作業効率が大幅向上
  • 最初の起動は仕方ない — 一度コンパイルが終わればキャッシュされ、以後は差分のみ再ビルド

なぜシェーダコンパイルが重いのか

UE5 はマテリアル 1 つに対して数十〜数百のシェーダ順列を生成します。マテリアルが使うライト・スタティック/スケルタル・パーティクル・モバイル/PC・LOD など、使用状況の組み合わせごとに別シェーダになるため、プロジェクトが大きくなるほど指数的に増えます。

初回起動・エンジンバージョンアップ・大量アセットインポート時に「シェーダをコンパイル N 個」が表示され、数千〜数万のコンパイルで数十分〜数時間止まる、という現象が発生します。本記事では実効性の高い短縮テクニックを優先度順に解説します。

対策1: スレッド数を最大化(最効果)

UE5 はデフォルトでコンパイルを並列化していますが、CPU を 100% 使い切らない設定になっています。Config/BaseEngine.ini または Config/DefaultEngine.ini を編集して全コア使用に変更します。

[DevOptions.Shaders]
; 未使用スレッド数を 0 にして全コア使い切る
NumUnusedShaderCompilingThreads=0
NumUnusedShaderCompilingThreadsDuringGame=1

; 同時コンパイル数の上限を上げる
MaxShaderJobBatchSize=50

; メモリ使用量(GB)。十分なメモリがあれば上げる
WorkerProcessPriority=1

16 コア機なら未使用 0 で 16 スレッド全部使えます。エディタ操作にひっかかりが出る場合は 1〜2 残します。

対策2: DDC (Derived Data Cache) を共有

シェーダコンパイル結果は DerivedDataCache/ に保存され、同じシェーダはキャッシュから即取得されます。チームで共有 DDC を立てるとメンバー全員のコンパイル時間が激減します。

; Config/DefaultEngine.ini
[DerivedDataBackendGraph]
; ネットワーク共有 DDC を使う
Shared=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false,
        Path=//fileserver/UE5_DDC, EnvPathOverride=UE_SharedDataCachePath)

個人開発でも、ローカルの DDC を SSD に置く、容量を 200GB 程度確保するだけで効果があります。Epic はUnrealCloudDDC(自社ホスト)も公式提供しており、規模が大きいなら導入価値があります。

対策3: マテリアルの Usage を絞る

マテリアル詳細パネルの Usage 欄に「スタティックメッシュで使う」「スケルタルメッシュで使う」「パーティクルで使う」などのチェックがあり、ON にした分だけシェーダ順列が増えます

Usage 項目有効にすべきタイミング
Used with Static Lighting静的ライトベイクするマテリアル
Used with Skeletal Meshキャラ・アニメ付きメッシュに貼る場合のみ
Used with Particle Spritesパーティクルに使うときのみ
Used with NiagaraNiagara で使うときのみ
Used with Instanced Static MeshesFoliage/HISM で使うときのみ

使わない用途は必ず OFF。これだけで初回コンパイル時間が半減することがあります。

対策4: プレビュー品質を下げる

エディタ右下のSettings → Engine Scalability Settings → Low に下げると、Lumen / Nanite / VSM の最高品質シェーダ順列をスキップでき、作業中の再コンパイルが大幅に短縮されます。

仕上げ確認時だけ Epic に戻すワークフローが効率的。または Material Quality を Medium にして開発、ライティングビルド前だけ High に切り替え。

対策5: Material Layer / Material Function を活用

機能を Material Function や Material Layer に分割すると、同じ計算を複数マテリアルで共有でき、結果としてシェーダの重複コンパイルを減らせます。

逆に、1 つのアンバーマテリアル(Master Material)に Static Switch / Quality Switch を山ほど詰め込むと、組み合わせ爆発で順列が暴増するので機能ごとに分割するのが正解。

対策6: r.ShaderPipelineCache を活用

パッケージビルドした際のシェーダパイプラインキャッシュを録画しておくと、ユーザー起動時に必要シェーダを事前にコンパイルできます。プレイ中のヒッチを防ぐテクニック。

# プロジェクト設定 → Packaging → Shader Pipeline Cache を有効化
# テストプレイして PSO(パイプラインステートオブジェクト)を録画
# ビルドに含めてユーザー初回起動時にプリコンパイル

その他のコツ

  • NVMe SSD を使う: DDC のランダムアクセス性能が直結。HDD は致命的に遅い
  • メモリ 32GB 以上: シェーダコンパイラ 1 つあたり数百 MB 使う。スレッド数 × この量必要
  • 不要な Material Instance を削除: マスターと違うパラメータがなければ別シェーダ順列になる
  • Translucent / Refractive はコスト大: 不透明(Opaque)で済むなら Opaque に
  • Niagara のマテリアル使い回し: 共通マテリアルを ParameterCollection で色だけ変える

コンパイル進捗の見方

右下のシェーダコンパイルインジケータをクリックすると、残り順列数とジョブ詳細が見えます。どのマテリアルが時間を食っているかも分かるので、的を絞った最適化が可能。

FAQ

Q: コンパイル中にエディタが固まる
A: NumUnusedShaderCompilingThreads を 1〜2 に上げてエディタ用の余剰スレッドを確保。

Q: 同じプロジェクトを再起動するたびに再コンパイル
A: DDC が消えている。Saved/DerivedDataCacheEngine/DerivedDataCache がワークスペースクリーンで消されていないか確認。

Q: モバイル向けの順列が多すぎる
A: プロジェクト設定 → Platforms → Mobile で対象 OS を絞る、または開発中は Mobile プレビューをオフ。

Q: Lumen / Nanite は重い?
A: 重い。使う場面だけ ON。プロジェクト全体で有効にすると全マテリアルに Lumen 順列が増える。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 床の上に乗ったらイベントを発生させる方法
  2. OverlapAllDynamicとOverlapAllの違い
  3. タイトル画面を作る方法
  4. サードパーソンテンプレートでのキャラクター表示の仕組みと非表示にする方法
  5. ボタンに文字を記載する方法
  6. Event ActorBeginOverlapとOn Component Begin Overlapの違い
  7. キャラクターに特定のオブジェクトとの当たり判定を付ける
  8. 特定のオブジェクトに触れたとき、キャラクターが倒れるようにする
  9. 動いているオブジェクトに静止しているキャラクターが当たり判定を持たない原因と解決方法
  10. 「On Component Hit」に「Cast To ~」で複数のクラスを指定する方法
  11. Blenderファイルをインポートする方法
  12. 鏡を作成する方法
  13. レベルブループリントでキャラクターの出現を設定する方法
  14. サードパーソンテンプレートにおけるキャラクター出現の定義
  15. アイテムに近づいたらボタンを押してイベントを発火させる方法
  16. 画面の中央にメッセージを表示する方法
  17. どこからでも呼び出せるカスタムイベントを作成する方法
  18. カスタムイベントに引数を追加する方法
  19. 「Get Overlapping Actors」から特定のクラスの場合のみ処理を実行する方法
  20. オブジェクトに近づいている間だけメッセージを表示する方法
  21. PCの画面を操作するUIを作る方法
  22. コンテンツブラウザに画像を追加する方法
  23. SetInputMode_UIOnlyを取り消す方法
  24. 特定の画像の上にマウスカーソルを置いたら手マークにする方法
  25. オブジェクトがアウトライナーで選択できない原因と解決策
  26. PlayerStartを作成する方法
  27. メニュー画面を作成して開く方法
  28. 「Esc」キーを押してメニュー画面を開く方法
  29. イベントの「On Clicked」と「On Pressed」の違い
  30. 「Set Input Mode」の種類と使い方
  31. 「Set Game Paused」の使い方と詳細解説
  32. Motion Matchingとは?
  33. 「GameMode」と「GameModeBase」の違い
  34. マップに配置したTargetPointを取得する方法
  35. TargetPointにタグをつけて取得する方法
  36. Spawnしたインスタンスがイベントを実行する方法
  37. 特定の時間ごとに処理を実行する方法
  38. 数値をランダムで出力する方法
  39. ThirdPersonテンプレートでキャラクターの移動を歩くように変更する方法
  40. MaxWalkSpeedを変更する方法
  41. しゃがむ動作を導入する方法
  42. キャラクターのアニメーションを設定する方法
  43. 導入済みのプラグインを確認する方法
  44. Motion Matchingの導入と必要なプラグイン
  45. プレイヤーを非表示にする方法
  46. カメラを傾ける角度を制限させる方法
  47. 配列からランダムに重ならない要素を特定の数取得する方法
  48. カメラの映す画面に文字やエフェクトを付ける方法
  49. キャラクターやメッシュを非表示にした際にカメラが移動しなくなる問題の解決方法
  50. プライマリーデータアセットを活用する方法
  51. プレイヤーのHPといった変数を定義する最適な場所
  52. カメラに映った画面をスクリーンショットとして保存する方法
  53. ゲーム内のカメラ映像を保存して再表示する方法
  54. HighResShot を使って高解像度の画像を保存する方法(UE5)
  55. HighResShotで保存した画像のファイル名を取得する方法
  56. SceneCapture2DとFrameGrabberの画像保存方法の比較
  57. SceneCapture2Dを使用して画像を保存・取得する方法
  58. HighResShotとTake High Res Screenshotの違い
  59. ゲーム終了ボタンを作成する方法
  60. 「Save Game To Slot」の戻り値がfalseになる問題の解決方法
  61. 画面上にメッセージを指定された時間表示させる方法
  62. シェーダコンパイル時間を短縮する方法
  63. 「Take High Res Screenshot」実行時に「シェーダをコンパイル」に長時間待たされる問題とその解決策
  64. データベースを活用する方法
  65. UE5.5がインストールされた環境にUE5.4を追加で導入する方法
  66. World PartitionとWorld Compositionの違い
  67. オープンワールドテンプレートとは?
  68. ポーンをスポーンさせても視点を切り替えない方法
  69. キャラクター同士がすり抜けてしまう問題の解決方法
  70. キャラクターの外見を動的に変更
  71. World Partitionでインスタンスが「アンロード済み」になる問題
  72. データ アセットとデータ テーブルの違い
  73. コンポーネントイベントグラフ内で親クラスの変数にアクセスする方
  74. エディターのソースコードの自動保存の頻度を高める方法
  75. SpawnActorでSpawn Transform Rotationが反映されない理由
  76. ミニマップを表示しポーンの位置を反映する方法
  77. RInterp ToとVInterp Toの違い
  78. 毎秒実行するイベントの定義方法
  79. Niagara のエフェクトにコリジョンを持たせる方法
  80. 「Overlap」と「Hit」の違い
  81. OverlapはあるがHitがない原因
  82. Overlapした位置の座標を取得する方法
  83. ブループリントでレベル間のパラメータを受け渡す方法

最近更新/作成されたページ