シェーダーバリアントがコンパイルされないようにすることができます。これはストリッピングと呼ばれています。不要なバリアントをストリッピングすると、ビルド時間、ファイルサイズ、シェーダーのロード時間、ランタイムのメモリ使用量を大幅に削減できます。大規模なプロジェクトや複雑なシェーダーを持つプロジェクトでは、これは非常に重要な考慮すべき事項です。
ランタイムにマテリアルに必要なシェーダーバリアントをストリッピングすると、Unity は使用可能な類似のシェーダーバリアントを選択しようとします。これを回避するには、以下のアプローチを使用します。
shader_feature キーワードを使用する場合は、ランタイムに実行するコード分岐の変更にこのキーワードを使用しないでください。以下のシェーダーキーワードの宣言方法によって、生成されるバリアントの数を制限することができます。
multi_compile の代わりに shader_feature を使用します。シェーダーの条件を参照してください。multi_compile で使わないキーワードを定義しないようにします。ハンドコーディングされたシェーダーでこれをキーワードを宣言する方法について詳しくは、HLSL でのシェーダーキーワードの宣言と使用を参照してください。Shader Graph でのキーワードの宣言については、Shader Graph: ブラックボードを参照してください。
キーワードを宣言すると、Unity はシェーダーのすべてのステージにそのキーワードの条件付きコードがあると見なします。
以下の接尾辞を追加して、特定のステージにのみキーワードの条件付きコードがあることを示すことで、Unity が不要なシェーダーバリアントを生成しないようにすることができます。
_vertex_fragment_hull_domain_geometry例えば、#pragma shader_feature_fragment RED GREEN BLUE を使用して、3 つのキーワードを使用してフラグメントステージでのみ条件コードを作成することを示します。
dynamic_branch はバリアントを作成しないため、これらの接尾辞を #pragma dynamic_branch に追加することはできません。
これらのサフィックスは、グラフィックス API によって動作が異なる、または効果がない場合があります。 例:
_geometry サフィックスと _raytracing サフィックスは Metal には効果がありません。Metal は _vertex、_hull、および _domain を 1 つのステージとして扱います。Unity 2021.3 以降では、ターゲットプラットフォームプリプロセッサーマクロを使用して条件付きシェーダーコードを作成できるため、メモリが制限されているプラットフォームのバリアントを制限できます。
コードサンプルは以下の処理を行います。
SHADER_API_DESKTOP プラットフォーム用にビルドする場合、Unity は可能なキーワードの組み合わせごとにバリアントをビルドします。#ifdef SHADER_API_DESKTOP
#pragma multi_compile _ RED GREEN BLUE WHITE
#else
#pragma shader_feature RED GREEN BLUE WHITE
#endif
ターゲットプラットフォームのプリプロセッサーマクロを使用して、shader_feature、multi_compile、dynamic_branch のいずれかを選択できます。各タイプの条件を使用するタイミングの詳細については、シェーダー条件を参照してください。
メモリ制限のあるコンソールおよびモバイルプラットフォーム用にビルドする場合、少数の品質設定の切り替えのみをユーザーに許可することでシェーダーバリアントを制限できます。
例えば、キーワード DYNAMIC_LIGHTING、SOFT_SHADOWS、HIGH_QUALITY_LIGHTMAPS を使用すると、以下を作成できます。
DYNAMIC_LIGHTING をオンにする低品質設定。DYNAMIC_LIGHTING、SOFT_SHADOWS、HIGH_QUALITY_LIGHTMAPS をオンにする高品質設定。つまり、Unity はオフの場合、または 3 つのキーワードの多くのさまざまな組み合わせがオンとオフになっている場合に、DYNAMIC_LIGHTING のシェーダー バリアントを作成しません。
ターゲットプラットフォームプリプロセッサーマクロを使用すると、メモリが制限されているプラットフォームで、作成する品質設定やバリアントを条件付きで減らすことができます。例えば以下のコードサンプルでは、SHADER_API_DESKTOP プラットフォームでは 8 つの設定の組み合わせを切り替えることができますが、SHADER_API_MOBILE プラットフォームで切り替えることができるのは 2 つの設定のみです。
#if SHADER_API_DESKTOP
#pragma multi_compile SHADOWS_LOW SHADOWS_HIGH
#pragma multi_compile REFLECTIONS_LOW REFLECTIONS_HIGH
#pragma multi_compile CAUSTICS_LOW CAUSTICS_HIGH
#elif SHADER_API_MOBILE
#pragma multi_compile QUALITY_LOW QUALITY_HIGH
#pragma shader_feature CAUSTICS // Uses shader_feature, so Unity strips variants that use CAUSTICS if there are no Materials that use the keyword at build time.
#endif
Unity エディターの UI には、シェーダーストリッピングを設定できる箇所がいくつかあります。
Graphics Settings ウィンドウで、Shader stripping セクションの設定を行います。
Always-included shaders 設定で、必要のないシェーダーがないようにします。
GPU インスタンス化、ライトマッピング、フォグに関連するバリアントを除去します。
ビルトインレンダーパイプラインでは、ティア設定が違うことが重要でない場合は、同一のティア設定にしてください。詳細については、グラフィックスティアを参照してください。
ユニバーサルレンダーパイプライン (URP)では、URP アセットで使用しない機能を無効にします。詳細については、シェーダーストリッピングを参照してください。
ユニバーサルレンダーパイプライン (URP) を使用する場合は、以下も実行できます。
HD レンダーパイプライン (HDRP) を使用する場合は、以下も実行できます。
他の方法では除去できないシェーダーバリアントについては、エディタースクリプトで以下の API を使用してビルド時のストリッピングを行うことができます。
この件に関する詳細は、スクリプタブルシェーダーバリアントのストリッピングを参照してください。