条件

HLSL 外部代码块

if, else, else if 指令用于在 DSHL 中对不同着色器变体执行条件编译。

示例:

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); }
  }
}

对于条件语句的每个分支,将创建一定数量的着色器变体(由组合学决定)。 如果分支与另一个分支完全重复,则不会创建任何变体。 这些变体将在运行时根据条件语句中的值进行切换。

HLSL 内部代码块

hlsl{...} 块内也可以使用类似的指令 ##if, ##elif, ##else, ##endif 并使用特殊的 ## 预处理器标记。 不过,在这种情况下,您需要在最后用 ##endif 关闭它们。示例

hlsl
{
##if tex != NULL
  float somefloat = 1.0;
##endif
}

maybe 本征

maybe() 本征可以在 bool-表达式中使用。 它的参数是任何标识符。如果该标识符不是布尔变量,本征将返回 false,否则返回布尔变量的值。

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
}

如果试图删除本例中的 maybe(),会导致编译错误,因为 use_wsao 并未在所有变体中声明。

使用条件式创建多个着色器

为方便起见,条件语句还可用于一次性定义多个着色器。 只需使用 shader 关键字声明多个着色器,并在着色器名称上执行条件语句即可:

shader one, two, three
{
  if (shader == one)
  {
    float var = 1.0;
  }
  else if (shader == two)
  {
    float var = 2.0;
  }
  else
  {
    float var = 0.0;
  }
}

此示例将编译 3 个不同的着色器,即 onetwothree,它们将为 ``var``分配不同的值。

Note

请勿将此功能与 intervals 间隔 混淆。 它不会创建单个着色器的变体,而是创建名称不同的着色器。