Unity を検索

カメラの使い方を工夫してゲームのパフォーマンスを最適化する方法:パート 1

2021年9月23日 カテゴリ: ゲーム | 8 分 で読めます
Accelerate Success Logo
Accelerate Success Logo
取り上げているトピック
シェア

より多くのクリエイターがいれば、世界はもっと良い場所になります。Unity の新しいコンテンツシリーズ「Accelerate Success」は、Accelerate Solutions Games チームの技術的な経験を紹介するための手段です。このチームは、顧客へのコンサルティング、共同開発、そしてフル開発のサービスを提供する、プロフェッショナル向けサービスを担当するグループです。顧客が Unity でできることの限界に挑戦するような、非常に複雑で困難な Unity による仕事を担当することもあります。

このシリーズは Unity が提供している技術系の e ブックとウェビナーの内容を元に構成された内容となっています。Unity の開発に力を貸してきてくださった大いなるゲーム開発コミュニティへのささやかな恩返しとなれば幸いです。Accelerate Success シリーズでは、私たちが世界中の優れたスタジオと共に仕事をする中で集めた実践的なヒントやベストプラクティスを、実際に手順をお見せしながらご紹介することを目指しています。Accelerate Success の名を冠して公開している各コンテンツは、Accelerate Solutions チームのそれぞれ別のソフトウェア開発コンサルタントによって監修・執筆されており、その内容は実際のシナリオや知見に基づいています。 

このブログ記事シリーズは、Accelerate Solutions - Games チームのリーダーの 1 人である Bertrand Guay-Paquet が執筆しました。Bertrand は Unity のストックホルムオフィスに所属しており、このブログ記事シリーズに収録されている知見は、彼がチームのために実施したプロジェクトレビューで得られた知見に基づいています。 

プロジェクトレビューとは何か

Accelerate Solutions - Games チームに所属する Unity ソフトウェア開発コンサルタントの仕事の大きな部分を占めるのが、プロジェクトレビューの実施です。プロジェクトレビューは、Integrated Success プランを契約している Unity の顧客と共に、年に一度行うミーティングです。その際、私たちは 2 日間かけてオンサイトで(最近の状況においては Zoomで)顧客のプロジェクトを徹底的にレビューします。プロジェクトレビューでは、Unity のソフトウェア開発コンサルタントがプロジェクトやワークフローを深く掘り下げ、スピード、安定性、効率性を高めるためにパフォーマンスを最適化できる領域を特定する包括的なレポートを提供します。 

プロジェクトレビューの中で、不要なカメラがある、最適とは言えないカメラの設定を目にすることがあります。通常、このような場合は即座に調査すべきものとしてフラグを立て、パフォーマンスを向上させるための最終的な推奨事項として、カメラの統合や不要なカメラの削除などを行います。

Profiler capture with multiple Cameras - A red flag!
複数のカメラでのプロファイラーキャプチャー:危険な兆候が見える

長年にわたり、いくつかの実際のゲームにおいて、カメラを追加したことでパフォーマンスを落としている例を目撃しました。しかし、これまでは、シーン内のさまざまなカメラ設定のベンチマークを取ることができませんでした。この e ブックでは、モバイルハードウェアでカメラのパフォーマンスベンチマークを実施し、状況をより正確に把握する方法について説明します。私たちは Unity のビルトインレンダーパイプラインとユニバーサルレンダーパイプラインをテストしました。

カメラの使い方を工夫してゲームのパフォーマンスを最適化する方法:パート 1

カメラは実際のところ何をするのか

カメラは基本的に、シーンの中での有効視野、位置、方向を定義するものです。これらのパラメーターは、カメラが表示するコンテンツ(レンダラー)を設定するものです。カメラのレンダリング画像は、ディスプレイまたは RenderTexture に出力されます。どちらの場合も、カメラのビューポートの矩形が対象となる出力領域を定義します。

大まかに言うと、毎フレーム、Unity エンジンのコードでは、有効になっているカメラでは以下のことを行う必要があります。

  • 可視状態にするレンダラーのセットを決めます。これは「カリング」と呼ばれます。カリングを行うことで、カメラがレンダリングした画像に影響する可能性のあるレンダラーのみが GPU 上で描画されるようになります。つまり、むやみに多くのレンダラーの描画をすることを避けて、パフォーマンスを向上させることが目的です。これには 3 つのプロセスが用いられます。
    • カメラのカリングマスクと一致しないレイヤーのレンダラーは除外されます。
    • 視錐台によるカリングでは、カメラの視錐台(表示領域)の外側にあるレンダラーを除外します。
    • オクルージョンカリングは、他の不透明なレンダラーの後ろに完全に隠れているレンダラーを除外します。この手順はオプションであり、通常は網羅的ではありません。
  • GPU が可視化されたレンダラーを描画する順序を決定します。大まかに言うと、カメラは透明なものを奥から手前に、不透明なものをおおよそ手前から奥にソートします。その他にも、マテリアルやシェーダーのレンダーキュー、ソーティングレイヤー、ソート順など、レンダリング順に影響を与える要因があります。
  • 可視状態の各レンダラーの描画コマンドを生成し、GPU に作業を依頼します。これらのコマンドは、レンダリングのためのマテリアルとメッシュを設定します。

お気づきの方もいらっしゃるかと思いますが、ここで示した手順はかなり多くの詳細やニュアンスを省いたものです。それでも、カメラについて理解するための出発点としては十分です。

カメラテストシーン

追加されたカメラのコストの測定には、広く使われている回転するキューブのシーンを使いました。すべてのテストシーンには、以下のものが奥から手前の順に配置されています。

  • 回転するキューブの 3D グリッド。各スライスは、キューブを 10 x 10 個配置したグリッドになっています。スライスの数は調整可能で、この記事のシリーズではその数を「ロードファクター」と呼びます。
  • ソフトシャドウに設定した単一のディレクショナルライトのソース
  • モバイルゲームでポップアップが 2 つ出てきたところをシミュレーションするために、それぞれパネルを持つ「ゲーム」UI キャンバス 2 つ。
  • テストを制御するための独立した「オーバーレイ」UI キャンバス。

テスト用プロジェクトの全体は、Unity の Accelerate Solutions Games samples GitHub レポジトリで公開されています。

Single Camera Test Scene
テストシーン

設定可能な回転するキューブの数(ロードファクター)を使って、ゲーム内のさまざまな状況のシミュレーションを行いました。1 つ目のシナリオは、ゲームのロビーシーンのような負荷の低いものを想定しています。2 つ目のシナリオでは、より処理の重いゲームプレイをシミュレーションするために高い負荷をかけます。

Exploded view of the test scene
テストシーンの分解図

意味のある結果を得るために、すべてのカメラの設定でシーン中の同じ役割のコンテンツの内容を一致させました。ベースとなるシーンには、メインカメラ、回転するキューブ、テストを制御する UI が含まれています。そして、カメラの設定を変えて「ゲーム」UI を含む 4 つのシーンを作成しました。

  1. メインカメラ単独の場合に最適なシーン。「ゲーム」UI キャンバスのレンダーモードは「Screen Space - Overlay」に設定されています。
  2. 2 つの「ゲーム」UI キャンバスのレンダーモードは「Screen Space - Camera」に設定されており、2 つ目のカメラに割り当てられています。これは、ゲームでは比較的よく見られるカメラの設定です。
  3. 2 つの「ゲーム」UI キャンバスのレンダーモードは「Screen Space - Camera」に設定されており、それぞれ別のカメラに割り当てられています。これは、複数のカメラを使用して UI を組み立てるカメラの設定をシミュレーションしたものです。
  4. これは、カリングマスクを「Nothing」に設定したカメラを追加した 3 つ目のシーンと同じで、何もレンダリングされません。

各テストシナリオではベースとなるシーンの上に、上記のシーンのうち 1 つを追加で読み込みます。カリングマスクを使って、複数のカメラで処理されるゲームオブジェクトがないようにしています。

レンダリングパイプライン

レンダリングパイプラインとは、シーン内のカメラが画像を生成するプロセスのことです。Unity のビルトインレンダーパイプラインは、古くはシーンをレンダリングするための唯一の選択肢でした。Unity 2018.1 で、スクリプタブルレンダーパイプライン(SRP)が導入され、C# スクリプトからレンダリングを制御できる可能性が広がりました。Unity が提供する SRP の実装には、ユニバーサルレンダーパイプライン(URP)と HD レンダーパイプライン(HDRP)の 2 つがあります。

このブログ記事のシリーズでは、ビルトインレンダーパイプラインと URP がモバイルデバイスに対応していることから、この 2 つのレンダーパイプラインでのカメラのパフォーマンスオーバーヘッドを検証します。HDRP はモバイルデバイスでは動作しないため、今回のテストでは除外しました。HDRP を除外した 2 つ目の理由は、レンダリング機能の設定範囲が非常に広いため、非効率的なカメラの使用に関する公平で意味のある比較シナリオを作成することが難しいからです。

URP では、ベースとなるカメラと 1 台以上のオーバーレイカメラで構成されるカメラスタックという概念が導入されています。これを URP でのテストでカメラを設定する際に使いました。実行時にプログラムでカメラスタックを設定・変更する方法については、Manager.cs を参照してください。

テストのセットアップ

テストには、Unity 2020.3.11f1(IL2CPP 開発ビルドを同梱)を使用しました。テストは、ビルトインレンダーパイプラインとユニバーサルレンダーパイプラインの両方で行いました。レンダーパイプラインごとに,ロードファクターが低い場合とロードファクターが高い場合の両方でテストを行い、デバイスごとに合計 16 回、プロファイラーのキャプチャを取りました。使用するデバイスは以下の 5 つです。

  • Google Nexus 5
  • Samsung Galaxy S7 edge (G935F)
  • Samsung Galaxy A20e
  • iPhone 5s
  • iPhone 7

Profile Analyzer パッケージを使用して、300 フレームのキャプチャーにおけるメインスレッド上のプロファイラーマーカーの平均値を取得しました。

モバイルのパフォーマンスに関する注意点

パフォーマンスを確実に測定することは、内的要因と外的要因の両方を考慮しなければならないため、困難となることがしばしばあります。スマートフォンはサーマルスロットリングや非対称な CPU コア構成など、外的要因をいくつか持っていることで有名です。Unity の Mobile チームによる「Mobile Performance handbook: Thermal stability」は、こうした困難な状況を克服するための非常に貴重な資料です。

Avoiding thermal throttling with a cooling pack
保冷剤でサーマルスロットリングを回避しているところ

以上、シリーズ 1 本目となるブログ記事「カメラの使い方を工夫してゲームのパフォーマンスを最適化する方法」をお届けしました。私たちが行ったテストの結果、避けるべきカメラの使い方のパターン、複数のカメラを使うタイミング、およびテストから導かれる結論などを紹介した続編の記事は 3 週間後に公開する予定です。ぜひご覧ください。 

パート 2 の公開を待ちきれないという方は、今すぐ完全版の e ブックの PDF バージョンをダウンロードしてお読みください。

2021年9月23日 カテゴリ: ゲーム | 8 分 で読めます
取り上げているトピック
関連する投稿