Version: 2022.1
言語: 日本語
グラフィックスのパフォーマンスとプロファイリング
ドローコールの最適化

グラフィックスのパフォーマンスとプロファイリング

このページでは、アプリケーションのレンダリングパフォーマンスを最適化するための簡単なガイドラインを紹介します。

始める前に - 問題を見つけ理解する

変更を加える前に、問題の原因を特定するために、アプリケーションをプロファイルする必要があります。原因を理解する前にパフォーマンスの問題を解決しようとすると、時間を浪費したり、問題を悪化させたりする可能性があります。さらに、レンダリング関連のパフォーマンスの問題は、CPU または GPU で発生する可能性があります。これらの問題を解決するための方策は全く異なります。ですから、何かアクションを起こす前に、問題がどこにあるのかを理解することが重要です。

Unity Learn サイトの以下の記事は、グラフィックスのパフォーマンスに関する包括的な紹介であり、問題の特定と修正に関する情報が含まれています。Fixing performance problems。もしまだこの課題に詳しくない場合は、このページのアドバイスの前に、この記事を読むことをお勧めします。

レンダリングの CPU コストの削減

通常、CPU のレンダリング時間に最も影響するのは、GPU にレンダリングコマンドを送信するためのコストです。レンダリングコマンドには、ドローコール (ジオメトリを描画するコマン ド) と、ジオメトリを描画する前に GPU の設定を変更するコマンドがあります。このような場合は、以下のオプションを検討してください。

  • Unity がレンダリングするオブジェクトの数を減らす。
    • シーン内のオブジェクトの全体的な数を減らすことを検討する。例えば、スカイボックス を使用して、遠くのジオメトリの効果を作成します。
    • より厳密なカリングを行います。これにより、Unity が描画するオブジェクトの数を少なくします。オクルージョンカリング を使って、他のオブジェクトの後ろに隠れているオブジェクトを描画しないようにする、Camera のファークリップ面を小さくして、より遠くにあるオブジェクトがその錐台の外になるようにする、より細かいアプローチとして、オブジェクトを 別のレイヤー に入れ Camera.layerCullDistances でレイヤーごとにカリングの距離設定をする、などを検討してみてください。
  • Unity が各オブジェクトをレンダリングする回数を削減する。
    • lightmapping を使用して、必要に応じてライトと影を “ベイク” (事前計算) します。これにより、ビルド時間、ランタイムメモリー使用量、ストレージスペースが増加しますが、ランタイムのパフォーマンスを向上させることができます。
    • アプリケーションでフォワードレンダリングを使用する場合は、オブジェクトに影響を与えるピクセル単位のリアルタイムライトの数を減らしてください。詳細は、フォワードレンダリングパス を参照してください。
    • リアルタイムシャドウは、非常に多くのリソースを必要とします。そのため、控えめかつ効率的に使用するようにしてください。詳しくは、影のトラブルシューティング を参照してください。
    • アプリケーションでリフレクションプローブを使用する場合、その使用方法を最適化するようにしてください。詳細は、リフレクションプローブのパフォーマンス を参照してください。
  • Unity がレンダリングコマンドを準備し送信するのに必要な作業量を減らす。通常、より効率的な “バッチ” で GPU に送信する方法が使われます。これを実現するには、いくつかの異なる方法があります。詳しくは、ドローコールの最適化 を参照してください。

これらのアプローチの多くは、GPU で必要な作業も削減します。例えば、Unity が 1 フレームでレンダリングするオブジェクトの総数を減らせば、CPU と GPU の両方の作業負荷が軽減されます。

レンダリングの GPU コスト削減

GPU がフレームをレンダリングする時間内に作業を完了できない理由は主に 3 つあります。

アプリケーションがフィルレートによって制限されている場合、 GPU はフレームあたり処理可能なピクセル数よりも多く描画しようとしています。このような場合は、以下のオプションを検討してください。

  • アプリケーションのオーバードローを特定し、削減する。オーバードローの最も一般的な原因は、UI、パーティクル、スプライトなどの重なり合った透明な要素です。Unity エディターでは Overdraw モード を使用して、これが問題となる領域を特定します。
  • フラグメントシェーダーの実行コストを削減する。シェーダーパフォーマンスについては、シェーダーパフォーマンス のページを参照してください。
  • Unity のビルトインシェーダーを使用する場合、 Mobile または Unlit のカテゴリーから選択する。モバイルでないプラットフォームでも動作しますが、より複雑なシェーダーの簡素化され、近似化されたバージョンです。
  • Dynamic Resolution を検討する。これは、GPU の負荷を軽減するために、個々のレンダーターゲットを動的にスケールする Unity の機能です。

アプリケーションがメモリ帯域幅によって制限されている場合、 GPU はフレーム内で処理できる以上のデータを専用メモリに 読み書きしようとしています。これは通常、テクスチャの数が多すぎるか、テクスチャが大きす ぎることを意味します。このような場合は、以下のオプションを検討してください。

  • ランタイムにカメラからの距離が変化するテクスチャ (例えば、3D シーンで使用されるほとんどのテクスチャ) に対して、ミップマップ を有効にする。これにより、テクスチャのメモリ使用量とストレージスペースが増えますが、ランタイムの GPU パフォーマンスを向上させることができます。
  • 適切な 圧縮形式 を使用して、メモリ内のテクスチャのサイズを削減する。これにより、ロード時間を短縮し、メモリフットプリントを縮小し、GPU レンダリングパフォーマンスを改善できます。圧縮テクスチャは、圧縮されていないテクスチャに必要なメモリ帯域幅の一部しか使用しません。

もしアプリケーションが頂点処理によって制限される場合、それは GPU が 1 フレームで処理できるよりも多くの頂点を処理しようとしていることを意味します。このような場合、以下のオプションを検討してください。

  • 頂点シェーダーの実行コストを削減する。シェーダーパフォーマンスについては、シェーダーパフォーマンス のページを参照してください。
  • ジオメトリを最適化する。必要以上の三角形を使用しない。UV マッピングの継ぎ目とハードエッジ (2 重化した頂点) をできるかぎり少数に抑える。詳しくは、最適なパフォーマンスのためのモデル作成 を参照してください。
  • Level Of Detail システムを利用する。

レンダリング頻度の低減

レンダリングのフレームレートを削減するとアプリケーションにメリットがある場合があります。 これにより、1 つのフレームをレンダリングする CPU や GPU のコストは削減されませんが、他の操作 (スクリプトの実行など) の頻度に影響を与えることなく、レンダリングする頻度が削減されます。

レンダリングフレームレートは、アプリケーションの一部に対して、またはアプリケーション全体に対して下げることができます。レンダリングフレームレートを下げると、不必要な電力消費を防ぎ、バッテリーを長持ちさせ、CPU 周波数が制限されるまでデバイスの温度が上昇するのを防ぐことができます。これは特にハンドヘルドデバイスで有効です。

プロファイリングによって、レンダリングがアプリケーションのリソースのかなりの割合を消費していることが判明した場合は、アプリケーションのどの部分がレンダリングの恩恵を受けられるかを検討します。一般的な使用例としては、メニューやポーズ画面、入力待ちのターン制ゲーム、自動車 UI のようにコンテンツのほとんどが静的なアプリケーションなどがあります。

入力遅延を防ぐために、入力の間、一時的にレンダリングのフレームレートを上げると、若干、反応が良くなります。

レンダリングフレームレートを調整するには、OnDemandRendering API を使用します。この API は、特に Adaptive Performance パッケージ を使うとうまく機能します。

ノート: VR アプリケーションは OnDemandRendering をサポートしていません。すべてのフレームをレンダリングしないと、頭の動きに合わせて映像が同期しなくなり、動きによる酔いのリスクが高まる可能性があります。

グラフィックスのパフォーマンスとプロファイリング
ドローコールの最適化