シェーダーキーワードを使用すると、シェーダーコードで 条件付き動作 を使用できます。一部の共通のコードを共有する複数のシェーダーを作成し、特定の キーワード が有効または無効にされた時の機能をそれぞれ異なるものにすることができます。
シェーダーキーワードは 動的分岐 や シェーダーバリアント と一緒に使うことができます。シェーダーキーワードの使用を開始する前に、これらの技法がどのように機能するのか、またどれがプロジェクトに適しているのかを理解することが重要です。
このページには以下の情報が含まれています。
シェーダーのキーワードはセットで宣言します。セットには、互いに排他的なキーワードが含まれます。
例えば、以下のセットには 3 つのキーワードが含まれています。
ノート: Shader Graph では用語が異なり、キーワードのセットは キーワード と呼ばれ、セット内のキーワードは ステート と呼ばれます。内部的には機能は同じで、例えば、Unity はこれらを同じ方法でコンパイルし、これらの扱いは C# スクリプトの場合と同様です。
シェーダーキーワードの宣言方法は、様々なことに影響します。
キーワードのセットを宣言する際に、それらを シェーダーバリアント で使用するか、動的分岐 で使用するかを選択します。シェーダーバリアントを選択した場合は、Unity が内部的にキーワードをどのように定義するかも選択する必要があります (これは、Unity がコンパイルするバリアントの数に影響します)。
#define
プリプロセッサーディレクティブを作成します。
“multi compile” と “shader feature” のどちらを選択するかは、キーワードをどのように使用するかによって変わります。そのキーワードを使ってプロジェクトのマテリアルの設定を行い、ランタイムに C# スクリプトから値を変更しない場合は、“shader feature” を使用してプロジェクトのシェーダーキーワードとバリアントの数を減らしてください。ランタイムに C# スクリプトを使用してキーワードを有効化/無効化する場合は、“multi compile” を使用して、バリアントが誤ってストリッピングされるのを防いでください。シェーダーのストリッピングについての詳細は、シェーダーバリアントのストリッピング を参照してください。
ノート: Graphics 設定ウィンドウの Always Included Shaders のリストにシェーダーを追加すると、Unity は、ビルド内の全てのセットの全てのキーワードを (たとえそれが “shader feature” を使って宣言されていたとしても) 含めます。
この値を設定するには、以下のドキュメントを参照してください。
キーワードのセットを宣言する際に、セット内のキーワードがローカルとグローバルのどちらの スコープ を持つか選択します。これにより、ランタイムにグローバルシェーダーキーワードを使用してこのキーワードの状態をオーバーライドできるかどうかが決まります。
デフォルトでは、グローバルスコープでキーワードを宣言します。これは、ランタイムにグローバルシェーダーキーワードを使用してそのキーワードの状態をオーバーライドできることを意味します。ローカルスコープでキーワードを宣言すると、ランタイムにグローバルシェーダーキーワードを使用してキーワードの状態をオーバーライドできません。詳細およびコード例は、C# スクリプトでのシェーダーキーワードの使用 を参照してください。
ノート: 同じ名前のキーワードがシェーダーソースファイル内とその依存関係内に存在する場合、ソースファイル内のキーワードのスコープが、依存関係内のスコープを上書きします。依存関係は、Fallback コマンド を介して含まれている全てのシェーダーと、UsePass コマンド を介して含まれているパスで構成されます。
この値を設定するには、以下のドキュメントを参照してください。
デフォルトでは、Unity はシェーダーの各ステージに対してキーワードバリアントを生成します。例えば、シェーダーに頂点ステージとフラグメントステージが含まれている場合、頂点シェーダープログラムとフラグメントシェーダープログラムの両方に、キーワードの全ての組み合わせのバリアントが生成されます。また、あるキーワードセットがどちらか一方のステージでしか使われていない場合、もう一方のステージにも同じバリアントが生成されます。Unity は同じバリアントを自動的に識別して 複製しない ため、ビルドサイズは増加しませんが、それでもコンパイル時間が浪費され、シェーダーのロード時間が増加し、ランタイムのメモリ使用量が増加する結果となります。
この問題を回避するために、ハンドコーディングされたシェーダー内でキーワードのセットを宣言する際に、特定のシェーダーステージに関してのみコンパイルするように Unity に指示することができます。これを行った場合は、そのキーワードが指定のシェーダーステージでのみ使用されることを確認する必要があります。
ノート: 以下のグラフィックス API は、ステージ固有のキーワードを完全にはサポートしていません。OpenGL と Vulkan では、コンパイル時に、Unity が全てのステージ固有キーワードディレクティブを通常のキーワードディレクティブに自動的に変換します。Metal では、頂点ステージをターゲットとする全てのキーワードはテッセレーションステージにも影響し、逆もまた同様です。
この値を設定するには:
シェーダーキーワードを使用してシェーダーの一部を条件付きにすることで、特定の動作を、特定のキーワードが特定の状態にある時にだけ実行されるようにすることができます。
これは以下の手順で行えます。
シェーダーキーワードは有効にも無効にもできます。シェーダーキーワードを有効または無効にすると、シェーダーは適切な条件付き動作を表示します。キーワードがシェーダーバリアントと動的分岐のどちらで動作するかによって、Unity が適切なシェーダーバリアントをレンダリングするか、GPU が適切なブランチを実行するかの、いずれかになります。
以下の 2 つの方法で、シェーダーキーワードを有効化/無効化できます。
Unity は、定義済みシェーダーキーワードのセットを使用して、共通の機能を実現するシェーダーバリアントを生成します。
Unity は、コンパイル時に以下のシェーダーバリアントキーワードのセットを追加します。
Unity は最大 4,294,967,294 個のグローバルシェーダーキーワードを使用できます。個々のシェーダーとコンピュートシェーダーは最大 65,534 個のローカルシェーダーキーワードを使用できます。これらの合計数には、バリアントに使用されるキーワードと動的分岐に使用されるキーワードが含まれます。
この合計数には、シェーダーのソースファイル内で宣言された全てのキーワードとその依存関係が含まれます。依存関係には、シェーダーが UsePass で含める パス や、フォールバック が含まれます。
Unity が同じ名前のシェーダーキーワードに複数回遭遇する場合は、1 回だけカウントされます。
シェーダーが合計で 128 個より多い数のキーワードを使用する場合、小さなランタイムパフォーマンスペナルティが発生します。したがって、キーワードの数は少なくすることが推奨されます。Unity は常に 1 つのシェーダーにつき 4 つのキーワードを確保します。