You can declare shader keywords so shaders behave differently when you enable or disable the keywords.
You can declare shader keywords in regular graphics shaders including surface shaders, and compute shaders.
To declare shader keywords, use a #pragma
directive in the HLSL code. For example:
#pragma shader_feature REFLECTION_TYPE1 REFLECTION_TYPE2 REFLECTION_TYPE3
You can use one of the following shader directives:
Shader directive | Branching type | Shader variants Unity creates |
---|---|---|
shader_feature |
Static branching | Variants for keyword combinations you enable at build time |
multi_compile |
Static branching | Variants for every possible combination of keywords |
dynamic_branch |
Dynamic branching | No variants |
Read more about when to use which shader directive.
The keywords in a single #pragma
statement are together called a ‘set’. You can enable or disable multiple keywords in a set at the same time.
For example, to declare a set of three keywords:
#pragma shader_feature REFLECTION_TYPE1 REFLECTION_TYPE2 REFLECTION_TYPE3
You can declare multiple sets of keywords in a single shader. For example, to create 2 sets:
#pragma shader_feature REFLECTION_TYPE1 REFLECTION_TYPE2 REFLECTION_TYPE3
#pragma shader_feature RED GREEN BLUE WHITE
You can’t do the following:
dynamic_branch
and shader_feature
or multi_compile
- Unity uses dynamic_branch
if you do this.To mark parts of your shader code conditional based on whether you enable or disable a shader keyword, use an HLSL if statement.
例
#pragma multi_compile QUALITY_LOW QUALITY_MED QUALITY_HIGH
if (QUALITY_LOW)
{
// code for low quality setting
}
You can enable and disable keywords using the Inspector or C# scripting.
What Unity does with your shader code depends on which shader directive you use.
If you use dynamic_branch
, Unity creates a uniform Boolean variable for each keyword. When you enable a keyword, Unity sets the Boolean for that variable to true
, and your GPU switches to using the code in the if
statement for that keyword. This is dynamic branching.
If you use shader_feature
or multi_compile
, Unity creates separate shader variants for each keyword state. Each variant contains the code from an if
branch for that keyword. When you enable a keyword, Unity sends the matching variant to your GPU. This is static branching.
Read more about when to use which shader directive.
You can also use the following HLSL statements to create conditional code:
Using these instead of if
makes it more difficult to change the #pragma
keyword directive later. For example, if you need to reduce the number of shader variants, it’s more difficult to change multi_compile
to shader_feature
.
Keywords are global by default.
Add _local
to the shader directive to make the keywords local. If you enable or disable a global keyword, you don’t affect the state of local keywords with the same name.
例
#pragma shader_feature_local QUALITY_LOW QUALITY_MED QUALITY_HIGH
When you declare a keyword, Unity assumes all stages of the shader contain conditional code for that keyword.
You can add the following suffixes to indicate that only certain stages contain conditional code for a keyword. This helps Unity strip unneeded shader variants.
_vertex
_fragment
_hull
_domain
_geometry
_raytracing
For example, use #pragma shader_feature_fragment RED GREEN BLUE
to indicate that you use the 3 keywords to create conditional code in the fragment stage only.
You can’t add these suffixes to #pragma dynamic_branch
because dynamic_branch
doesn’t create variants.
These suffixes may behave differently or have no effect depending on the graphics API:
_geometry
and _raytracing
suffixes have no effect on Metal, and Metal treats _vertex
, _hull
and _domain
as a single stage.You can add keywords to #pragma require
and #pragma target
directives, so conditional code only runs if the current hardware uses a particular shader model or GPU feature.
For more information, see Targeting shader models and GPU features in HLSL.
If you use shader_feature
to create a single keyword, Unity automatically creates a second variant for when the feature is disabled. This helps reduce the number of keywords you need to enable and disable. For example, the following code creates 2 variants:
# pragma shader_feature EXAMPLE_ON
If you use multi_compile
, or you use shader_feature
to create a set of two or more keywords, you can use _
when you declare a keyword set. Unity creates a shader variant for situations when all keywords in that set are disabled.
#pragma multi_compile _ EXAMPLE_ON
#pragma shader_feature _ RED GREEN BLUE WHITE
You can use Unity shader directive shortcuts to create sets of shader variants. The following example explains how to add SHADOWS_DEPTH
and SHADOWS_CUBE
variants:
#pragma multi_compile_shadowcaster
You can remove keywords you don’t need using skip_variants
. For example, use the following to remove POINT
and POINT_COOKIES
variants when Unity generates variants from multi_compile_fwdadd
.
# pragma multi_compile_fwdadd
# pragma skip_variants POINT POINT_COOKIE
以下のショートカットは、ビルトインレンダーパイプラインのライト、影、ライトマッピングに関するものです。
multi_compile_fwdbase
は、以下のキーワード群を追加します。DIRECTIONAL LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON SHADOWS_SCREEN SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING LIGHTPROBE_SH。これらのバリアントは、PassType.ForwardBase で必要となります。multi_compile_fwdbasealpha
は、以下のキーワード群を追加します。DIRECTIONAL LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING VERTEXLIGHT_ON LIGHTPROBE_SH。これらのバリアントは、PassType.ForwardBase で必要となります。multi_compile_fwdadd
は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE。これらのバリアントは、PassType.ForwardAdd で必要となります。multi_compile_fwdadd_fullshadows
は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE SHADOWS_DEPTH SHADOWS_SCREEN SHADOWS_CUBE SHADOWS_SOFT SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING。これは multi_compile_fwdadd
と同じですが、ライトがリアルタイムの影を作れるようになります。multi_compile_lightpass
は、以下のキーワード群を追加します。POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE SHADOWS_DEPTH SHADOWS_SCREEN SHADOWS_CUBE SHADOWS_SOFT SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING。これは事実上、ライトプローブ以外に、リアルタイムのライトと影に関連するすべての機能の包括的なショートカットです。multi_compile_shadowcaster
は、以下のキーワード群を追加します。SHADOWS_DEPTH SHADOWS_CUBE。これらのバリアントは、PassType.ShadowCaster に必要です。multi_compile_shadowcollector
は、以下のキーワード群を追加します。SHADOWS_SPLIT_SPHERES SHADOWS_SINGLE_CASCADE。multi_compile_shadowcollector
は、これらのキーワードをまったく含まないバリアントもコンパイルします。 これらのバリアントは、スクリーンスペースシャドウに必要です。multi_compile_prepassfinal
は、以下のキーワード群を追加します。LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON UNITY_HDR_ON SHADOWS_SHADOWMASK LIGHTPROBE_SH。multi_compile_prepassfinal
は、これらのキーワードをまったく含まないバリアントもコンパイルします。 これらのバリアントは PassType.LightPrePassFinal と PassType.Deferred に必要です。以下のショートカットは、他の設定と関連しています。
multi_compile_particles
は、ビルトインのパーティクルシステムに関連する以下のキーワードを追加します: SOFTPARTICLES_ON。multi_compile_particles
は、このキーワードを含まないバリアントもコンパイルします。詳しくは、Built-in Particle System を参照してください。multi_compile_fog
は、フォグに関連する以下のキーワードを追加します: FOG_LINEAR, FOG_EXP, FOG_EXP2。multi_compile_fog
は、このキーワードを含まないバリアントもコンパイルします。この動作は、Graphics 設定 ウィンドウ で制御できます。multi_compile_instancing
は、インスタンシングに関連するキーワードを追加します。シェーダーがプロシージャルなインスタンシングを使用する場合、以下の一連のキーワードを追加します: INSTANCING_ON PROCEDURAL_ON。そうでない場合は、INSTANCING_ON を追加します。また、multi_compile_instancing
は、これらのキーワードを含まないバリアントもコンパイルします。この動作は Graphics 設定 ウィンドウ で制御できます。