Unreal Engineにおける描画周りのプロファイリング手法

こんにちは。
株式会社アドグローブ ゲーム事業部デザイナーの粟屋です。

今回はUnreal Engineにおける描画周りのプロファイリング手法についてご紹介します。
弊社が開発し、先日リリースされた『リデンプションリーパーズ』のゲーム画面を用いて解説します。

はじめに

Redemption Reapers(リデンプションリーパーズ)
リデンプションリーパーズ(以下、本ゲーム)はUnreal Engine 4.27を使用し、開発が行われました。
また、マルチプラットフォーム(Steam/PS4/Switch)で発売されています。

そのためデバイスプロファイル機能を使用して、各デバイス向けにチューニングを行っています。
そちらに関して今回は触れませんが、描画周りのプロファイリング~処理負荷対応が開発において、
どのような流れで行われるかをご紹介したいと思います。

本ゲームはクォータービューのダークファンタジー シミュレーションRPGです。

基本的な考え方

各所でも触れられてはいますが、処理負荷を下げようと闇雲に設定を弄るのはおすすめしません。
不必要にクオリティを下げてしまったり、余計な工数が掛かりがちとなるためです。
まずはしっかりとプロファイリングを行い、原因(ボトルネック)を探ることが大切です。
その調査に時間が掛かったとしても、結果クオリティを極力落とさずに無駄な工数を削減できます。

理想は一通りゲームとしての機能を実装、1ステージをプレイできる状態で、
実機で早い段階からプロファイリングを行うことです。
各コンソールで特有の問題、見た目の差異が発生することが多々あるため、
アセットの量産体制に入る前に確認しておきたいところです(戒めの意を込めて…)

プロファイリング手法

お待たせしました、本題です。
まず流れですが、基本的にはコンソールコマンド・変数を使用して原因を探っていきます。
stat fpsstat unitを表示しつつ、stat ~ / show ~系のコマンドを使用して調査します。
その後、場合によってUnreal InsightsやRenderDocといったツールを使用することがあります。
上記を踏まえて、実際のゲームで使用されている下記マップで計測してみましょう。

計測するマップ

©BINARY HAZE INTERACTIVE Inc.
1. コマンド stat fps / stat unit を入力する

stat fps / stat unit
本ゲームは60fpsが目標のため、各処理を16.66msに収める必要があります。
GPUが何やら重たいですね。
※ 今回は純粋な負荷が分かりやすいように動的解像度はOFFにしています

2. コマンド stat GPU を入力する

stat GPU
各種パスにどれくらいの負荷が掛かっているか、リアルタイムで確認することができます。
BassPass / Prepassの値が高いですね…背景メッシュ周りでしょうか?

3. コマンド show StaticMeshs を入力する

show StaticMeshs
スタティックメッシュを非表示にしてみます。
GPUの値が一気に負荷が下がりました(17.54ms -> 10.34ms)
背景メッシュに原因がないか、もう少し探ってみます。

4. コマンド FreezeRendering を入力する

FreezeRendering
ゲーム画面のカリング処理を固定します。
範囲外に余計なものが描画されていないかを確認します。

5. コマンド ToggleDebugCamera を入力する

ToggleDebugCamera
カメラを自由に動かすことができます。
カメラを引くと…ゲーム画面外の不要な背景メッシュが多数表示されていますね。
このオブジェクトがすべて描画計算に含まれてしまっていて、GPU負荷が掛かっていそうです。
各メッシュをある程度分割して、カリング処理を正しく機能させる必要があります。
カリングについては 公式ドキュメント に詳しく記載されています。

6. 対応後、処理負荷を再び計測

メッシュ分割後にFreezeRendering -> ToggleDebugCameraで確認
無事にゲーム画面外のカリング処理が行われています。
処理負荷対策後の結果
背景メッシュをある程度分割してから、再び負荷計測を行ってみます。
対応前より負荷が下がり、fpsが改善されました(約56fps -> 60fps、GPUは17.54ms -> 13.80msに改善)
Draw負荷が上がっているのは、カリング処理(Frustum Culling)が機能しているためです。
しっかりと原因を調査したことで、クオリティを下げることなく対策ができました。

さいごに

以上、簡単なプロファイリング~対策の流れでした。
今回は極端な例でしたが、実際の負荷原因は多岐にわたります。
メッシュ以外ですと、ライト・シャドウ・ポストプロセス周りは負荷が掛かりがちですし、
Unreal Engine 5でLumenやNaniteを使用している場合は別アプローチの調査が必要です。

ゲームの方向性や求める品質によっても対応が違ってきますので、
取り返しの付かない段階へ入ってしまう前に、日頃から地道に処理負荷対策を行いましょう。

最後までお読みいただきありがとうございました。


rreapers.com




現在アドグローブでは、さまざまなポジションで一緒に働く仲間を募集しています。
詳細については下記からご確認ください。みなさまからのご応募お待ちしております。

hrmos.co