[UE4] OculusQuestでUnrealInsightsを使ってプロファイリングする

# はじめに
OculusQuestでプロファイリング情報を取得するのにUnrealInsightsを使ってみたのですが、取得できるようになるまでにいくつか躓いた箇所があったので記事を書いておきます。UE4.25.3を使用しています。

# 手順
自分が現在動かすことができている手順を以下に示します。
1. UE上で起動ボタンを押して、プロファイリング対象のアプリをビルドしOculusQuestに書き込みます。
2. OculusQuest上の/sdcard/UE4Game/[プロジェクト名]フォルダからUE4CommandLine.txtというファイルをローカルPC上にコピーします(自分はファイルの転送にSideQuestを使っています)。
3. UE4CommandLine.txtを編集し、末尾に" -tracehost=127.0.0.1 -trace=cpu,loadtime,log,frame,gpu -statnamedevents"を追加します(取得したい情報により記載内容は変更ください。記載内容の意味は[こちら](https://docs.unrealengine.com/ja/Engine/Performance/UnrealInsights/Overview/index.html)に情報があります)。
4. 更新したUE4CommandLine.txtをOculusQuest上の/sdcard/UE4Game/[プロジェクト名]フォルダに書き戻します。UE4CommandLine.txtは、アプリをビルドしOculusQuestに書き込むごとに上書きされるので、その場合はプロファイリング実施前に再度手順を実施する必要があります。
4. コマンドプロンプトから以下を実行します。
adb.exe start-server
adb.exe reverse tcp:1980 tcp:1980
6. Unreal Insightsを起動します。Unreal Insightsの実行ファイルはUE4をインストールしたフォルダのEngine/Binaries/Win64の下にあります。
7. Unreal InsightsのNew Connectionに127.0.0.1を入力し、Connectを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/60a6a0aa-483c-f587-5d8e-ccccfde9743d.png)
8. OculusQuest上でプロファイリング対象のアプリを起動します。
9. 取得に成功するとTrace Sessionsにデータが追加されるので、対象データを選択してダブルクリックすると解析された情報が表示されます。

# プロファイリング例
OculusQuestでプロファイリング実施したときの情報を参考に記します。
## 調査対象のアプリ概要
VRテンプレートをベースに作成したアプリで、2個のレベルがあります。
1. プレイヤー以外は何もなし、ランドスケープ(コンポーネント数は8x8=64)のみ。ブロックに触ると次のレベルに遷移。
2. プレイヤー以外にAIで動く約50体のキャラクターが存在。ランドスケープ(コンポーネント数は8x8=64)に若干のフォリッジが存在。

## 最初の設定とプロファイリング
プロジェクトの設定は、最初は以下のようにデフォルトの設定を使用しました。赤枠の設定は後で設定変更した箇所です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/fbe505f6-55e8-cc53-f693-57e1efe0dcf2.png)

これでプロファイリングを取得すると以下のようになりました。これはフレームパネルの箇所の画像になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/bb6f5807-cb4b-b131-8147-90d629594107.png)
① レベル1の実行中、おおむね72FPSですが、7フレームに1回処理時間が伸びて40FPSくらいになっています。
② レベル2のロード中です。
③ レベル2の実行中、処理が重すぎて20FPS～30FPS程度です。
Timingパネルの画面で、①の処理時間が伸びている箇所を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/52f5f787-4286-8e61-5cfb-705e44b749c7.png)
処理時間が伸びている箇所では、RHIThreadの処理時間が伸びており、どうやらレンダリング処理が1フレーム内に間に合っていなさそうです。RHIThreadについてはあまり情報がなかったのですが、[こちら](https://developer.oculus.com/blog/understanding-gameplay-latency-for-oculus-quest-oculus-go-and-gear-vr/?locale=ja_JP)に解説がありました。


## 設定変更後のプロファイリング
プロジェクトの設定を以下のように変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/23958849-9862-ef11-c546-1a67340964b2.png)

設定変更した箇所でパフォーマンスに大きく影響あるのがフォワードレンダラの有効化です。[こちら](https://docs.unrealengine.com/ja/Engine/Performance/ForwardRenderer/index.html)に詳しい情報があります。デフォルトのディファードレンダラに比べて制限はいろいろあるのですが、OculusQuestではもともと性能的にポストエフェクトを使用するのが厳しいため、あまり問題にはならないように思います。

これでプロファイリングを取得すると以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/5dec72b6-249d-d93a-ec0e-16a0dcebe436.png)
① レベル1の実行中、72FPSを維持できています。
② レベル2のロード中です。
③ レベル2の実行中、あいかわらず処理は重いですが、40FPS～50FPS程度とだいぶ改善しました。
ところで、設定変更後のアプリの画質ですが、違いは自分には判らなかったです。

## モバイルマルチビュー設定について
モバイルマルチビュー設定を有効にするとシングルパスステレオレンダリングが有効になるため、パフォーマンス向上が期待できるので、モバイルマルチビュー設定を有効にする設定も試していたのですが、有効にすると、アプリが落ちる現象が発生していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/e5f8a60b-e9f6-bec2-3e20-208493b98ccf.png)
この時のログを見ると、どうやらフォリッジの所でエラーが発生しているようでした。
<pre>
LogPlayLevel:   08-09 06:07:04.717  4197  4432 D UE4     : Assertion failed: Views.Num() == 2 [File:D:/Build/++UE4+Licensee/Sync/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp] [Line: 1505]
</pre>
試しにフォリッジを外してみると現象は発生せず、また、エラーが発生しているコードを見ると、モバイルマルチビュー設定が影響することが判明したため、今回はモバイルマルチビュー設定は無効で使用することとしました。
モバイルマルチビュー設定については[こちら](https://developer.oculus.com/documentation/unreal/unreal-multi-view/)に情報があります。

# 参考資料
・[Unreal Insightsの概要](https://docs.unrealengine.com/ja/Engine/Performance/UnrealInsights/Overview/index.html)
公式のページです。Unreal Insightsについて基本はこちらを参照したのですが、アプリにCommandLine引数を渡す方法がこちらではわからなかったです。
・[Oculus Quest Performance Tools in Unreal Engine](https://medium.com/realities-io/oculus-quest-performance-tools-in-unreal-engine-2210f2581c8f)
英語の情報ですが、アプリにCommandLine引数を渡す方法についてはこちらを参考にしました。

そのほかOculusQuestでのパフォーマンス向上の参考になる参考資料
・[モバイル デバイスのパフォーマンス ガイドライン](https://docs.unrealengine.com/ja/Platforms/Mobile/Performance/index.html)
・[Oculus QuestおよびOculus Go:固定中心窩レンダリング](https://developer.oculus.com/documentation/unreal/unreal-ffr/)
・[UE4のモバイル向け機能や最新情報などを改めて紹介！2019](https://www.slideshare.net/EpicGamesJapan/ue4mobilestudy)
・[そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>](https://www.slideshare.net/EpicGamesJapan/ue4-festeast2019-ue4mobilepart1-179705324)