ビルトインレンダーパイプラインでは、グラフィックス階層 を使用して、アプリケーションを異なる性能のハードウェアで実行する場合に、さまざまなグラフィックス設定を適用することができます。Unity のビルトインの 階層設定 を使って一般的な設定を行ったり、独自のシェーダーコードや C# コードでカスタムの動作を定義することもできます。
ノート: この機能は、ビルトインレンダーパイプラインでのみサポートされています。他のレンダーパイプラインでは、Unity は起動時にハードウェアをチェックし、その値を Graphics.activeTier に保存します。ただし、このフィールドの値は何の効力もなく、Unity はグラフィックス階層に関連する他の操作を行いません。
Unity が最初にアプリケーションをロードするとき、ハードウェアとグラフィックス API を調査し、現在の環境がどのグラフィックス階層に対応しているかを判断します。
グラフィックス階層は以下の通り。
Value | Hardware | Corresponding GraphicsTier enum value | Corresponding shader keyword |
---|---|---|---|
1 | Android: devices that only support OpenGL ES 2 iOS: iPhones before iPhone 5S (not including 5S, but including 5C), iPods up to and including 5th generation, iPads up to 4th generation, iPad mini first generation Desktop: DirectX 9 XR: HoloLens |
Tier1 | UNITY_HARDWARE_TIER1 |
2 | Android: devices that support OpenGL ES 3, devices that support Vulkan iOS: iPhones starting from iPhone 5S, iPad Air, iPad mini 2nd generation, iPod 6th generation, AppleTV WebGL: all devices |
Tier2 | UNITY_HARDWARE_TIER2 |
3 | Desktop: OpenGL, Metal, Vulkan, DirectX 11+ | Tier3 | UNITY_HARDWARE_TIER3 |
Unity は、現在のグラフィックス階層の値を Graphics.activeTier に格納し、GraphicsTier enum で表します。現在のグラフィックス階層に基づいてカスタムの動作を加えるには、この値に対してテストします。
Graphics.activeTier
の値を上書きするには、それを直接設定します。グラフィックス階層に基づいて変化するシェーダーを Unity が読み込む前に、この設定を行う必要があります。この値を設定するのに適した場所は、メインシーンをロードする前のシーンです。
Unity エディターでは、階層設定 を行うことができます。階層設定では、各階層のグラフィックス機能を有効または無効にすることができます。
階層設定を行うには、Unity の内部シェーダーコードの #define
プリプロセッサーディレクティブを変更します。これらの変更は、自動的にビルトインレンダーパイプライン用の事前にビルドされたシェーダー (例えば、スタンダードシェーダー )や、サーフェスシェーダー 用の内部シェーダーライブラリコードに影響を与えます。また、独自に書いたシェーダーにコードを加え、階層設定に基づいて動作を変更することもできます。詳細については、グラフィックス階層とシェーダーバリアント を参照してください。
デフォルトの階層設定は、ほとんどのユースケースに適しています。パフォーマンスに問題がある場合や、デフォルトでは有効になっていない下位機種の機能を有効にしたい場合にのみ、設定を変更してください。
特定のビルドターゲットのグラフィックス階層ごとに、異なる階層の設定を行うことができます。階層設定の変更は、以下の方法で行うことができます。
エディターで階層設定をテストすることができます。これを行うには、Edit > Graphics Tier に移動し、Unity エディターで使用する階層を選択します。
ビルトインレンダーパイプラインでは、Unity はグラフィックス階層に対応した シェーダーバリアント を生成することができます。
ノート: これらの階層シェーダーバリアントは、通常のシェーダーバリアントとは異なります。ランタイムに Unity がシェーダーオブジェクトを CPU メモリにロードするとき、アクティブな階層のバリアントのみがロードされます。アクティブな階層のバリアントのみをロードし、他の階層のバリアントはロードしません。これにより、階層バリアントのランタイムへの影響を軽減することができます。
階層シェーダーバリアントを生成するために、Unity は以下の一連のシェーダーキーワード をすべてのグラフィックスシェーダーに加えます。
UNITY_HARDWARE_TIER1
UNITY_HARDWARE_TIER2
UNITY_HARDWARE_TIER3
これらのキーワードを HLSL コードで使用すると、他のシェーダーキーワードと同じように、下位または上位のハードウェアに対する条件付きの動作を記述することができます。例えば、以下のようになります。
# if UNITY_HARDWARE_TIER1
// Tier 1 デバイス用のコードをここに記述
# else
// 他のデバイス用のコードをここに記述
# endif
HLSL コードでのシェーダーキーワードの扱い方については、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。
Unity は、現在のビルドターゲットの階層設定に基づいて、以下のように階層シェーダーのバリエーションを自動的に生成します。
すべての階層シェーダバリアントを生成した後、Unity は、同一の階層シェーダバリアントを識別し、重複排除 します。つまり、2 つの階層の設定が同一である場合 (例えば、Tier 1 は異なるが、Tier 2 と Tier 3 は互いに同一である場合)、これらのバリアントはアプリケーションのファイルサイズを増やすことはなく、Unity がティアバリアントをロードする方法は、ロード時間やランタイムのメモリ使用量に影響を与えないことを意味します。ただし、これではコンパイル作業が冗長になってしまいます。
階層ごとに異なる設定を使用したいが、冗長な作業になることがわかっている場合 (例えば、アプリケーションが Tier 1 と Tier 2 のデバイスでしか実行されないことがわかっている場合)、他のバリアントと同じように、不要な階層のバリアントをコンパイルから取り除くスクリプトを使用できます。詳しくは、シェーダーバリアントの削除 を参照してください。
自動動作に加えて、シェーダーごとに階層シェーダーバリアントを生成するよう Unity に強制することもできます。これは、HLSL コードでこれらの定数を使用し、現在のビルドの階層設定が互いに異なるかどうかにかかわらず、確実に必要なバリアントをコンパイルしたい場合に便利です。
手動で、指定したシェーダーの階層シェーダーバリアントを Unity に生成させるには、HLSL コードで #pragma hardware_tier_variants
プリプロセッサーディレクティブを使用し、階層ごとのバリアントを生成したいグラフィックス API を指定します。
# pragma hardware_tier_variants gles3
このディレクティブで使用できる有効なグラフィックス API 名のリストについては、ターゲットのグラフィックス API を参照してください。#pragma
ディレクティブに関する一般的な情報については、pragma ディレクティブ を参照してください。