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

シェーダーキーワード

ある共通のコードを持ちながら、特定の キーワード が有効または無効の場合に異なる機能を持つシェーダーを作成することができます。

内部的には、シェーダーキーワードは シェーダーバリアント を作成することによって機能します。シェーダーキーワードを使う前にシェーダーバリアントがどのように機能するか、そしてパフォーマンスやワークフローに与える潜在的な影響を理解することが重要です。このトピックに関する情報は、シェーダーバリアント を参照してください。

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

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

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

  • COLOR_RED
  • COLOR_GREEN
  • COLOR_BLUE

内部的には、シェーダーキーワードは #define プリプロセッサーディレクティブを使用します。シェーダーキーワードのセットを宣言すると、Unity は #define ディレクティブに合うシェーダーバリアントをコンパイルします。

ノート: Shader Graph では、用語が異なります。キーワードのセットを キーワード と呼び、セット内のキーワードを ステート と呼びます。Unity はこれらを同じようにコンパイルし、C# スクリプトなどと同じように扱うことができる、など内部的には機能は同じです。

宣言するキーワードの数とその方法は、Unity がコンパイルするシェーダーバリアントの数に大きな影響を与え、その結果、プロジェクトやアプリケーションのパフォーマンスに大きな影響を与えます。詳細については、シェーダーバリアント を参照してください。

ハンドコーディングされたシェーダーでこれをキーワードを宣言する方法については、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでキーワードを宣言するには、キーワード を参照してください。

ローカルまたはグローバルなスコープを持つキーワードの宣言

When you declare a set of keywords, you choose whether the keywords in the set have local or global scope. This affects Unity’s behavior when you enable and disable shader keywords. For more information on enabling and disabling shader keywords, see Using shader keywords with C# scripts.

ハンドコーディングされたシェーダーでこの値を設定するには、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでこの値を設定するには、キーワード を参照してください。

ノート: 同じ名前のキーワードがシェーダーソースファイル内とその依存関係内に存在する場合、ソースファイル内のキーワードのスコープが、依存関係内のスコープを上書きします。依存関係は、Fallback コマンド を介して含まれている全てのシェーダーと、UsePass コマンド を介して含まれているパスで構成されます。

定義タイプ: “マルチコンパイル” と “シェーダー機能”

キーワードのセットを宣言する場合、Unity がキーワードを定義する手法を選択します。これは、Unity がコンパイルするシェーダーバリアントの数に影響します。

  • “マルチコンパイル” はキーワードのセットを宣言します。

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

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

Which option is best depends on how you use the keywords. If you use the keywords to configure materials in your project and do not change their value from C# scripts at runtime, then you should use “shader feature” to reduce the number of shader keywords and variants in your project. If you enable and disable keywords at runtime using C# scripts, then you should use “multi compile” to prevent variants being stripped in error. For more information on shader stripping, see Shader variant stripping.

ハンドコーディングされたシェーダーでこの値を設定するには、HLSL でのシェーダーキーワードの宣言と使用 を参照してください。Shader Graph シェーダーでこの値を設定するには、キーワード を参照してください。

ステージ固有のキーワード

デフォルトでは、Unity はシェーダーの各ステージに対してキーワードバリアントを生成します。例えば、シェーダーに頂点ステージとフラグメントステージが含まれている場合、Unity は頂点シェーダープログラムとフラグメントシェーダープログラムの両方について、すべてのキーワードの組み合わせに対するバリアントを生成します。また、あるキーワードセットがどちらか一方のステージでしか使われていない場合は、もう一方のステージでも同じバリアントが生成されます。Unity は、同じバリアントを自動的に識別し、複製 します。そのため、ビルドサイズは増加しませんが、それでもコンパイル時間の無駄、シェーダーのロード時間の増加、ランタイムのメモリ使用量の増加につながります。

この問題を回避するために、ハンドコーディングされたシェーダーでキーワードのセットを宣言するときに、Unity に特定のシェーダーステージでのみコンパイルするように指示することができます。

ノート: キーワードが指定されたシェーダーステージでのみ使用されるように自身で管理する必要があります。

グラフィックス API サポート

Unity は、以下のグラフィックス API に対するステージ固有のキーワードディレクティブの使用を完全にはサポートしていません。

  • OpenGL と Vulkan: コンパイル時に、Unity はすべてのステージ固有のキーワードディレクティブを通常のキーワードディレクティブに自動的に変換します。
  • Metal: 頂点ステージを対象としたキーワードは、テッセレーションステージにも影響し、その逆も然りです。

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

シェーダーキーワードを使った条件付きコンパイル

シェーダーソースファイルのセクションをマークすることで、特定のキーワードが有効なときに使用されるバリアントにのみ、その機能を入れることができます。

これを行う方法は、ハンドコードのシェーダーと Shader Graph では異なります。ハンドコードシェーダーの手順については、シェーダーキーワードの定義と使用 を参照してください。Shader Graph の説明については、Shader Graph: Keyword Node を参照してください。

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

シェーダーキーワードを有効または無効にすることができます。シェーダーキーワードを有効または無効にすると、Unity はレンダリングに適切なシェーダーバリアントを使用します。

シェーダーキーワードの有効化無効化には 2 つの方法があります。

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.

Every keyword declared in the shader source file and its dependencies count towards this limit. Dependencies include Passes that the shader includes using UsePass, and fallbacks.

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

If a shader uses more than 128 keywords in total, it incurs a small runtime performance penalty; therefore, it is best to keep the number of keywords low.

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