キーワードのセットを宣言するときは、シェーダーバリアントで使用するか、動的分岐で使用するかを選択します。
#define プリプロセッサーディレクティブが作成されます。
“multi compile” と “shader feature” のどちらを選択するかは、キーワードの使用方法によって異なります。キーワードを使ってプロジェクトのマテリアルを構成し、ランタイムに C# スクリプトで値を変更しない場合は、“shader feature” を使ってプロジェクトのシェーダーキーワードとバリアントの数を減らします。C# スクリプトを使用してランタイムにキーワードを有効または無効にする場合は、“multi compile” を使用し、バリアントが誤って削除 (ストリップ) されるのを防ぐ必要があります。シェーダーストリッピングの詳細については、シェーダーバリアントストリッピングを参照してください。
シェーダーにおける条件には、“全てのケースに適したアプローチ” はありません。個々のプロジェクトで、使用しているシェーダーを踏まえて、それぞれのアプローチのメリットとデメリットを検討する必要があります。
どちらの条件を使用すべきかは、どのタイミングでシェーダーを別のコードブランチに切り替える必要があるかによって変わります。
ランタイムでシェーダーを別のコードブランチに切り替える必要がない場合は、Unity が編集中にのみ評価する条件を使用できます。
例えば、マテリアルの Inspector ウィンドウでプロパティを設定して、シェーダーに以下のような動作をさせることができます。
このアプローチを用いることで、シェーダーコードの記述と管理が行いやすくなり、ビルド時間やファイルサイズ、パフォーマンスに悪影響を及ぼしにくくなります。
これを行うには、以下のいずれかを使用してください。
shader_feature を使用してキーワードを宣言し、if 文で評価します。
shader_feature キーワード定義を使用すると、Unity はビルドでマテリアルが使用するシェーダーバリアントを保持し、他のシェーダーバリアントを削除 (“ストリップ”) します。これにより、ビルド時間を短く、ファイルサイズを小さく抑えることができます。
ランタイムに shader_feature キーワードを有効または無効にする C# スクリプトの使用は避けてください。欠落しているシェーダーバリアントをマテリアルが使用する場合、代わりに別の使用可能なバリアントが選択されるためです。ランタイムにキーワードを有効または無効にする必要がある場合は、以下のいずれかの方法を使用して、ビルドに必要なすべてのバリアントが含まれていることを確認します。
shader_feature キーワードの組み合わせごとにマテリアル 1 つをビルドに含めます。
C# スクリプティングを使用してランタイムでシェーダーを別のコードブランチに切り替える必要がある場合は、Unity が編集中およびランタイムの両方で評価する条件式を使用できます。
例えば、C# スクリプトを使ってシェーダーに以下のような処理をさせることができます。
これを行うには、以下のいずれかを使用してください。
multi_compile を使用してキーワードを宣言し、if 文で評価します。
multi_compile キーワード定義を使用すると、Unity では、ビルドのマテリアルで使用されていない組み合わせも含めて、シェーダーコードブランチの考えられるすべての組み合わせに対して、シェーダーバリアントがビルドされます。これは、ランタイムでキーワードを有効化/無効化できることを意味しますが、ビルド時間、ファイルサイズ、ロード時間、メモリ使用量が大幅に増加する可能性もあります。シェーダーバリアントを参照してください。
動的分岐はシェーダーバリアントを作成しませんが、特に、以下のいずれかが当てはまる場合には、GPU でのシェーダーの動作が遅くなる可能性があります。
シェーダーバリアントの数をチェックすることで、GPU パフォーマンスにあまり影響を与えずに動的分岐を使用できるかどうかを確認することができます。動的分岐のメリットとデメリットについては、シェーダーにおける分岐を参照してください。