ある共通のコードを持ちながら、特定の キーワード が有効または無効の場合に異なる機能を持つシェーダーを作成することができます。
内部的には、シェーダーキーワードは シェーダーバリアント を作成することによって機能します。シェーダーキーワードを使う前にシェーダーバリアントがどのように機能するか、そしてパフォーマンスやワークフローに与える潜在的な影響を理解することが重要です。このトピックに関する情報は、シェーダーバリアント を参照してください。
シェーダーのキーワードはセットで宣言します。セットには、互いに排他的なキーワードが含まれます。
例えば、以下のセットには 3 つのキーワードが含まれています。
内部的には、シェーダーキーワードは #define
プリプロセッサーディレクティブを使用します。シェーダーキーワードのセットを宣言すると、Unity は #define
ディレクティブに合うシェーダーバリアントをコンパイルします。
ノート: Shader Graph では、用語が異なります。キーワードのセットを キーワード と呼び、セット内のキーワードを ステート と呼びます。Unity はこれらを同じようにコンパイルし、C# スクリプトなどと同じように扱うことができる、など内部的には機能は同じです。
宣言するキーワードの数とその方法は、Unity がコンパイルするシェーダーバリアントの数に大きな影響を与え、その結果、プロジェクトやアプリケーションのパフォーマンスに大きな影響を与えます。詳細については、シェーダーバリアント を参照してください。
ハンドコーディングされたシェーダーでこれをキーワードを宣言する方法については、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでキーワードを宣言するには、キーワード を参照してください。
キーワードのセットを宣言する際には、セットのキーワードの スコープ がローカルかグローバルかを選択します。
グローバルキーワードとローカルキーワードは別のものです。グローバルキーワードはプロジェクト全体に影響し、ローカルキーワードは個々のシェーダーに固有です。
複数のシェーダーに対して同時にキーワードを有効にする予定がない限り、一般的にはローカルスコープでキーワードを宣言します。
ハンドコーディングされたシェーダーでこの値を設定するには、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでこの値を設定するには、キーワード を参照してください。ローカルおよびグローバルシェーダーのキーワードの有効化と無効化につ いては、C# スクリプトによるシェーダーキーワードの使用 を参照してください。
ノート: 同じ名前のグローバルキーワードとローカルキーワードがある場合、Unity はローカルキーワードを優先します。
キーワードのセットを宣言する場合、Unity がキーワードを定義する手法を選択します。これは、Unity がコンパイルするシェーダーバリアントの数に影響します。
どのオプションが最適かは、キーワードの使用方法によって異なります。キーワードを使ってプロジェクトのマテリアルを構成し、ランタイムに C# スクリプトから値を変更しない場合は、“シェーダー機能” を使ってプロジェクトのシェーダーキーワードとバリアントの数を減らします。C# スクリプトを使用してランタイムにキーワードを有効または無効にする場合は、“マルチコンパイル” を使用してバリアントが誤って除去されるのを防ぐ必要があります。シェーダーのストリッピングについての詳細は、シェーダーバリアントのストリッピング を参照してください。
ハンドコーディングされたシェーダーでこの値を設定するには、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでこの値を設定するには、キーワード を参照してください。
デフォルトでは、Unity はシェーダーの各ステージに対してキーワードバリアントを生成します。例えば、シェーダーに頂点ステージとフラグメントステージが含まれている場合、Unity は頂点シェーダープログラムとフラグメントシェーダープログラムの両方について、すべてのキーワードの組み合わせに対するバリアントを生成します。また、あるキーワードセットがどちらか一方のステージでしか使われていない場合は、もう一方のステージでも同じバリアントが生成されます。Unity は、同じバリアントを自動的に識別し、複製 します。そのため、ビルドサイズは増加しませんが、それでもコンパイル時間の無駄、シェーダーのロード時間の増加、ランタイムのメモリ使用量の増加につながります。
この問題を回避するために、ハンドコーディングされたシェーダーでキーワードのセットを宣言するときに、Unity に特定のシェーダーステージでのみコンパイルするように指示することができます。
ノート: キーワードが指定されたシェーダーステージでのみ使用されるように自身で管理する必要があります。
Unity は、以下のグラフィックス API に対するステージ固有のキーワードディレクティブの使用を完全にはサポートしていません。
ハンドコーディングされたシェーダーでこの値を設定するには、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。デフォルトではすべてのキーワードがすべてのステージに影響します。
シェーダーソースファイルのセクションをマークすることで、特定のキーワードが有効なときに使用されるバリアントにのみ、その機能を入れることができます。
これを行う方法は、ハンドコードのシェーダーと Shader Graph では異なります。ハンドコードシェーダーの手順については、シェーダーキーワードの定義と使用 を参照してください。Shader Graph の説明については、Shader Graph: Keyword Node を参照してください。
シェーダーキーワードを有効または無効にすることができます。シェーダーキーワードを有効または無効にすると、Unity はレンダリングに適切なシェーダーバリアントを使用します。
シェーダーキーワードの有効化無効化には 2 つの方法があります。
Unity では、一般的な機能を実現するために、あらかじめ定義されたシェーダーキーワードのセットを使用しています。コンパイル時に以下のシェーダーキーワードのセットを加えます。
グローバルシェーダーキーワードは 384 個までと制限されていますが、Unity はそのうち約 60 個を内部で使用しているため、実際の利用可能数は減ってしまいます。個々のシェーダーには、ローカルキーワードが 64 個までという制限があります。
シェーダーのソースファイルで宣言されたすべてのキーワードとその依存関係は、これらの制限数に含まれます。依存関係には、Pass が含まれ、UsePass や fallbacks を使用するシェーダーが含まれます。
Unity が同じ名前のシェーダーキーワードに複数回遭遇する場合は、制限数に 1 回カウントされます。