年末にOculus Quest 2を購入してUnityで開発を始めました。
まだ絶賛開発中ですが最適化で使った便利なツールたちをサクッと紹介します。
作っているもの
Oculus Riftが発売されたときにホラーゲームを作りました。
Questも2世代目になり、Riftで動かしていたクォリティをQuestにどこまで落とし込めるか試してみました。
Oculus Storeで無料で配信中です。ちなみにこれはUE4で作りました。
https://www.oculus.com/experiences/rift/1811961072194113/?locale=ja_JP
最適化フロー
大まかな手順としては上から順に以下のような流れで行いました。
・OVRメトリックツール
・Unity Profiler
・Unity Frame Debugger
・Render Doc
・OVR GPU Profiler
・Snapdragon Profiler
OVRメトリックツール
まずはOVRメトリックツールを使用してフレームレートやCPU・GPUの負荷をざっくり把握します。
https://developer.oculus.com/documentation/tools/tools-ovrmetricstool/

Unity Profiler

描画が重すぎると「Gfx.WaitForRenderThread」という処理がとても長くなることがあります。
これは描画が追いつかず、フレームをスキップした時のCPU Idle時間です。
Unity Frame Debugger

Render Doc

OVR GPU Profiler
https://developer.oculus.com/documentation/tools/tools-ovrgpuprofiler/
OVRメトリックツールを使用中にadbでプロファイル内容を指定するとログが出力できます。
GPUのキャッシュ使用率、ドローコールごとのラスタライザの描画範囲をチェック可能です。
GPUのハードウェアの知識と、Mobileプラットフォーム特有の仕様(タイルレンダリングなど)の知識が必要です。
テクスチャキャッシュヒット率が低い場合はテクスチャの解像度を下げたり、リピートさせてキャッシュヒット率を改善させます。
Snapdragon Profiler

そのほか
USBケーブルを接続しながら開発を長時間行うとサーマルスロットリングが発生する
adb接続のために通常はケーブルを接続しますが、充電も同時に行われるためQuestがアツアツになってします。
温度が上がりすぎるのを防ぐため、Questが温度上昇を検知するとCPUやGPUのクロックが下がります。
対策としてはadb接続にWifiを用いてワイヤレスにするとか濡れティッシュをかぶせて放熱対策をします。
Wifiでadb接続する
忘れがちなテンプレUnity設定
プロジェクトを作り直すたびに忘れがち。
・テクスチャフォーマットをASTCにする
→ ETC2より品質が良いです。よりテクスチャサイズを削減することができます。
・ライトマップ最大解像度を4096にする
→ ライトマップが分割されているとリソースの切り替えが増えます。テクスチャアトラスと同様の原理です。
・XR設定のレンダリングモードをMultiViewにする
→ シングルパスステレオレンダリングを有効にします。そうでないと両目の描画を別々に行いドローコールが2倍になります。
・Player設定のGraphics APIをVulkanのみにする
→ OpenGL ESよりCPUオーバーヘッドが少ないです。OpenGLESにできてVulkanにできない機能はありません。
・Player設定のGraphics JobとMulti Thread Renderingを有効にする
→ メニーコアの利点をより生かすために複数スレッドに描画コマンドの積み込みを分散させます。
・カメラのFarClipを標準の1000mから可能な限り小さくする
→ カリング効率を上げるため。どうしても厳しい場合Fogを利用してFarClipの切れ目をごまかします。
・アンチエイリアスにMSAAx4を設定し、OVRManagerのUse Recommended MSAA Levelを有効にする
→ OVRManagerでMSAAレベルを操作できるようにします。
ざっくり過ぎましたが、開発が進みましたらより詳細な情報を記事にしたいと思います。