.. _conditionals: ============ 条件 ============ **HLSL 外部代码块** ``if``, ``else``, ``else if`` 指令用于在 DSHL 中对不同着色器变体执行条件编译。 示例: .. code-block:: c 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`` 关闭它们。示例 .. code-block:: c hlsl { ##if tex != NULL float somefloat = 1.0; ##endif } **maybe 本征** ``maybe()`` 本征可以在 bool-表达式中使用。 它的参数是任何标识符。如果该标识符不是布尔变量,本征将返回 false,否则返回布尔变量的值。 .. code-block:: c 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`` 关键字声明多个着色器,并在着色器名称上执行条件语句即可: .. code-block:: c 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 个不同的着色器,即 ``one``、 ``two`` 和 ``three``,它们将为 ``var``分配不同的值。 .. note:: 请勿将此功能与 intervals :ref:`intervals` 混淆。 它不会创建单个着色器的变体,而是创建名称不同的着色器。