This documentation is for a prerelease version of O3DE. Click here to switch to the latest release, or select a version from the dropdown.

Version:

Shader Variant Options in Amazon Shading Language (AZSL)

Shader variant options are shader constants that are only used in conditional statements that can be statically optimized. You can choose to compile them as static constants or as global variables.

Consider the following AZSL code snippet, where a shader variant option is used in a conditional branch:

    if (o_useRed) {
        color = float3(1, 0, 0);
    } else {
        color = float3(0, 0, 1);
    }

In the shader code above, the value of o_useRed is not known at compilation time, so o_useRed is compiled as a shader constant. The shader byte code branches at runtime depending on the runtime value of o_useRed. In general, branching is slow and should be avoided.

In this scenario, if the value of o_useRed is defined as true at compilation time, then the compiler produces the following branch-less code.

    color = float3(1, 0, 0);

If o_useRed is defined as false at compilation time, then the compiler produces the following branch-less code:

    color = float3(0, 0, 1);

The example above produces three different versions of the compiled shader code. These are called shader variants (ShaderVariantAsset). The three shader variants produced in the example differ in two ways:

  • Whether or not the value of the shader variant option o_useRed is statically defined at compilation time.
  • The compilation time value for the o_useRed when the shader variant option is statically defined.

The table below describes the three shader variants created by the example.

o_useRed valueRuntime branch?Notes
undefinedyesSlower than branch-less shader code, but can be set at runtime. This is the root variant (Root ShaderVariantAsset).
truenoFaster because the value of o_useRed is baked in, and shader variant doesn’t branch at runtime.
falsenoFaster because the value of o_useRed is baked in, and shader variant doesn’t branch at runtime.

Using baked shader variant options provides maximum shader runtime performance but generates more shader variants (ShaderVariantAssets) in the Asset Cache.

Important:
If many shader variant options are declared in a shader, a large number of shader variant assets might be generated. This is particularly important to understand if the shader code has nested conditional statements that have shader variant options. A shader variant asset is generated for each possible combination shader variant options, which creates an exponential number of shader variants. For more information on this topic, refer to Shader Variant Options and the Fallback Key.