Version: Unity 6 (6000.0)
Language : English
Shader keyword scope fundamentals
Declare shader keywords

Choose which type of keyword to use in shaders

When you declare a set of keywords, you choose whether to use them with shader variantsA verion of a shader program that Unity generates according to a specific combination of shader keywords and their status. A Shader object can contain multiple shader variants. More info
See in Glossary
or with dynamic branching.

  • “dynamic branch”: Use this to create a set of keywords for use with dynamic branching. Internally, Unity uses these keywords to create uniform variables.
  • “multi compile” or “shaderA program that runs on the GPU. More info
    See in Glossary
    feature”: Use this to create a set of keywords for use with shader variants. Internally, Unity uses these keyword to create #define preprocessor directives.
    • “multi compile” declares a set of keywords for use with shader variants.

      Unity compiles shader variants for all keywords in the set.
    • “shader feature” declares a set of keywords for use with shader variants, and also instructs the compiler to compile variants where none of these keywords are enabled.

      Unity examines the state of your project at build time, and only compiles variants for keywords that are in use. A keyword is in use if a material that is included in the build has that keyword enabled.

Whether to choose “multi compile” or “shader feature” 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# scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary
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.

There is no “one size fits all” approach to conditionals in shaders, and you should consider the advantages and disadvantages of each approach for a given shader, in a given project.

Which conditional to use depends on when you need the shader to switch to a different code branch:

Switch code branch while you’re editing

If you don’t need a shader to switch to a different code branch at runtime, you can use conditionals that Unity only evaluates while you’re editing.

For example you can set up a property in a Material’s InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary
window to make a shader do the following:

  • Add specular reflections to some instances of a material but not others.
  • Add a different look to certain objects, such as objects that appear in underwater scenesA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
    See in Glossary
    .

If you use this approach, shader code is simpler to write and maintain, and less likely to affect build time, file size and performance.

To do this, use one of the following:

If you use the shader_feature keyword definition, Unity keeps shader variants used by Materials in your build, and removes (‘strips’) other shader variants. This keeps build times low and file sizes small.

Avoid using a C# script to enable or disable shader_feature keywords at runtime, because if a Material uses a shader variant that’s missing, Unity chooses a different available variant instead. If you do need to enable or disable keywords at runtime, use one of the following approaches to make sure your build includes all the variants you need:

Switch code branch at runtime

If you need to use C# scripting to make the shader switch to a different code branch at runtime, you can use conditionals that Unity evaluates both while you’re editing and at runtime.

For example you can use a C# script to make a shader do the following:

  • Change a Material dynamically so it has snow on it at certain times.
  • Change a Material when a user changes quality settings, for example to give users dynamic control over whether fog appears.

To do this, use one of the following:

If you use the multi_compile keyword definition, Unity builds a shader variant for every possible combination of shader code branches, including combinations that aren’t used by Materials in your build. This means you can enable and disable keywords at runtime, but it might also greatly increase build time, file size, load times and memory usage. See shader variants.

Dynamic branching doesn’t create shader variants, but may mean your shaders run more slowly on the GPU, especially if any of the following are true:

  • Your shaders run on a less capable GPU.
  • Your conditional code has ‘asymmetric branches’, where one branch is longer or more complex code than the other.

You can check how many shader variants you have to see whether you can use dynamic branching without affecting GPU performance too much. See shader branching for more on the advantages and disadvantages of dynamic branching.

Additional resources

Shader keyword scope fundamentals
Declare shader keywords