Conditionals
Outside HLSL blocks
if
, else
, else if
directives are used to perform conditional compilation of different shader variants in DSHL.
Example:
texture tex;
texture fallback;
int test_interval = 0;
interval test_interval:negative<0, less_than_two<2, more_than_two;
shader test_shader
{
if (tex != NULL)
{
(ps) { tex@smp2d = tex; }
}
else
{
(ps) { tex@smp2d = fallback; }
}
if (test_interval == positive)
{
(vs) { var@f4 = (0, 0, 0, 0); }
}
else if (test_interval == less_than_two)
{
(vs) { var@f4 = (1, 0, 0, 0); }
}
else
{
(vs) { var@f4 = (1, 0, 1, 0); }
}
}
For each branch of the conditional statement, there will be created some number of shader variants (determined by combinatorics). If branch is an exact duplicate of another, no variants will be created. These variants are to be switched in runtime, based on the values in the conditionals.
Inside HLSL blocks
It is possible to use similar directives ##if, ##elif, ##else, ##endif
inside hlsl{...}
blocks too with a special ##
preprocessor tag.
In this case, however, you need to close them with ##endif
in the end. Example:
hlsl
{
##if tex != NULL
float somefloat = 1.0;
##endif
}
maybe intrinsic
maybe()
intrinsic can be used in a bool-expression.
Its argument is any identifier. If this identifier is not a boolean variable, the intrinsic will return false, otherwise the value of this boolean variable.
if (wsao_tex != NULL) {
if (shader == ssao) {
bool use_wsao = true;
}
}
(ps) {
if (maybe(use_wsao)) {
foo@f4 = foo;
}
}
hlsl(ps) {
##if maybe(use_wsao)
return foo;
##endif
}
If you try to remove the maybe()
in this example, it will cause a compilation error, because the use_wsao
is not declared in all variants.
Creating multiple shaders with conditionals
Conditionals can also be used to define multiple shaders at once (for convenience).
You just declare multiple shaders with the shader
keyword and do a conditional statement on the shader’s name:
shader one, two, three
{
if (shader == one)
{
float var = 1.0;
}
else if (shader == two)
{
float var = 2.0;
}
else
{
float var = 0.0;
}
}
This example will result in compilation of 3 different shaders, namely one
, two
and three
,
which will have different values assigned to var
.
Note
Do not confuse this feature with intervals Intervals. It does not create variants of a single shader, but creates different shaders with different names.