このテック ブログでは、静的な環境を高度に最適化するために、当社で採用している方法を紹介します。最適化することによって、インタラクションに関わるところや、至近距離で表示されるシーン内のオブジェクトなど、必要なところで負荷の高い処理を行えるようにします。最適化というのは些細なことのように思われるかもしれませんが、実際には、繰り返し行われるクリエイティブなワークフローとしばしば矛盾しています。これは当社に限らず、多くのスタジオでもそうだろうと思います。これから、最適化についての当社の考え方を説明していきます。また、優れたエクスペリエンスを作成するために必要なワークフローを制限することなく、高度に最適化された環境のコンテンツを作成するために、UE4 のツールをどのように活用したかを紹介します。この記事では、Time Stall を例として挙げていきますが、ここで紹介する最適化の多くは、当社のほかのタイトルでも実装されたものです。そうしたタイトルには、National Geographic: Explore VR (Oculus Quest)、Coaster Combat、Pet Lab (Oculus Go) などがあります。 当社のミッションは、VR で可能だと考えられている範囲を広げることです。技術的に強固な基盤の上で、高品質なビジュアルを追求しています。こうした野心的な目標を達成するために、社内で最適化哲学を定義しています。その原則は次のようなものです。
- 最適化の作業は、できるかぎり自動化する必要がある。
- 最適化の作業は、非破壊的なものである必要がある。また、芸術的な自由を確保できるものであり、イテレーションを可能にするものである必要がある。
- 最適化は、ワークフローの一部である。プロジェクトの早い段階でパフォーマンスを確保し、自動化したテストを定期的に実行して確認しながら、そのパフォーマンスを維持する。
VR における最適化には次の点が含まれます。これらは目新しいものではありません。モバイル VR についても同様であり、パフォーマンスの要件がもう少し厳しくなるというところだけが異なります。
- シェーダーの複雑度:大量のピクセルを、ときには複数回にわたって描画するので、できるだけ負荷を小さくします。
- ドローコールの数:ステートの変更は GPU にとっても CPU にとっても負荷の高い処理なので、変更を制限します (Quest では 150 が目標)。
- 三角ポリゴンの数:未加工の頂点データは、特にモバイル VR では制約要因となります。約 15 万を目標とします。
Landfall の開発中に、静的なシーンの最適化方法を探し始めました。するとすぐに、Unreal Engine で利用できる階層的 LOD (HLOD) システムを見つけることができました。この機能を使えば、複数のオブジェクトをまとめてドローコールを減らすことができ、また、複数のマテリアルをベイクして 1 つの新しいマテリアルにできます。それはまさに、最適化のワークフローを改善するために私たちが求めていたもののようでした。

上に挙げたのは、Time Stall での HLOD クラスタの例です。パフォーマンスがどれほど向上したかご覧いただけます。
HLOD のプロセスは、一般に 2 つの段階で構成されます。
- クラスタの生成
- シーンのアクタをグループ化してプロキシ メッシュにします。
- 手動または自動で実行できます。
- 自動のクラスタ生成からさまざまな点を変更しました。後ほど詳しく説明します。
- プロキシ メッシュのビルド
- ソース メッシュ (およびマテリアル) をマージして、プロキシ メッシュのレンダリングに使用できるようにします。
- マージされたメッシュはさまざまな手段で最適化されます。
- 別々のメッシュを 1 つにマージして、ドローコール数を減らします。
- マテリアルをマージします。マテリアルの数を減らして、単純化します。

プロキシ メッシュとマテリアルのスワップの動作例
オレンジ:HLOD レベル 2。アクタ数:1
青:HLOD レベル 1。アクタ数:2
緑:HLOD レベル 0。アクタ数: 8
HLOD システムが提供するオプションは、最適化目的での利用の良い出発点となります。しかし、私たちは、各タイトルの開発中に、HLOD システムを継続的に改善して拡張し、より良く、より速く、高品質の成果を出せるようにしてきました。以降のセクションでは、HLOD プロセスを変更した点と、変更を加えた理由について説明していきます。
オレンジ:HLOD レベル 2。アクタ数:1
青:HLOD レベル 1。アクタ数:2
緑:HLOD レベル 0。アクタ数: 8
自動のクラスタ生成の改善
クラスタ生成は、HLOD プロセスの最初の段階です。ここでは、複数のスタティック メッシュ アクタが選択され、1 つのプロキシ メッシュへとクラスタ化されます。当初は、アート チームがクラスタ化を手動で行っていました。それは 3 つの理由によります。1 つ目は、自動的なクラスタ化では想定外の望ましくない結果が生じたことです。2 つ目は、クラスタの作成に時間がかかっていたことです。3 つ目は、クラスタ化を制御するパラメータの数がごく限られていたことです。たとえば、デフォルトでは、マテリアルのシェーダー モデルの種類ごとに区別することができないので、透明でマスクされたマテリアルが、不透明なマテリアルとしてベイクされてしまいます。徐々に手を加えて、クラスタリング システムを次のように改善していきました。
- 代わりのクラスタリング アルゴリズム (階層的凝集型クラスタリング) を実装して、クラスタの生成を高速化しました。
- クラスタのコンストレイントを追加して、まとめてクラスタ化されるマテリアルの種類を詳しく制御できるようにしました。
- マテリアルの種類や、マテリアルの静的スイッチの値までクラスタのコンストレイントにすることができます。
- クラスタの生成オプションを追加しました。
ビジビリティ カリングの追加
より大きな改善点の 1 つは、プレイヤーから見えないメッシュの三角ポリゴンを削除する機能です。当社のゲームでは、プレイ空間を定義して、プレイヤーがその範囲から出ないようにしています。プレイ空間は、1 つあるいは複数のボリューム、またはレベルを通るスプラインで表されます。HLOD アセットの作成中に、プレイ空間から見えることのない三角ポリゴンがツールによってすべて削除されるようにしました。


上:Time Stall の食堂のシーン。三角ポリゴンのカリング前
下:同じシーンで、見えない部分の三角ポリゴンをカリングしたもの
アトラスの方法の改善
マテリアルのマージ中に、テクスチャはテクスチャ アトラスに配置されます。デフォルトでは、HLOD システムはグリッド ベースのソリューションを使用します。パックされるアセットごとに解像度を異なるものにすることもできますが、それはアセットのテクスチャ サイズに基づきます。背景で使われるオブジェクトの一部で、マテリアル内に何らかの大きなテクスチャがあるために、大量のテクスチャ空間が割り当てられることがあるとわかりました。テクスチャ マップが大きくなるのには、いくつかの理由が考えられます。アセットを結合した結果 1 つの大きなテクスチャ マップができたという場合や、プレイ空間の近くで使われるように設計されたプロップが背景でも使われているという場合があります。いずれにしても、そのアセットは結合されたアトラスで多くの空間を占めることになります。三角ポリゴンのカリングで使用したボリュームを利用して、アトラスのパッキングを改善できました。アトラスに関する改善点は次のとおりです。
- 三角ポリゴンのカリングのあとにアトラスを作成します。
- パッキングを最適化するために UV を再生成します。
- プレイ空間に近いオブジェクトは、プレイ空間から遠いオブジェクトよりも解像度が大きくなります。
- パックされたテクスチャ内でオブジェクトのサイズを決定する際、ライトマップの解像度も考慮します。

左側は Unreal のデフォルトのグリッド レイアウトです。アトラス テクスチャ内で、各メッシュに正方形の領域が割り当てられます。
右側は当社の重み付けした UV アトラス レイアウトです。

マテリアルのベイクの拡張
マテリアルのマージ プロセスに加えたほかの変更の 1 つに、テクスチャをアトラスにベイクする際のオプションの追加があります。テクスチャをベイクして結合する機能は Unreal Engine のシステムにありましたが、PBR のワークフローに限定されていました。最終的な出力を 1 つのテクスチャにベイクすることはできませんでした。そこで、最終的なテクスチャに何をベイクするかをアーティストが制御できるシステムを実装しました。
- ベース カラーのベイク
- UE4 のデフォルトのベイク方法
- ベース カラーの入力のみを新しく生成されるテクスチャと結合
- PBR シェーディングを維持
- このオプションでは、通常、結合された法線マップ、パックされたメタリック、ラフネス、アンビエント オクルージョン マップもベイクされます。
- 主に、動的なシェーディングが引き続き必要となる、プレイ空間に近いオブジェクトに使用します。
- ディフューズのベイク
- ライトマップとベース カラーを 1 つのテクスチャ マップにベイクします。
- ディフューズとスペキュラのベイク
- ライトマップ、ベース カラー、すべてのシェーディングを 1 つのテクスチャ マップにベイクします。遠くにあるオブジェクトに特に役立ちます。
- スペキュラのシェーディングをどこからベイクするか、シーンのアクタによって定義されます。
- ライティングなしのマテリアルに格納できる 1 つのテクスチャ マップができます。これはレンダリングの負荷が最も低い方法です。
- ディフューズ、スペキュラ、フォグのベイク
- 前の選択肢と似ていますが、指数関数的高さフォグを含むところが異なります。

左は HLOD レベル 0 です。元々の PBR マテリアルを使用します。個々のメッシュを結合して 1 つの新しいメッシュにします。見えない三角ポリゴンはカリングされます。この LOD レベルは、プレイヤーが近くにいるときにのみ表示されます。
中央:HLOD レベル 1。このメッシュでは、ごくシンプルなマテリアルがあり、ライティングとシェーディングはすべてテクスチャにベイクされます。
右:HLOD レベル 2。HLOD レベル 1 と同様に、1 つのテクスチャ マップのみが入力となるシンプルなマテリアルがあります。ライティングとシェーディングはすべてベイクされます。
HLOD システムを当社固有のニーズに合わせて拡張する作業を開始してから、2 年以上が経過しました。これは、成果の良い点と悪い点、開発プロセスへの影響を評価するために十分な時間です。
良い点としては、当初の目標はほぼすべて達成できています。
- プロセスは非破壊的で、元のセットアップに基づいて新しいコンテンツを生成 (および再生成) できます。通常は HLOD プロセスを再度実行するだけで調整できます。
- このプロセスをエディタやコマンドレットなど Unreal のコードベース内で動作させることには多くのメリットがあります。エディタ内のあらゆるプロパティ セットと適切に連携します。また、既存のコードの再利用や、既存のコード パスの利用や拡張が可能です。
- ほぼ全体が自動化されたプロセスであり、とても便利です。
将来的にいくつか注意が必要な点もあります。
- アプリケーションのフットプリントが、ときには著しく増加します。すべてを HLOD のセットにベイクすると、ディフューズ テクスチャ 1 つのみをレンダリングすればよくなるため、パフォーマンスも向上します。ただし、これらのアセットすべてが独自にベイクされたテクスチャ アトラスを持つことになります。パッケージのサイズとローディング時間には注意が必要です。
- 今のところはまだ、プロジェクト単位の構成となっていて、最初に手作業でのセットアップが必要です。また、このセットアップを適切に利用するには、最初にいくらかのアセットが必要です。
- おそらく最大の欠点は、メンテナンスが必要な変更の量です。Fortnite を通じて HLOD システムに多くの改良が加えられましたが、そのなかには当社独自の最適化とコンフリクトするところもありました。HLOD システムは UE4 のコア システムの一部なので、多くの変更が生じるものであり、エンジンがアップグレードされるとほぼ毎回のように、当社独自の変更とマージする必要があります。
Unreal は、使っていてすばらしいと感じるエンジンです。また、オープン ソースであるため、自分たちのニーズに合わせてエンジンに調整を加えることができています。
当社では、より良い UE4 エクスペリエンスの開発を手伝っていただける人材をいつでもお待ちしています。アムステルダムで高度な VR と AR のタイトルを開発することにご興味のある方は、当社の求人情報をご覧ください。
冒頭で述べたとおり、Oculus Quest 向けの最適化を検討しているデベロッパーにとって参考になるマテリアルを紹介します。
- UE4 Performance and Profiling(UE4 のパフォーマンスとプロファイリング) | Unreal Dev Day Montreal 2017 [2017 年 10 月 9 日]
- Optimizing Oculus Go for Performance(Oculus Go でのパフォーマンス向上のための最適化) [2018 年 3 月 22 日]
- 「フォートナイト バトルロイヤル」モバイル版で採用した技術 [2018 年 4 月 3 日]
- Tech Note: Profiling & Optimizing on Mobile Devices(モバイル デバイスでのプロファイリングと最適化) [2018 年 5 月 30 日]
- Oculus Connect 5 | Porting Your App to Oculus Quest(Oculus Quest へのアプリの移植) [2018 年 9 月 26 日]
- Oculus Connect 5 | Reinforcing Mobile Performance with RenderDoc(RenderDoc を利用したモバイルでのパフォーマンス向上) [2018 年 9 月 26 日]
- Understanding Gameplay Latency for Oculus Quest, Oculus Go and Gear VR(Oculus Quest、Oculus Go、Gear VR でのゲームプレイのレイテンシについて) [2019 年 4 月]
- Developer Perspective: UE4 Logging and Console Commands for Mobile VR(UE4 のログとコンソール コマンドのモバイル VR での活用) [2019 年 7 月 2 日]
- Developer Perspective: Improving Memory Usage and Load Times in UE4(UE4 のメモリ使用量とロード時間の改善) [2019 年 7 月 25 日]
- Developer Insights: How to Develop with Vulkan for Mobile VR Rendering(モバイル VR のレンダリングへの Vulkan の利用) [2019 年 8 月 2 日]
- Common Rendering Mistakes: How to Find Them and How to Fix Them(レンダリングに関するよくある失敗:その発見方法と修正方法) [2019 年 8 月 22 日]
- Unreal Engine 4 でのレンダリングについての Oculus の公式ドキュメント [2019 年 9 月 4 日]
- HLOD についての Unreal Engine 4 の公式ドキュメント [2019 年 9 月 4 日]
- Oculus Connect 6 | Using Vulkan for Mobile VR(モバイル VR への Vulkan の利用) [2019 年 9 月 26 日]