Version: 2021.3
言語: 日本語
シェーダーバリアント
C# スクリプトでのシェーダーキーワードの使用

シェーダーキーワード

Shader keywords allow you to use conditional behavior in your shader code. You can create shaders that share some common code, but have different functionality when a given keyword is enabled or disabled. You use with Shader variants.

このページには以下の情報が含まれています。

シェーダーキーワードの使用

シェーダーキーワードの宣言

シェーダーのキーワードはセットで宣言します。セットには、互いに排他的なキーワードが含まれます。

例えば、以下のセットには 3 つのキーワードが含まれています。

  • COLOR_RED
  • COLOR_GREEN
  • COLOR_BLUE

ノート: Shader Graph では用語が異なり、キーワードのセットは キーワード と呼ばれ、セット内のキーワードは ステート と呼ばれます。内部的には機能は同じで、例えば、Unity はこれらを同じ方法でコンパイルし、これらの扱いは C# スクリプトの場合と同様です。

シェーダーキーワードの宣言方法は、様々なことに影響します。

  • The type affects how Unity creates shader variants for the keywords.
  • スコープ は、キーワードがローカルとグローバルのどちらであるかに影響します。これによってランタイムの動作が決まります。
  • ステージ は、キーワードがどのシェーダーステージに影響を与えるかに影響します (該当する場合)。

Definition type: “multi compile” or “shader feature”

When you declare a set of keywords, you must also choose how Unity defines the keywords internally; this affects the number of variants that Unity compiles.

  • “multi compile” または “shader feature”: これを使用して、シェーダーバリアントで使用するキーワードのセットを作成します。内部的には、Unity はこれらのキーワードを使用して #define プリプロセッサーディレクティブを作成します。
    • “multi compile” は、シェーダーバリアントで使用するキーワードのセットを宣言します。

      Unity はセット内の全てのキーワードのシェーダーバリアントをコンパイルします。
    • “shader feature” は、シェーダーバリアントで使用するキーワードのセットを宣言し、また、これらのキーワードのいずれも有効になっていないバリアントをコンパイルするようにコンパイラーに指示します。

      Unity は、プロジェクトの状態をビルド時に調査し、使用されているキーワードのバリアントのみをコンパイルします。ビルドに含まれるマテリアルで有効になっているキーワードは、使用されています。

“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 では、頂点ステージをターゲットとする全てのキーワードはテッセレーションステージにも影響し、逆もまた同様です。

この値を設定するには:

  • ハンドコーディングされたシェーダーでは、HLSL のシェーダーキーワードの宣言と使用 を参照してください。
  • Shader Graph では、この値を設定することはできません。デフォルトで、全てのキーワードが全てのステージに影響します。

シェーダーキーワードで動作を条件付きにする

シェーダーキーワードを使用してシェーダーの一部を条件付きにすることで、特定の動作を、特定のキーワードが特定の状態にある時にだけ実行されるようにすることができます。

これは以下の手順で行えます。

シェーダーキーワードの有効化と無効化

You can enable or disable shader keywords. When you enable or disable a shader keyword, Unity renders the appropriate shader variant, or the GPU executes the appropriate branch.

以下の 2 つの方法で、シェーダーキーワードを有効化/無効化できます。

Unity の定義済みシェーダーキーワード

Unity は、定義済みシェーダーキーワードのセットを使用して、共通の機能を実現するシェーダーバリアントを生成します。

Unity は、コンパイル時に以下のシェーダーバリアントキーワードのセットを追加します。

  • デフォルトでは、Unity は全てのグラフィックスシェーダープログラムに、STEREO_INSTANCING_ON, STEREO_MULTIVIEW_ON、STEREO_CUBEMAP_RENDER_ON、UNITY_SINGLE_PASS_STEREO のキーワードセットを加えます。これらのキーワードはエディタースクリプトを使ってストリッピングできます。詳しくは シェーダーバリアントのストリッピング を参照してください。
  • デフォルトでは、Unity はスタンダードシェーダーに LIGHTMAP_ON、DIRLIGHTMAP_COMBINED、 DYNAMICLIGHTMAP_ON、LIGHTMAP_SHADOW_MIXING、SHADOWS_SHADOWMASK のキーワードセットを加えます。これらのキーワードは、Graphics 設定 ウィンドウを使ってストリッピングできます。
  • ビルトインレンダーパイプラインで、互いに異なる ティア設定 をプロジェクトに使用している場合、Unity は、UNITY_HARDWARE_TIER1、UNITY_HARDWARE_TIER2、UNITY_HARDWARE_TIER3 のキーワードセットを全てのグラフィックスシェーダーに加えます。詳細は グラフィックスティア: グラフィックスティアとシェーダーバリアント を参照してください。

シェーダーキーワードの制限

Unity can use up to 4,294,967,294 global shader keywords. Individual shaders and compute shaders can use up to 65,534 local shader keywords.

この合計数には、シェーダーのソースファイル内で宣言された全てのキーワードとその依存関係が含まれます。依存関係には、シェーダーが UsePass で含める パス や、フォールバック が含まれます。

Unity が同じ名前のシェーダーキーワードに複数回遭遇する場合は、1 回だけカウントされます。

シェーダーが合計で 128 個より多い数のキーワードを使用する場合、小さなランタイムパフォーマンスペナルティが発生します。したがって、キーワードの数は少なくすることが推奨されます。Unity は常に 1 つのシェーダーにつき 4 つのキーワードを確保します。

シェーダーバリアント
C# スクリプトでのシェーダーキーワードの使用