
この記事は、Unityプロジェクトの最適化のヒントを紐解くシリーズの第2弾です。より少ないリソースでより高いフレームレートで実行するためのガイドとしてご利用ください。これらのベストプラクティスを試したら、シリーズの他のページもぜひご覧ください。
Unity 6の開発者とアーティスト向けの最新の最適化ガイドをご覧ください。
Unity のグラフィックススツールを使用すると、モバイルからハイエンドのコンソール、デスクトップまで、範囲プラットフォームで最適化されたグラフィックスをあらゆるスタイルで作成できます。このプロセスは通常、アーティスティックなディレクションとレンダーパイプラインによって異なります。そのため、開始する前に、使用可能なレンダーパイプラインを確認することをお勧めします。
シーンライティングの最適化は厳密な科学ではなく、より反復的なプロセスです。これには試行錯誤が必要で、そのプロセスは通常、アーティスティックなディレクションとレンダーパイプラインによって異なります。
シーンのライティングを開始する前に、利用可能なレンダーパイプラインの 1 つを選択する必要があります。レンダーパイプラインは、シーンのコンテンツを取得して画面にディスプレイする一連の操作を実行します。
Unityには、さまざまな機能とパフォーマンス特性を備えた3つのレンダーパイプラインがあらかじめ用意されています。また、独自のレンダーパイプラインを作成することもできます。
1. ユニバーサルレンダーパイプライン(URP)は、構築済みのスクリプタブルレンダーパイプライン(SRP)です。URP は、モバイルからハイエンドのコンソールや PC まで、範囲プラットフォームで最適化されたグラフィックスを作成するためのアーティストフレンドリーなワークフローを提供します。URP はビルトインパイプラインの後継で、古いパイプラインでは利用できなかったグラフィックスとレンダリング機能を提供します。パフォーマンスを維持するために、ライティングとシェーディングの計算コストを削減するトレードオフを行います。モバイルやVRなど、ほとんどのターゲット プラットフォームにアクセスしたい場合は、URPを選択します。
URPの機能の詳細については、eBook「上級者向けユニバーサルレンダーパイプライン(URP)入門(Unity 6版)」を参照してください。
2. HDレンダーパイプライン(HDRP)も、最先端の忠実度の高いグラフィックス用に設計された構築済みSRPです。HDRP は PC、Xbox、PlayStation などのハイエンドハードウェアをターゲットにしています。上級者向けのライティング、リフレクション、シャドウを備えた、最高レベルの現実感のあるフォトリアリスティックなグラフィックスを作成する際に推奨されるレンダーパイプラインです。HDRP は物理ベースのライティングとマテリアルを使用し、改良されたデバッグツールをサポートしています。
HDRPの機能の概要については、eBook「HDレンダーパイプライン(HDRP)のライティングと環境」をご覧ください。
3. ビルトイン レンダー パイプラインは、Unityの古い汎用レンダー パイプラインで、カスタマイズ性に制限があります。このパイプラインは、Unity 6.x サイクルを通じてサポートが継続されます。

フォワードレンダリングでは、グラフィックススカードがジオメトリを投影し、頂点に分割します。これらの頂点はさらにフラグメント、つまりピクセルに分解され、画面にレンダリングされて最終的な画像が作成されます。
パイプラインは各オブジェクトを 1 つずつグラフィックス API に渡します。フォワードレンダリングには各ライトのコストがかかります。シーン内のライトの数が多いほど、レンダリングに時間がかかります。
ビルトインパイプラインのフォワードレンダラーは、オブジェクトごとに別々のパスで各ライトを描画します。同じゲームオブジェクトに複数のライトが当たっている場合、オーバー描画が顕著になり、オーバーラップする領域が同じピクセルを複数回描画する必要がある場合があります。リアルタイムライトの数を最小化してオーバードローを削減します。
URP は、ライトごとに 1 つのパスをレンダリングするのではなく、オブジェクトごとにライトをカリングします。これにより、ライティングを 1 つのパスで計算できるようになり、ビルトインパイプラインのフォワードレンダラーと比較して描画コールが少なくなります。
フォワード +
フォワード+ レンダリングは、オブジェクトごとではなく空間的にライトをカリングすることで、標準のフォワードレンダリングを改善します。これにより、フレームのレンダリング時に利用できるライト全体の数が増加します。ディファードレンダリングは、Native RenderPass API をサポートしており、G バッファーとライティングパスを単一のレンダーパスにまとめることができます。

ディファードシェーディングでは、ライティングはオブジェクトごとに計算されません。
ディファードシェーディングは、代わりにライティングの計算を後の段階に延期します。ディファード シェーディングは 2 つのパスを使用します。
1 つ目のパスである G バッファ ジオメトリパスでは、Unity がゲームオブジェクトをレンダリングします。このパスは、いくつかの種類のジオメトリプロパティを取得し、テクスチャのセットに格納します。G バッファ テクスチャには、次のものがあります。
2 つ目のパス、つまりライティングパスでは、Unity が G バッファに基づいてシーンのライティングをレンダリングします。各ピクセルを繰り返し処理し、個々のオブジェクトではなくバッファに基づいてライティング情報を計算するとします。そのため、ディファードシェーディングで非シャドウキャストライトを追加しても、フォワードレンダリングと同じパフォーマンスヒットは発生しません。
レンダリングパスを選択すること自体は最適化ではありませんが、プロジェクトの最適化方法に影響を与える可能性があります。このセクションの他の手法やワークフローは、選択したレンダーパイプラインやレンダリングパスによって異なります。

HDRP と URP はどちらも、シェーダー作成用のビジュアルインターフェースである Shader Graph をサポートしています。これにより、一部のユーザーは、以前は手が届かなかった複雑なシェーディングエフェクトを作成できます。ビジュアルグラフシステムの 150 以上のノードを使用して、より多くのシェーダーを作成できます。API を使用して独自のカスタムノードを作成することもできます。
各 Shader Graph は、グラフの出力を決定する互換性のあるマスターノードから開始します。ビジュアルインターフェースでノードと演算子を追加し、シェーダーロジックを構築します。
この Shader Graph はレンダーパイプラインのバックエンドに渡されます。最終的な結果は、HLSLまたはCgで記述されたシェーダーと機能的に類似したシェーダーLabシェーダーです。
Shader Graph の最適化は、従来の HLSL/Cg シェーダーに適用されるのと同じルールの多くに従います。Shader Graph の処理が増えるほど、アプリケーションのパフォーマンスに影響が及びます。
CPU負荷が高い場合は、シェーダーを最適化してもフレームレートは改善されませんが、モバイルプラットフォームのバッテリー寿命は改善される可能性があります。
GPU 依存の場合は、シェーダーグラフでパフォーマンスを向上させるための次のガイドラインに従ってください。
- ノードのデシメーション:未使用のノードを削除します。変更が必要な場合を除き、デフォルトを変更したり、ノードを接続したりしないでください。Shader Graph は、使用されていない機能を自動的にコンパイルします。可能な場合は、値をテクスチャにベイクします。例えばテクスチャテクスチテクスチャ明度加えます。明度アセテクスチャ
- 小さいデータ形式を使用する:可能な場合は、より小さなデータ構造体に切り替えます。プロジェクトに影響を与えない場合は、Vector3 の代わりに Vector2 を使用することを検討してください。状況によっては精度を下げることもできます (Float の代わりに half を使うなど)。
- 演算の削減:シェーダー操作は1秒間に何度も実行されるため、可能な限り演算演算子を最適化してください。論理ブランチを作成する代わりに、結果をブレンドしてみてください。定数を使用し、ベクトルを適用する前にスカラー値を組み合わせる。最後に、Inspector に表示する必要のないプロパティーをインラインノードとして換算します。これらの段階的な高速化はすべて、フレームバジェットにヘルプます。
- プレビューをブランチする:グラフが大きくなると、コンパイルが遅くなることがあります。現時点でプレビューしたい操作のみを含む独立した小さなブランチでワークフローを合理化し、目的の結果が得られるまでこの小さなブランチのイテレーションを高速化します。
分岐がマスターノードに接続されていない場合は、プレビュー分岐をグラフに残して問題ありません。Unity は、コンパイル中に最終出力に影響しないノードを削除します。
- 手動での最適化:グラフィックスプログラマーの経験があっても、Shader Graph を使用してスクリプトベースのシェーダー用の定型コードを記述できます。Shader Graphアセットを選択し、コンテキスト メニューから[Copy Shader]を選択します。
新しい HLSL/Cg シェーダーを作成し、コピーした Shader Graph にペーストします。これは一方通行の操作ですが、手動の最適化でパフォーマンスをさらに高めることができます。

グラフィックス設定の「Always Included」リストから、使用しないシェーダーをすべて削除します(編集>「ProjectSettings」>「グラフィックス」)。アプリケーションの生存期間に必要なシェーダーをここに追加します。

シェーダーバリアントはプラットフォーム固有の機能には便利ですが、ビルド時間とファイルサイズが増加します。
シェーダーコンパイルプラグマディレクティブを使用すると、ターゲットプラットフォームごとに異なるシェーダーをコンパイルできます。次に、シェーダーキーワード (または Shader Graph Keyword ノード) を使用して、特定の機能を有効または無効にしたシェーダーバリアントを作成します。
シェーダーバリアントが必要ないことがわかっている場合は、ビルドに含めないようにできます。
Editor.logを解析してシェーダーのタイミングとサイズを確認します。「Compiled シェーダー」と「Compressed シェーダー」で始まる行を探します。ログの例には、TEST シェーダーで次のように表示されます。
31.23秒にコンパイルされたシェーダー「TEST Standard(スペキュラー設定)」
d3d9(内部プログラムの合計:482, unique:474)
d3d11(内部プログラムの合計:482, unique:466)
Metal(内部プログラムの合計:482, unique:480)
glcore(内部プログラムの合計:482, unique:454)
d3d9の圧縮シェーダー「TEST Standard(スペキュラー設定)」を1.04 MBから0.14 MBに
d3d11の圧縮シェーダー「TEST Standard(スペキュラー設定)」を1.39 MBから0.12 MBに
Metal上の圧縮シェーダー「TEST Standard(スペキュラー設定)」を2.56 MBから0.20 MBに
glcore の圧縮シェーダー「TEST Standard (Specular 設定)」を 2.04 MB から 0.15 MB に
これにより、このシェーダーについていくつかのことがわかります。
- #pragma multi_compile とシェーダー_feature により、シェーダーは 482 バリアントに拡張されます。
- Unityは、ゲーム データに含まれるシェーダーを、圧縮されたサイズのおおよその合計に圧縮します。0.14+0.12+0.20+0.15 = 0.61MB.
-ランタイム時に、Unityは圧縮データをメモリ(0.61 MB)に保持しながら、現在使用しているグラフィックスAPIのデータは非圧縮です。例えば、現在のAPIがMetalの場合、2.56 MBのアカウントになります。
ビルド後、Project Auditor は Editor.log を解析して、プロジェクトにコンパイルされたすべてのシェーダー、シェーダーキーワード、およびシェーダーバリアントのリストをディスプレイできます。また、ゲーム実行後のプレイヤーログを分析することもできます。アプリケーションがランタイムで実際にコンパイルして使用したバリアントを示します。
この情報を使用して、スクリプタブルシェーダーストリッピングシステムをビルドし、バリアントの数を削減します。これにより、ビルド時間、ビルドサイズ、ランタイムメモリ使用量を改善できます。
このプロセスの詳細については、ストリッピングスクリプタブルシェーダーバリアントのブログ記事をお読みください。
アンチエイリアシングは、画像を平滑化し、エッジのギザギザを減らし、スペキュラーエイリアシングを最小化します。
ビルトインレンダーパイプラインでフォワードレンダリングを使用している場合は、品質設定でマルチサンプルアンチエイリアシング(MSAA)を使用できます。MSAA は高品質のアンチエイリアシングを生成しますが、コストがかかる場合があります。ドロップダウン メニューの MSAA サンプル数(None、2X、4X、8X)は、レンダラーが効果の評価に使用するサンプル数を定義します。
URP または HDRP でフォワードレンダリングを使用している場合は、レンダーパイプラインアセットで MSAA を有効にできます。
または、ポストプロセス効果としてアンチエイリアシングを追加することもできます。これは、Camera コンポーネントの Anti-aliasing に表示されます。
- 高速近似アンチエイリアシング(FXAA)により、ピクセル レベルのエッジをスムージングします。これは、最もリソース消費の少ないアンチエイリアシングで、最終的な画像がわずかにぼやけます。
- サブピクセルモーフォロジカルアンチエイリアシング (SMAA) は、画像の境界に基づいてピクセルをブレンドします。これは FXAA よりもはるかにシャープな結果をもたらし、フラット、カートゥーン調、クリーンなアートスタイルに適しています。
HDRP では、FXAA および SMAA をカメラのポストアンチエイリアシング設定と併用することもできます。URPとHDRPには、追加オプションもあります。
- Temporal Anti-aliasing(TAA):履歴バッファのフレームを使用してエッジを平滑化します。これは FXAA よりも効果的に機能しますが、機能するにはモーションベクトルが必要です。TAAはアンビエントオクルージョンとボリューメトリックも改善できます。一般的に FXAA よりも高品質ですが、より多くのリソースを必要とし、ゴーストアーティファクトが時折発生する可能性があります。

STP(時空間ポストプロセッシング)は、モバイル、コンソール、PCなどの幅広いプラットフォームでビジュアル品質を向上させるように設計されています。STPは、HDRPとURPの両方のレンダー パイプラインで動作する時空間アンチエイリアシング アップスケーラーで、既存コンテンツに変更を加えることなく高品質のコンテンツ スケーリングを提供します。このソリューションは、特にGPUパフォーマンスに最適化されており、レンダリング時間を短縮し、ビジュアル品質を維持しながら高いパフォーマンスを簡単に実現できます。
URP で STP をイネーブルにするには、次の手順を実行します。
- Project ウィンドウでアクティブな URP アセットを選択します。
- Inspectorで品質>アップスケーリング フィルターを選択し、Spatial-Temporal Post-Processingを選択します。

ライティングを作成するための最も高速なオプションは、フレームごとに計算する必要のないオプションです。これを行うには、リアルタイムで計算するのではなく、ライトマッピングを使用して静的ライティングを一度だけ「ベイク」します。
グローバルイルミネーション(GI)を使用して静的ジオメトリにドラマチックなライティングを追加します。オブジェクトに Contribute GI マークを付けることで、ライトマップの形で高品質のライティングを保存できます。
ライトマップ環境の生成プロセスは、Unityでシーンにライトを配置するよりも時間がかかりますが、次の処理が可能です。
- 2ピクセルライトで 2~3 倍高速に動作
- 見た目が向上 – GI はリアルな直接光と間接光を計算できます。ライトマッパーは、結果のマップを平滑化およびノイズ除去します。
ベイクしたシャドウとライティングは、リアルタイムライティングとシャドウのパフォーマンスを落とさずにレンダリングできます。
複雑なシーンでは、長いベイク時間が必要になる場合があります。ハードウェアがプログレッシブGPUライトマッパーをサポートしている場合、このオプションを使用すると、ライトマップの生成が大幅にスピードアップし、場合によっては最大10倍になります。
このガイドに従って、Unity でライトマッピングの使用を開始してください。
![ライトマッピング設定([Windows]> [Rendering]> [Lighting Settings])とライトマップのサイズを調整して、メモリ使用量を制限します。](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fddcb9004d790152b8fb3fc0c5aa605639b7e210d-810x338.jpg&w=3840&q=75)
リフレクションプローブコンポーネントはリアルなリフレクションを作成できますが、バッチのコストが非常に高くなります。低解像度のキューブマップ、カリングマスク、テクスチャ圧縮を使用して、ランタイムのパフォーマンスを改善します。Use Type:フレームごとの更新を避けるためにベイクしました。
Type を使用している場合:URP ではリアルタイムが必要です。可能な場合は、Every Frame を避けてください。「Refresh Mode」と「Time Slicing」の設定を調整して、更新頻度を下げます。Via Scriptingオプションを使用して更新を制御し、カスタム スクリプトからプローブをレンダリングすることもできます。
Type を使用している場合:HDRP ではリアルタイムが必要です。オンデマンド モードを使用してください。フレーム設定は、「Project Settings」>「HDRP Default Settings」でも変更できます。パフォーマンスを向上させるために、リアルタイム リフレクションの品質と機能を減らします。
リアルタイム リフレクションの品質と機能を下げて、パフォーマンスを向上させます。

Unity 6では、APV(アダプティブプローブボリューム)が導入されています。APVは、Unityでグローバルイルミネーションを処理するための洗練されたソリューションを提供し、複雑なシーンでダイナミックで効率的なライティングを可能にします。APVは、特にモバイルおよびローエンドのデバイスでパフォーマンスとビジュアル品質の両方を最適化できる一方で、ハイエンドプラットフォーム向けの上級者向け機能を提供します。
APV は、特にダイナミックで大きなシーンでグローバルを強化する範囲な機能を提供します。URPが頂点ごとのサンプリングをサポートするようになり、ローエンドのデバイスでのパフォーマンスが向上しました。一方、VFXパーティクルはプローブボリュームにベイクされた間接光のメリットを享受できます。
APVデータをディスクからCPUおよびGPUにストリーミングできるため、大規模な環境向けにライティング情報を最適化できます。開発者は、複数のライティング・シナリオをベイクおよびブレンドして、昼夜サイクルなどのリアルタイムの遷移を行うことができます。また、スカイオオクルージョンをサポートし、レイセクター API と統合してプローブ計算を効率化し、ライトプローブのサンプル密度を制御してライトを減らし、イテレーションをスピード化します。新しいC#ベイキングAPIでは、ライトマップやリフレクション プローブから独立したAPVのベイキングも可能になります。
APV の使用を開始するには、GDC 2023 の講演「Efficient and impactful lighting with Adaptive Probe Volumes」をご覧ください。

シャドウキャストは、MeshRenderer とライトごとに無効にできます。描画コールを減らすために、可能な限りシャドウを無効にします。
また、キャラクターの下のシンプルなメッシュやクアッドに適用されたぼやけたテクスチャを使用して、フェイクシャドウを作成することもできます。また、カスタムシェーダーでブロブシャドウを作成することもできます。
特に、ポイントライトのシャドウを有効にしないでください。シャドウを持つ各ポイントライトには、ライトあたり6つのシャドウマップ パスが必要です 。スポットライトのシャドウマップ パスが1つであるのと比較してください。ダイナミックシャドウがどうしても必要な場合は、ポイントライトをスポットライトに置き換えることを検討してください。ダイナミックシャドウが回避できる場合は、代わりにポイントライトでキューブマップをライト.cookieとして使用します。

場合によっては、ライトを複数追加するのではなく、簡単なテクニックを適用することもできます。例えば、カメラに直接当たるライトを作成してリムライティング効果を与える代わりに、リムライティングをシミュレートするシェーダーを使用します(HLSL での実装については、サーフェスシェーダーの例を参照してください)。
ライトが多数ある複雑なシーンでは、オブジェクトをレイヤーで分離し、各ライトの影響を特定のカリングマスクに限定します。

GPUライトマッパーは、Unity 6で製品版として使用できます。GPUを活用してライティング データの生成を大幅に高速化し、従来のCPUライトマッピングと比較してベイク時間を大幅に短縮します。コードベースを簡素化し、より予測可能な結果をもたらす新しいライトベイキングバックエンドが導入されています。さらに、GPU の最小要件が 2GB に引き下げられ、ランタイム時にライトプローブの位置を移動する新しい API も搭載されました。これは、プロシージャルに生成されたコンテンツに特に有用で、また、さまざまな品質・オブ・ライフ(QOL)の改善も含まれています。


Unity Best Practices Hubでは、上級者向けのUnity開発者およびクリエイター向けのベストプラクティスやヒントをさらに多数見つけることができます。Unity のツールセットやシステムを使って効率的に開発するのにヘルプ、業界のエキスパートや Unity のエンジニア、テクニカルアーティストが作成した 30 以上のガイドからお選びください。