Intervals
Intervals are a way to generate multiple variants of a single shader
, based on whether the value of a special variable falls into specific range.
They can be created from an int
or float
shader variable using the interval
keyword.
Consider this example:
int var;
interval var:below_zero<0, zero<1, positive_less_than_four<4, four<5, five_or_higher;
// same goes for floats
This declaration will create 5 permutations of the shader (below_zero
, zero
, positive_less_than_four
, four
and five_or_higher
),
and the var
interval itself can be accessed in hlsl blocks with special preprocessor tag ##
.
int var;
interval var:below_zero<0, zero<1, positive_less_than_four<4, four<5, five_or_higher;
shader example_shader {
hlsl {
##if var == five_or_higher
...
##endif
}
}
It is essential to understand that this construction doesn’t mean that var
equals to 5
, but
it means var
is within the declared interval five_or_higher
, so this syntax applies to float
numbers as well.
Warning
Notice that intervals can be created not only from global variables (as in example above), but also from static
and dynamic
variables (described in Local variables).
Intervals on static
variables are resolved (appropriate shader variant is selected) only once during material instantiation, so
shader variants dependant on static
variables are not switched during runtime.
Intervals on dynamic
and global variables, however, are resolved each time the shader is used for rendering (on setStates()
call), because such variables can change during runtime.
This has worse CPU performance impact, compared to static
intervals.
Assumes
Shader variables can be assigned a fixed value when the shader is compiled by assuming. Such shader vars may not be changed at runtime, their values will be constant in the binary. This allows to reduce number of shader variants or disable specific features for specific platforms.
You can assume intervals inside a config .blk file for the shader compiler.
To do this, create an assume_vars
block inside a Compile
block and then specify the assumes you want, following regular .blk syntax:
Compile
{
// ...
assume_vars
{
include common_assumes.blk
supports_sh_6_1:i = 0
static_shadows_custom_fxaa:i=0
grass_use_quads:i=0
bloom_tex:i = 1
}
}
Note
By assuming a texture, e.g. bloom_tex:i = 1
, you declare that this texture is never NULL
.
Assume statement
You can use assume interval_name = interval_value;
statement in DSHL shaders to force an interval to be fixed.
This can be useful to disable unnecessary shader variants when the same interval is shared among different shaders.
Assumes are evaluated irrespective of static and dynamic intervals: if you put an assume statement inside a static or dynamic condition, it will be applied, and it will only be ignored if the condition is constant irrespective of variants.
Assumes to the same interval override each other in program order, and assumes in code override assumes from the blk.
If you need an assume that doesn’t override ones from blk or ones declared before as a default fallback, use
assume_if_not_assumed interval_name = interval_value;
include "deferred_shadow_common.dshl"
assume use_ssss = off;
shader deferred_shadow_classify_tiles
{
assume_if_not_assumed use_ssss = on; // use_ssss is still assumed to be off
// ...
}