Version: 2022.1
HLSL로 그래픽스 API 및 플랫폼 타게팅
셰이더 시맨틱

HLSL에서 셰이더 키워드 선언 및 사용

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.

Declare shader keywords using pragma

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.

See shader keyword limits.

How sets of keywords work

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:

  • Include two keywords with the same name in one set.
  • Include duplicate keyword sets in one shader.
  • Declare a keyword as both dynamic_branch and shader_feature or multi_compile - Unity uses dynamic_branch if you do this.

Make shader behavior conditional

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.

Use other statements to make shader behavior conditional

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.

Make keywords local

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

Restrict keywords to shader stages

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:

  • The suffixes have no effect on OpenGL, OpenGL ES or Vulkan.
  • The _geometry and _raytracing suffixes have no effect on Metal, and Metal treats _vertex, _hull and _domain as a single stage.

Restrict keywords to shader models and GPU features

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.

Create a shader variant for disabled keywords

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

Use shortcuts to create keyword sets

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_prepassfinal는 LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON UNITY_HDR_ON SHADOWS_SHADOWMASK LIGHTPROBE_SH 키워드 세트를 추가합니다. 또한 이러한 키워드 없이도 배리언트를 컴파일합니다. PassType.LightPrePassFinalPassType.Deferred가 이러한 배리언트를 필요로 합니다.

다음 단축키는 기타 설정과 관련됩니다.

  • multi_compile_particles는 빌트인 파티클 시스템에 관련된 SOFTPARTICLES_ON 키워드를 추가합니다. 또한 이 키워드 없이도 배리언트를 컴파일합니다. 자세한 내용은 빌트인 파티클 시스템을 참조하십시오.
  • multi_compile_fog는 안개에 관련된 FOG_LINEAR, FOG_EXP, FOG_EXP2 키워드 세트를 추가합니다. 또한 이러한 키워드 없이도 배리언트를 컴파일합니다. Graphics settings 창에서 이 동작을 컨트롤할 수 있습니다.
  • multi_compile_instancing은 인스턴싱에 관련된 키워드를 추가합니다. 셰이더가 절차적 인스턴싱을 사용하는 경우 이 단축키는 INSTANCING_ON PROCEDURAL_ON 키워드 세트를 추가합니다. 이외의 경우에는 INSTANCING_ON 키워드를 추가합니다. 또한 이러한 키워드 없이도 배리언트를 컴파일합니다. Graphics settings 창에서 이 동작을 컨트롤할 수 있습니다.
HLSL로 그래픽스 API 및 플랫폼 타게팅
셰이더 시맨틱