UE5にて動作がカクツクとき、何が原因で負荷が発生しているのか調べる必要があります。
本記事では統計データであるstat unitの項目の読み方、統計データから負荷ボトルネックを特定する基本、統計データの毎回自動表示する方法を説明します。
動作のボトルネック調査の第一歩は「stat unit」など統計データです。コンソールに「stat unit」を入力する方法もありますが、①画面の左上のメニューをクリックします。②統計データ、③Engine、④FPSにチェック、⑤UnitとUnitGraphにチェックを入れます。簡単な方をお使いください。
右側に細かい数字が出てきます。Frame、Game、Draw、RHIT、GPU time、DynRes、Draws、Primsなどの項目です。
これら数字からゲームスレッド(ゲームロジックやプレイヤーの入力処理など)、レンダリングスレッド(3Dモデルのレンダリング、テクスチャの適用、シェーダーの計算、光源の処理など)、またはGPUのいずれかにパフォーマンスのボトルネックがあるか判別に役立ちます。
公式の説明
https://dev.epicgames.com/documentation/en-us/unreal-engine/stat-commands-in-unreal-engine#unit
Frame(フレーム)
フレーム時間は、ゲームの1フレームを生成するのにかかった総時間です。ゲームスレッドと描画スレッドはフレームを終える前に同期するため、フレーム時間はこれらのスレッドのいずれかの表示時間に近くなることが多いです。
Game(ゲーム:)
フレーム時間がゲーム時間に近い場合、ゲームのパフォーマンスはおそらくゲームスレッドによってボトルネック(負の影響を受けている)になっています。
Draw(描画)
フレーム時間が描画時間に近い場合、ゲームのパフォーマンスはおそらくレンダリングスレッドによってボトルネックになっています。
GPU time(GPU時間)
デオカードがシーンをレンダリングするのにかかる時間を測定します。GPU時間はフレームに同期されているため、フレーム時間と似たようなものになる可能性が高いです。
RHIT
RHIスレッド時間はフレームに同期され、フレーム時間と似ている可能性が高いです。
DynRes
サポートされている場合(および有効になっている場合)、動的解像度は主画面のパーセンテージを副画面のパーセンテージで表示します。
以下画面の一番上に数値が、このプロジェクトの実際のfpsです。60fps出るはずが、何かがボトルネックになっており、48fpsしか出ていません。何がボトルネックなのでしょうか。
まずフレーム時間とゲームスレッドの比較
フレーム時間がゲーム時間に近い場合、それはゲームスレッドがパフォーマンスのボトルネックになっている可能性が高いです。ゲームスレッドは、ゲームロジック、AIの計算、物理演算などを処理します。この時間が全体のフレーム時間に占める割合が大きい場合、ゲームスレッドの最適化が必要です。
実際に以下を見ると、FrameとGameは近くないので、ゲームスレッドがボトルネックではないと判断できます。
フレーム時間と描画スレッドの比較
フレーム時間が描画時間に近い場合、描画スレッドがボトルネックであることを示します。描画スレッドは、3Dモデルのレンダリング、テクスチャのマッピング、シェーダーの適用など、画面に表示するための計算を行います。この時間がフレーム時間に占める割合が大きければ、描画関連の最適化が求められます。
実際に以下を見ると、FrameとDrawはとても近いです。レンダリングスレッドがボトルネックになっている可能性が高いです。
GPU時間の確認(GPU time)
GPU時間もフレーム時間と同様に、グラフィックカードがシーンをレンダリングするのにかかる時間です。GPU時間がフレーム時間に近い場合、GPU処理がボトルネックとなっている可能性があります。
RHIスレッドの時間(RHIT)
RHI(Render Hardware Interface)スレッドは、レンダリングを制御するための低レベルAPIと通信します。この時間がフレーム時間に近い場合、レンダリングAPIの呼び出しに問題がある可能性が指摘されます。以下は近くないので問題がなさそうです。
動的解像度の監視(DynRes)
無効になっていますが動的解像度が有効な場合、パフォーマンスを維持するために解像度が動的に変更されます。この設定の有効化とその効果もパフォーマンス分析に重要です。
毎回自動でエディタに統計データを表示する方法
エディタを再起動すると表示が消えてしまいます。消えないようにする方法はエディタの環境設定から、ビューポート、ルック&フィール、エンジン統計の保存をクリックします。これでエディタを再起動しても再表示されます。
アプリで書き出したり実行しながら統計データを確認
簡易なプレビューではなく、実際にアプリで書き出した時にも統計データをチェックしたいことがあります。実際に操作するとまた挙動が異なるものです。ブループリントにて、stat unitが実行されるようにします。Execute Console Commandを設定して、そこにstat unitなど統計データのコマンドを入力します。
riragonの記事はここまで。以下deepサーチ検索結果です。本記事で発見できない項目など見つかるかもしれません。AI検索のよいところは、知りえなかった情報が見つかることです。
もっと深堀してみよう!
UE5においてstat unit
の項目の詳細な読み方、ボトルネックの特定方法、および関連する統計データについて調査します。また、パッケージ化後の実行やVR環境での最適化に関する情報、ハードウェアの影響、および効果的な最適化手法についても調査し、包括的にまとめます。
UE5におけるパフォーマンス計測とボトルネック分析
1. stat unit
各項目の意味とボトルネックの見分け方
Unreal Engine 5では、コンソールコマンドstat unit
を実行するとフレーム時間の内訳が表示されます。表示される主な項目は「Frame」「Game」「Draw」「GPU」「RHIT」「Present」です。それぞれの意味は以下の通りです。
- Frame(フレーム時間): 1フレーム全体にかかった時間(ms)です。これは実質的に他の値の中で最大のものになり (Meaning of Frame, Game, Draw when using Stat UnitGraph – Debugging, Optimization, & Profiling – Epic Developer Community Forums)、FPSの逆数(例: 33msなら約30FPS)に相当します (Measuring Performance – Unreal Art Optimization)。Frame時間が目標値(例えば60FPSなら16.67ms)を超えている場合、何らかのボトルネックが発生しています。
- Game(ゲームスレッド時間): ゲームスレッドでの処理時間です。ゲームプレイのコード(C++やブループリント)、AI、物理演算などCPUで行われるゲームロジックの時間を示します (Measuring Performance – Unreal Art Optimization) (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。この値がFrameとほぼ同じくらい大きい場合、ゲームスレッド(CPU)の処理がボトルネックでフレームレートを制限している可能性があります (Profiling & Optimizing for the best performance in Unreal Engine)。
- Draw(レンダースレッド時間): 描画スレッドでの処理時間です。CPUがレンダリングのためにデータを準備しコマンドを発行する処理時間を示します (Measuring Performance – Unreal Art Optimization)。この値がFrame時間に近い場合、CPUのレンダリング処理(描画スレッド)がボトルネックとなっている可能性があります (Profiling & Optimizing for the best performance in Unreal Engine)。
- GPU(GPUレンダリング時間): GPUがフレームの描画に費やした時間です (Measuring Performance – Unreal Art Optimization)。GPUはCPUとは非同期並列に動作しますが、現在のフレームのGPU処理が完了し表示されるまで次のフレームに進めないため、GPU時間が長いとそれがフレーム全体を押し延ばします (Measuring Performance – Unreal Art Optimization)。GameやDrawがいずれもFrameより十分小さい一方でGPU時間がFrameに近い場合、GPU側にボトルネック(ビデオカードが処理しきれない負荷)があると判断できます (Profiling & Optimizing for the best performance in Unreal Engine)。
- RHIT(RHIスレッド時間): レンダリング・ハードウェア・インターフェーススレッドの処理時間です。Direct3D12やVulkanなど低レベルAPI向けに実装されたスレッドで、レンダースレッドと並行してGPUコマンド送信を行います (Profiling & Optimizing for the best performance in Unreal Engine)。通常この値はFrame時間とほぼ同程度かわずかに小さいくらいで、特定の重い処理がない限り大きな負荷にはなりません (AMD Lança hoje Patch especifico para Unreal Engine 4, seu calcanhar de aquiles, será que a partir de agora vai?????w | Fórum Outer Space – O maior fórum de games do Brasil)。極端にRHITが大きい場合はドライバ処理やGPU待ちが発生している可能性があります。
- Present(プレゼント時間): 画面表示のための処理や、GPUの処理完了を待機している時間です。
stat unit
のオンスクリーン表示そのものには出ない場合もありますが、stat scenerendering
など詳細な統計で「Present」時間が計測されることがあります (Unreal Engine performance guide – AMD GPUOpen)。Presentが高い場合、レンダリングスレッドがGPUの完了待ちでブロックされていることを意味し、実質的にはGPUボトルネックの兆候です (What is Present Time in D3D11RHI? – Rendering – Epic Developer Community Forums)。例えばDirectXでは、GPUの処理が遅いとCPU側がPresent(表示)で待たされるため、この値がフレーム時間を押し上げます。
以上の項目の中で最も時間のかかっている部分がボトルネックです。実際のFrame時間は、Game・Draw・GPUのいずれか遅い方によって決まります (Meaning of Frame, Game, Draw when using Stat UnitGraph – Debugging, Optimization, & Profiling – Epic Developer Community Forums)。したがって、stat unit
を見てFrameとほぼ同じ値を示している項目がボトルネック要因であり、そのスレッドないしデバイス(CPUゲーム処理・CPU描画処理・GPU)の最適化が必要になります (Profiling & Optimizing for the best performance in Unreal Engine)。例えば「Game: 25ms, Draw: 5ms, GPU: 4ms, Frame:25ms」であればCPUのゲームロジックが足かせになっており、「GPU: 30ms, Game:10ms, Frame:30ms」であればGPUがボトルネックだと判断できます。
2. stat unit
関連の統計データ活用方法 (stat fps
, stat gpu
, stat scene rendering
など)
パフォーマンスを詳しく分析するには、stat unit
以外にもUnreal Engineの各種統計コマンドを組み合わせて使います。それぞれの用途と読み取り方は以下の通りです。
stat fps
– 現在のFPSとフレームタイム(ms)を簡易表示するコマンドです (Measuring Performance – Unreal Art Optimization)。ゲーム全体のパフォーマンスの目安になりますが、CPU/GPUのどちらが原因かまでは分かりません (Measuring Performance – Unreal Art Optimization)。まずFPSが目標を下回っている場合に、stat unit
で原因を掘り下げるという使い方になります。stat unitgraph
–stat unit
と同じ情報(Frame, Game, Draw, GPU時間)をリアルタイムグラフで表示するコマンドです (Measuring Performance – Unreal Art Optimization)。ゲーム中にカメラを動かしたりシーンを移動したりしながら実行すると、どのタイミングでフレーム時間が悪化するか(スパイクが出るか)視覚的に捉えやすいです (Measuring Performance – Unreal Art Optimization)。緩やかな負荷と比較して急激にFrameが跳ね上がる場面があれば、その瞬間に重い処理(ヒッチ)が発生していることを意味します。stat sceneRendering
– シーンレンダリング統計を表示します。描画関連の高レベルな情報が一覧でき、例えば現在のDraw Calls(描画呼び出し回数)や描画プリミティブ数(三角形数)、ライティングやオクルージョンの状況などが分かります (Profiling & Optimizing for the best performance in Unreal Engine)。またPresent時間(CPUがGPU待ちする時間)などレンダリング全体の内訳も表示され (Unreal Engine performance guide – AMD GPUOpen)、ボトルネックの概観を掴むのに役立ちます。「動的ライトがいくつあるか」「半透明オブジェクトの負荷」なども示されるため、レンダリングパイプラインのどこに負荷が集中しているかを特定する手がかりになります (AMD Lança hoje Patch especifico para Unreal Engine 4, seu calcanhar de aquiles, será que a partir de agora vai?????w | Fórum Outer Space – O maior fórum de games do Brasil)。例えばstat sceneRendering
で描画呼び出し(Draws)が極端に多い場合は、オブジェクト数やマテリアル数の多さ(描画コール過多)がCPU負荷につながっている可能性があります。stat gpu
– GPU側の処理時間内訳をテキスト表示するコマンドです (Measuring Performance – Unreal Art Optimization)。GPUが1フレーム内でどの処理に何msかけているか(例: ベースパス描画○ms、シャドウマップ○ms、ポストプロセス○ms など)を一覧できます (Measuring Performance – Unreal Art Optimization)。いわば簡易版の「GPUビジュアライザ」機能で、どの描画パスが特に重いかを数値で把握できます (Measuring Performance – Unreal Art Optimization)。GPUボトルネックが疑われる場合、この出力からどのレンダリングパスが支配的かを見極めます。例えば“Translucency”にGPU時間を多く消費していれば半透明オブジェクトの描画負荷が高いことが分かります。なお、stat gpu
を使用するには一部の環境でr.GPUStatsEnabled 1
の設定が必要な場合があります (AMD Lança hoje Patch especifico para Unreal Engine 4, seu calcanhar de aquiles, será que a partir de agora vai?????w | Fórum Outer Space – O maior fórum de games do Brasil)。stat rhi
– RHI (Rendering Hardware Interface)レベルの情報を表示するコマンドです。現在使用中のレンダリングリソース(レンダータARGETやテクスチャなど)のメモリ使用量やドライバの統計情報が得られます (Unreal Engine performance guide – AMD GPUOpen)。例えば「Render target memory」が表示する値から、GバッファやシャドウマップなどレンダーターゲットがどれくらいVRAMを消費しているか分かります。メモリ不足によるパフォーマンス低下や、VRAM使用率が異常に高くなっていないかを確認するのに有用です (Unreal Engine performance guide – AMD GPUOpen)。
これらの統計コマンドを組み合わせることで、まずCPUとGPUのどちらにボトルネックがあるか把握し(stat unit)、次に問題の詳細を深掘りできます (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。例えば「GPUがボトルネックだ」と判明したらstat gpu
でどの描画処理に時間がかかっているか調べたり、「CPUのGameが重い」場合はstat game
やUnreal Insightsでゲームコード中の重い関数を探す、といった流れです (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。またstat sceneRendering
の情報(Draw Call数やライティング負荷など)は、シーンの設計レベルでの最適化ポイント(オブジェクト数削減やライト設定の見直し)を考える材料になります (AMD Lança hoje Patch especifico para Unreal Engine 4, seu calcanhar de aquiles, será que a partir de agora vai?????w | Fórum Outer Space – O maior fórum de games do Brasil)。
補足として、stat startfile
/stat stopfile
コマンドで統計情報をログに記録し、Session FrontendやUnreal Insightsで詳細解析する方法もあります(後述) (Profiling & Optimizing for the best performance in Unreal Engine) (Profiling & Optimizing for the best performance in Unreal Engine)。短時間の統計をファイル出力し、後からグラフ表示や詳細な関数単位の分析が可能です。
3. パッケージ化後の実行時におけるパフォーマンス計測と問題特定
エディタ上での計測だけでなく、実際にパッケージ化したビルド(実行ファイル)上でパフォーマンスを測定することは非常に重要です。理由として、エディタでは各種オーバーヘッドやエディタ専用処理があるため、実行性能やメモリ使用量が実ビルドと異なる場合があるからです。実際、「エディタでの実行」と「パッケージ後の実行」ではメモリ使用量が大きく異なったり、ストリーミングによるスタッター(カクつき)の発生状況が変わることがあります (Unreal Engine Game Optimization on a Budget – Tom Looman)。そのため最終的なパフォーマンス検証はパッケージビルドで行うのが望ましく、エディタ上で得た最適化策もパッケージ版で効果を確認する必要があります (Unreal Engine Game Optimization on a Budget – Tom Looman)。
パッケージビルド上で統計情報を確認する方法:
- 開発ビルドでのコンソール使用: パッケージ作成時にDevelopmentビルドまたはDebugビルドを選択すると、実行時にチートコマンドやコンソールが有効な状態でゲームを起動できます。その状態でゲーム中に~キー(または適宜設定したキー)でコンソールを開き、エディタ同様に
stat unit
やstat fps
等のコマンドを実行すれば、オンスクリーンにパフォーマンス指標を表示できます。これによりパッケージ後でもリアルタイムな計測が可能です。ただしShippingビルド(出荷用ビルド)ではデフォルトでコンソールやstatコマンドが無効になる点に注意が必要です (How to profile Shipping build? – Unreal Engine Forums)(本番用ではチートが使えなくなるため)。最終的な製品ビルドではなくパフォーマンス解析が目的であれば、Developmentビルドで実行するか、あるいはDefaultEngine.ini
に一時的に設定を入れてコンソールを有効化するとよいでしょう。 - 統計ファイルの記録 (
stat startfile
): ゲーム実行中にコンソールからstat startfile
コマンドを入力すると、そこからstat stopfile
を実行するまでの間、詳細なパフォーマンス統計をファイルに記録できます (Profiling & Optimizing for the best performance in Unreal Engine)。記録が終了すると、プロジェクトのSaved/Profiling/UnrealStats/
フォルダに拡張子.ue4stats
のファイルが出力されます (Profiling & Optimizing for the best performance in Unreal Engine)。このファイルをエディタの「Session Frontend」(Window → Developer Tools → Session Frontend
)で開くか、あるいはUnreal Insightsツールでロードすると、記録されたCPU・GPU各スレッドの詳細なプロファイルを解析できます (Profiling & Optimizing for the best performance in Unreal Engine)。これによりパッケージ実行環境で発生しているボトルネックを後からじっくり分析可能です。Unreal InsightsはUE4後期~UE5で導入された強力なプロファイリングツールで、スタンドアロン実行されたゲームにもアタッチしてトレースを取得できます(例えばコマンドライン引数に-trace=cpu,render,gpu
等を付与して起動し、Insightsで接続)。パッケージ版で再生中の動作を記録しておけば、あとでエディタに戻って詳しくボトルネック原因を調査できるわけです。 - ターゲットプラットフォーム固有のツール: 場合によっては、プラットフォーム固有のプロファイラも役立ちます。例えばモバイル向けにパッケージした場合はAndroidのSystraceやGPUベンダー提供のツール、コンソール機では各社の開発者ツールを用いてCPUやGPUの使用率、描画コール数、メモリ使用量などを計測する方法もあります。しかし一般的なPC環境であれば、前述のUnreal Engine標準のstatファイル+Insightsで十分詳細な情報が得られます。
パッケージ実行時の問題特定ポイント: エディタ実行との違いに注目しましょう。例えばエディタでは問題なかったのにパッケージ後に急にFPSが低下する場合、エディタでは無効化されていたフルスクリーン独自の負荷や、ビルド設定によって有効になった機能(例: LumenのQualityレベル差異)などが影響している可能性があります。またロード時のカクつきはパッケージ時に顕在化しやすい問題です。エディタではすでにロード済みだったアセットも、パッケージ環境ではディスクから読み込むため、ストリーミング負荷が直接体感されます。このようなストレージやメモリ起因のボトルネックは (Unreal Engine Game Optimization on a Budget – Tom Looman)、統計ファイルをとってLoadTimeやFile I/Oイベントを解析したり (Unreal Engine Game Optimization on a Budget – Tom Looman)、ログ出力(例えば log LogContentPolling
や log LogStreaming
)から診断できます。特定のタイミングでFrameが跳ね上がる場合、その前後で「どのファイルを読み込んでいたか」「GC(ガベージコレクション)は走っていないか」などを調べることで原因を突き止められます。
4. VR環境でのボトルネック特定と最適化ポイント
VR(仮想現実)向けアプリケーションでは、非常に高いフレームレート(90FPSや120FPSなど)と低遅延が要求されるため、通常のゲーム以上にボトルネックの把握と最適化が重要です。またHMD(ヘッドマウントディスプレイ)向けでは両目分の描画が必要で処理負荷が増える点にも注意する必要があります。以下にVR特有のボトルネック診断法と最適化ポイントをまとめます。
● ボトルネックの診断(CPU or GPU): 基本的な手順は通常のケースと同じく、まずstat unit
でCPUとGPUのどちらに余裕がないかを確認します (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。VRでは特にGPU負荷がボトルネックになりやすい傾向があります。高解像度で両目分のレンダリングを行うため、ピクセル描画量が膨大になりがちだからです。一方で、CPU側もVR固有のオーバーヘッド(例: 両目分の描画コール、トラッキングデバイスの更新など)はありますが、GPUに比べればボトルネックになるケースは少なめです。いずれにせよ、Game・Draw・GPUの値を確認し、どれがフレーム時間を占有しているかで判断します。もしGPU時間がFrameと同程度ならGPUボトルネック、GameまたはDrawが長ければCPU側のボトルネックです。
- GPUがボトルネックの場合、
stat gpu
でどのレンダリングパスが時間を食っているか詳しく確認します。VRではピクセル描画負荷が高い(=シェーダやポストプロセスが重い)か、ジオメトリ描画負荷が高い(=描画物が多すぎる)かを切り分けることが大切です。ひとつの手法として、極端にレンダリング解像度を下げてみるというものがあります。例えばvr.PixelDensity 0.5
(もしくはr.ScreenPercentage
で50%程度に解像度縮小)を一時的に適用すると、それまでGPUがピクセル処理に費やしていた時間が大幅に減少します。もしこの操作でフレームレートが大きく向上するなら、ピクセルシェーダ/描画解像度寄りの負荷がボトルネックだったことが示唆されます。一方、解像度を下げてもフレームレートがほとんど変わらない場合、ジオメトリやCPU側の負荷が支配的である可能性が高いです (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。このようにしてボトルネックの性質を掴んだ上で、次の最適化策を講じます。
● VRパフォーマンス最適化の主なポイント:
- 描画コールの削減(Instanced StereoやMulti-Viewの活用): VRでは左右2つの目のために同じシーンを2回描画する必要があります。標準のレンダリングでは描画コールも2倍になりますが、UEのInstanced Stereo(インスタンシングステレオ)機能を使うとCPUの描画処理を1回で両目分行えるため、レンダリングスレッドの負荷を大幅に減らせます (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。PC向けVRではプロジェクト設定の「Engine > Rendering > VR」内でInstanced Stereoを有効にしましょう (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。モバイルVR(例: Oculus Quest)ではMobile Multi-Viewという同様の最適化を利用できます (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。これらによりDraw(レンダースレッド)時間の短縮が期待できます。
- 固定フォービエイテッドレンダリング (FFR) の利用: Oculus QuestなどスタンドアロンVRでは、視野の中心以外を低解像度でレンダリングする固定フォービエイテッドレンダリング機能があります。UEでは「Dynamic Fixed Foveation」を有効にすることで利用可能です (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。これによりプレイヤーの視線の周辺部のピクセルを削減し、GPUのピクセル描画負荷を軽減できます。特にスタンドアロンVRデバイスではGPU性能が限られるため、品質と性能のバランスを取る有効な手段です。
- レンダリングパイプラインの選択: VRではフォワードレンダリングが推奨される場合があります。デフォルトの遅延レンダリングは多数の動的ライトやポストプロセスに強力ですが、VRにおいては解像度優先・動的ライト最小構成が多いためフォワードシェーディングの方が高速になる傾向があります (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。プロジェクト設定のレンダリング設定でForward Shadingを有効にし、アンチエイリアスもMSAAを使用するとよいでしょう (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)(VRでデフォルトのTAAはブレやゴーストが目立つため画質的にもMSAAが適します)。フォワードレンダリング+MSAAにすることで描画の単純化と画質向上を両立できます。
- 描画負荷(オブジェクト数・ポリゴン数)の削減: できるだけ描画コール数を減らし、ポリゴン数も適切に抑えることが重要です。特にスタンドアロンVRでは描画コール数が100を超えると厳しいとも言われており、Oculus Quest 2では1フレームあたり100未満に抑えることが推奨されています (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。オクルージョンカリングやフラスタムカリングを駆使してカメラに映らないオブジェクトは描画しない、レベルストリーミングやLODを利用して距離に応じポリゴン数を減らす、といった施策が必要です。またNaniteが利用可能な環境なら積極的に活用し、遠距離のポリゴン数を自動で圧縮するのも有効でしょう。実例として、Quest 2クラスではシーン全体の三角形数を75万~100万程度に抑えるのが目安とされています (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。こうした目標値を参考に、自分のVRコンテンツがジオメトリ過多でないかチェックします。
- ライティングとポストプロセスの最適化: 動的シャドウや複雑なポストプロセスはVRではできる限り控えます。可能な範囲でライティングはベイクしておき、動的ライトの数を極力減らす(必要な場合も影の解像度やカスケード数を下げる)ことが望ましいです。またポストプロセス効果(ブルーム、被写界深度、モーションブラーなど)はVRでは効果が出にくいか酔いやすくなるため、品質よりパフォーマンスを優先してオフにする判断も重要です。これらの効果を削減すれば、その分GPUの余裕を確保できます (Measuring Performance – Unreal Art Optimization)。
- VRプラットフォーム固有のツール: 実機でのボトルネック確認には、プラットフォーム提供ツールも活用しましょう。PC VRの場合、SteamVRのFrame Timingグラフで「アプリケーション(ゲーム側)」「コンポジター(VR合成側)」のどちらが遅延しているか確認できます。またOculusデバイスではOVR Metrics ToolでHMD上にCPU/GPUの利用率や熱状況を表示できます (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance) (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。こうしたツールとUEの
stat
コマンドを併用し、どの部分に余裕がないかを継続的にモニタリングすると効果的です。
5. ハードウェア要因とそれぞれのボトルネック判別方法
パフォーマンスのボトルネックは大きくCPU、GPU、メモリ、ストレージのどこに起因するかに分類できます。それぞれの典型的な症状と見分け方を整理します。
- CPUボトルネック: CPU側(ゲームスレッドまたはレンダースレッド)がフレームレートの足を引っ張っている状態です。
stat unit
でGameまたはDrawの値がFrameと同程度になっている場合はCPUボトルネックと判断できます (Profiling & Optimizing for the best performance in Unreal Engine)。原因となるCPU処理として多いのは、ゲームロジックの負荷(AIの思考や大量のイベント処理)、物理演算のコスト、アニメーション更新、オブジェクト数過多によるコリジョン判定負荷などです (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。まずはstat game
でゲームスレッド内訳を見たり、stat physics
で物理エンジンの更新時間を確認するなど、どのカテゴリに時間がかかっているかを突き止めます (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。ゲームスレッド自体が問題であれば、Unreal InsightsのCPUプロファイルやprofilegame
コマンドで数秒間の詳細な関数トレースを取得し、特定の関数(例えば毎フレーム重いTickを持つBlueprintなど)を特定します (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。レンダースレッド(Draw)が重い場合は、描画コール数やオクルージョン、バッチングの状況を見直します。CPUボトルネックの対処としては後述のようにコードの最適化(計算量削減や並列化)、不要なTickの削除、BlueprintからC++への置き換え、描画コール削減などが有効です。 - GPUボトルネック: GPUのレンダリング処理がフレームレートを制限している状態です。
stat unit
でGPUの値がFrameに近い場合がこれに該当します (Profiling & Optimizing for the best performance in Unreal Engine)。典型的な原因は、シーンが複雑すぎる(ポリゴン数過多)、描画範囲が広大でピクセル数が多い、マテリアル/シェーダが複雑(オーバードローや重いエフェクト)、高解像度テクスチャやポストプロセスによる負荷、パーティクルなどのエフェクト過多などです (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。stat gpu
やGPU Profiler(Ctrl+Shift+,
で開くビジュアライザ)を使って、どの描画パスに時間がかかっているかを確認します。例えばBasePassが大半を占めるならジオメトリ量が原因、PostProcessingが大きければポストエフェクトが原因、といった具合です。GPUボトルネック時は画質設定を下げることで改善するか試すのも有効です。もしテクスチャやライティング品質を下げたり解像度を落としてFPSが向上するようであれば、まさしくGPU負荷過多だったわけです。対処法としては後述のとおり描画負荷削減(ポリゴン数・描画コール数の削減)、シェーダ最適化、不要なエフェクトを切る、解像度や品質設定の見直しなどが効果的です。 - メモリボトルネック: メインメモリ(RAM)またはGPUメモリ(VRAM)が不足または帯域不足になっている状態です。メモリ自体が不足してフレームレートが常に低下するケースは稀ですが、メモリ不足は断続的なスタッターやガベージコレクション起因のフレーム低下となって現れます。例えば「一定時間ごとに一瞬カクつく」場合は、ヒープメモリ確保やGCが走っている可能性があります。
stat memory
でメモリ使用量を監視したり、memreport -full
で詳細なメモリレポートを出力して、どのリソースがメモリを圧迫しているか調査します (Unreal Engine Game Optimization on a Budget – Tom Looman)。またGPUのVRAM不足も問題で、VRAMが満杯になるとテクスチャストリーミングが追いつかず画質低下やスワップが発生します。ログに「Texture pool size exceeded」等の警告が出ていないか確認し、出ている場合はr.Streaming.PoolSize
拡大やテクスチャ縮小を検討します。stat rhi
で現在のVRAM使用量を把握できるので参考にします (Unreal Engine performance guide – AMD GPUOpen)。メモリ関連のボトルネックは直接FPS低下というよりは不定期なヒッチとして表れることが多いため、症状に応じてプロファイルデータ中のMemoryやLoadingトレースをチェックすることが重要です (Unreal Engine Game Optimization on a Budget – Tom Looman)。 - ストレージ(IO)ボトルネック: 読み込みストレージ(HDD/SSD)の速度が原因で発生するボトルネックです。これもFPSが常時低いというより、ロード時にフレームが止まるといった形で現れます。大量のアセットをストリーミング読み込みするオープンワールドなどでは、ディスクIOが追いつかずフレームが一時的に停止するケースがあります。これを特定するにはUnreal InsightsでFileトレースを有効にしておき、問題の起きたフレーム前後のファイル読み込みイベントを確認します (Unreal Engine Game Optimization on a Budget – Tom Looman)。またログに
LogStreaming
をVerbose以上で出力し、長時間かかっているロードがないか探すのも有効です。対策としては、あらかじめ必要なデータを読み込んでおく(ロード画面を設ける、LoadLevelStreaming
を早めに仕掛ける)、ストリーミングするオブジェクト数を減らす、圧縮を減らして読み込み展開コストを下げる、といった方法があります。幸い近年はNVMe SSDなど高速ストレージが普及し、ストレージ速度が描画のボトルネックになるケースは少なくなっています(標準的なSSDならストレージは滅多にボトルネックにはならない)とも言われています (How do you speed up Unreal? – Getting Started & Setup – Epic Developer Community Forums) (How do you speed up Unreal? – Getting Started & Setup – Epic Developer Community Forums)。しかし低速HDD環境や非常に大量のデータを扱う場合は無視できないため、必要に応じてストレージの性能改善(SSD化など)も検討しましょう。
6. 効果的な最適化手法
ボトルネックが特定できたら、それに対処するための最適化を行います。Unreal Engineで効果的な最適化手法には大きくエンジン設定の調整、アセット(コンテンツ)の最適化、コードやアルゴリズムの最適化の3つがあります。それぞれ具体的な施策を以下に提案します。
- エンジン設定・レンダリング設定の見直し: 不要な高負荷機能をオフにし、適切な品質設定に調整します。例えばUE5であれば、重いLumen(全局照明)を無効化してスクリーンスペースGIに切り替える、ハードウェアレイトレーシングを使っていないならオフにするといった設定変更だけでも大幅に軽量化できます (How do you speed up Unreal? – Getting Started & Setup – Epic Developer Community Forums)。またVSyncの無効化(テスト時)、スムースフレームレートの無効化(エンジンが自動調整しないようにする)もプロファイリング時には重要です (Unreal Engine Game Optimization on a Budget – Tom Looman)。加えてシャドウ品質やポストプロセス品質を下げることもGPU負荷軽減に直結します。必要以上に高い解像度のレンダリングやアンチエイリアス設定も見直しましょう。プロジェクト設定のスケーラビリティ設定(Epic/High/Mediumなど)をターゲットハードに合わせて調整し、ターゲットFPSで動作する最低限の品質に留めることが安定したパフォーマンスに繋がります。
- アセットの最適化(LOD・ポリゴン・テクスチャ): モデルやテクスチャなど美術アセット面での最適化です。高ポリゴンモデルにはLOD(レベルオブディテール)を設定し、距離に応じてポリゴン数を減らします (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。遠景に細密なモデルをそのまま描画すると無駄が大きいため、自動LOD生成機能やSimplifierを用いてポリゴン数を削減します。また視界に入らないオブジェクトはヒエラルキーLOD(HLOD)やインスタンシングでまとめることで、レンダリング負荷と描画コールを削減できます (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。テクスチャについても、解像度が過剰に高いものは適切なサイズに落とすか圧縮設定を調整し、メモリと描画の帯域負荷を下げます。モバイルやVR向けであれば、使用しないMipMapはストリッピングするなどメモリ節約も効果的です。さらに、不要な透明素材や過度なパーティクルはシーンから取り除くか簡略化します(透明オブジェクトは描画順序制御やオーバードローの関係で特に重いため、必要最低限に抑える)。
- オブジェクト数と描画コール削減: CPU描画負荷を下げるために、描画コール(Draw Calls)の数を減らす工夫が必要です。大量の小オブジェクトがある場合、それぞれ個別に描画するのではなくメッシュを結合してひとつにまとめることを検討します (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。動的に変更がない背景オブジェクト群は、DCCツール側でひとつのスタティックメッシュに結合して配置すれば、1回のDraw Callで描画可能になります (Understanding performance bottlenecks? – UDK Programming and UnrealScript – Epic Developer Community Forums)。Unreal Engineは自動的に同じマテリアルのメッシュをバッチングする仕組みがありますが (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)、それでもなお膨大な数のオブジェクトが存在すると限界があります。階層LOD(HLOD)システムを有効化すれば、距離に応じて建物などをまとめた簡易メッシュに置き換えることで描画コール数を減らせます。一方、動的に移動するオブジェクトが多数ある場合はインスタンシングやInstanced Static Meshコンポーネントを使うのも有効です (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。数十個~数百個の同種メッシュを個別のアクターで配置する代わりに、1つのアクターでインスタンス配列として保持すれば描画コールは飛躍的に減ります。
- 不可視オブジェクトのカリング: カメラに映らないオブジェクトを描画しない工夫も重要です。エンジンはデフォルトでビューカリング(視錐台カリング)やオクルージョン(遮蔽)カリングを行いますが、レベルデザインによってはカメラ後方のオブジェクトまで存在している場合があります。必要に応じてCull Distance Volumeを配置して遠距離の小オブジェクトを強制的に非表示にしたり、
PrimitiveComponent
のMinDrawDistance
/MaxDrawDistance
を設定して距離で描画を切ることを検討します (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。また、ポータルや遮蔽物を利用できるなら手動のビューブロッカーを活用して、あるエリアでは別エリアのオブジェクトを描画しないといった仕組みもパフォーマンスに寄与します。 - ライティングの最適化: ライティングは静的照明の活用が基本です。可能な限り静的ライトやベイクしたライトマップを使い、動的な影の数を削減します (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。動的ライティングが必要な場合でも、その影の解像度や更新頻度を下げてコストを抑えます。例えばプレイヤー周辺の限られたライトのみを可動ライトにし、他は静的にする、影を落とすオブジェクトを限定する、といった調整です。また距離によるシャドウのフェードアウト(シャドウカスケードの遠距離フェード)も利用しましょう。加えて反射も計算コストが高いため、必要に応じてPlanar Reflectionの解像度を下げたり、SkyLightの更新をリアルタイムではなく静的にするなどしてチューニングします。ライティングビルドをしっかり行い、Lightmap UVや解像度の最適化もメモリ・描画負荷の軽減に繋がります。
- ポストプロセス効果の削減: ポストプロセッシングは視覚効果向上に有用ですが、過剰に使うとGPU負荷が大きくなります。被写界深度やモーションブラー、ブルーム、レンズフレア、スクリーンスペース反射(SSR)、アンビエントオクルージョン(SSAO)など、シーンに大きな影響を与えない効果は思い切ってオフにすることも検討しましょう (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。特にVRや性能ギリギリの環境では、ポスト効果を切るだけで数ms節約できる場合があります。どうしても必要な効果についてもクオリティ設定を落とす(例: SSRを低品質にする、モーションブラーのサンプル数を減らす)ことで性能を稼げます。
- Blueprintとコードの最適化: ゲームのロジック部分での最適化です。毎フレーム実行される不要な処理を削除・抑制するのが第一です。多数のアクターでTickイベントを使っているなら、本当にTickが必要か見直し、必要な場合も更新頻度を下げられないか検討します(例えば「毎フレームではなく0.1秒おき実行」等タイマーに置き換える)。Blueprintの実行はC++に比べてオーバーヘッドがあるため、頻繁に呼ばれるBlueprintロジックはC++化(またはブループリントナティファイ(Nativization))するのも有効です (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)。特に算術計算やループ処理など負荷の高い部分はC++で書き直すと劇的に軽くなる場合があります。またUEにはマルチスレッドタスク(AsyncTaskや並列フォーイーチなど)を活用できる場面も多いので、ゲームスレッド一本で処理していたものを非同期処理に分散することも検討します。さらに、物理演算やコリジョン判定もチューニング可能です。剛体オブジェクト数を減らしたり衝突判定の頻度を下げる、Collisionチャンネルを細かく設定して無駄な衝突チェックをしないようにする、などの工夫でCPU負荷を下げられます。アニメーションでは、必要のない骨はUpdateしない設定(MasterPoseComponentの利用やUpdate Rate Optimizations)を使う、複雑なスケルタルメッシュは画面外でTickしないようにする、といった最適化があります。
- その他の最適化テクニック: 上記以外にも様々なテクニックがあります。例えばシグニフィカンスマネージャを導入して視界外や遠距離のアクターの更新を自動スローダウンする、広大なマップではレベルストリーミングでエリアごとに区切って必要な部分だけ読み込む (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)、圧縮技術(Oodleなど)でロード時間を短縮する、エフェクト用のパーティクルはLODやカリング距離を設定する (10 Tips for Improving Performance in Unreal Engine – Leartes Studios)、など挙げれば切りがありません。重要なのは、プロファイリングで得られたデータに基づいてボトルネックに直結する部分から優先的に手を入れることです。一通り最適化を施したら再度プロファイルを取り、効果を検証します (GitHub – authorTom/notes-on-VR-performance: How to optimise VR performance)。この計測→改善→検証のサイクルを繰り返し、小さな積み重ねでパフォーマンスを目標値まで引き上げていくことが肝要です。
以上、UE5におけるstat unit
の読み取り方から始まり、関連統計コマンドの活用、ビルド後の計測方法、VR特有の留意点、ハードウェア別の診断と最適化手法について詳しく解説しました。ボトルネックを正しく特定し、適切な対策を講じることで、フレームレートの向上と安定化が図れるでしょう。ゲームの規模やターゲットプラットフォームに応じて最適な手法を選び、快適な体験を提供できるよう最適化を進めてください。各種ツール(Unreal Insights等)や統計コマンドを駆使して分析を行い、ボトルネックに対処することが、UE5で高性能なコンテンツを制作する鍵となります。
参考資料: Epic Games 公式ドキュメントおよびコミュニティフォーラム、Unreal Engineパフォーマンスガイド (Unreal Engine performance guide – AMD GPUOpen) (Unreal Engine performance guide – AMD GPUOpen)、有志による技術ブログ記事 (Measuring Performance – Unreal Art Optimization) (AMD Lança hoje Patch especifico para Unreal Engine 4, seu calcanhar de aquiles, será que a partir de agora vai?????w | Fórum Outer Space – O maior fórum de games do Brasil)など.