本日はUnityグラフィックのパフォーマンスを調査します。
今回は、実際に稼働しているアプリケーションの例として筆者が開発に参加しているVRゲームGrooveFitIslandのステージを例題にUnityでのパフォーマンスの向上を調査していきます。
〇GrooveFitIsland
GrooveFitIslandは筆者がグラフィックエンジニアとして開発に参加しているVRゲームです。
グルーブフィットと呼ばれる様々なゲームを遊びながらリズムに乗ってフィットネスを行うことができます。
現在はSteamVRでリリースされています。
〇Unityでオブジェクト統合によってパフォーマンスを向上させる
Unityではシーンに配置されている様々なグラフィック的な要因でパフォーマンスが決まっています。
よく知られる例では3Dモデルのポリゴン数などです。
対象のデバイスのスペックに依存しますが一般的にVRでは10~20万ポリゴン以上のポリゴンを一度に描画させた場合特に安定したパフォーマンスを維持できないと呼ばれています。
また、オブジェクト数に関しても少なければ少ないほどパフォーマンスが向上すると呼ばれています。
UntiyではUnity内でメッシュを統合してマテリアル数を減らすためにMeshBakerのようなアセットも公開されています。
今回はGrooveFitIslandのステージを例にとってパフォーマンス向上を行っていきます。
〇RenderDocでステージのパフォーマンスを調べる。
今回ベンチマークをとるためにRenderDocを使用しました。
今回はグルーブフィットの一つのFishingのステージを例にとっています。
このステージでは正面が海、背面が森となっています。
今回この背面の森の処理が重いように思えたので実際にベンチマークをとりながら最適化を行いました。
〇最適化前のパフォーマンス
最適化前は背面の描画に1フレームにつき16033μSecかかっていました。
これは0.1秒に相当します。
ただし、これはUnityのGUIもレンダリングしており実際のレンダリングは次のようになっています。
MetaQuestなどでは72fpsのパフォーマンスが推奨されますが、この場合単純計算で0.72秒描画だけで時間をかけており、パフォーマンスが高いとは言えません。
もともとこの木々は一本一本別のオブジェクトになっており、400以上の木がありました。
まずは木々を一度Blenderで統合し1つのオブジェクト、メッシュに変換しました。
ベンチマークをとると317まで落とすことができました。
もともとがオブジェクト数が多いとは言え、一気にパフォーマンスが向上しました。
次に背景の山ですが、ここはオブジェクト数が少ないため実際にもっと細かく見ていきます。
山も一つ一つ別のオブジェクトとなっており、RenderDocを見るとそれぞれにイベントが発生して描画していることがわかります。
ここでは3回で48μ秒かけていました。
山もBlenderで統合することで最終的にはイベントが1回、18μ秒に抑えることができました。
山の例では18μ秒はわずかな値ですが、1フレームで18μ秒のためゲームが高いフレームレートで動けば動くほど1秒間の処理は大きな値になります。
以上でオブジェクト統合でのパフォーマンス向上が一つ一つのオブジェクトでは些細な差ですが、総合すると大きな差となることがわかりました。
※ここでのベンチマークはRTX 2070のGPUで実行しています。