间隔

间隔是一种根据特殊变量的值是否在特定范围内生成单个 shader``多个变体的方法。 可以使用 ``interval 关键字从 intfloat 着色器变量创建它们。 请看下面这个例子

int var;
interval var:below_zero<0, zero<1, positive_less_than_four<4, four<5, five_or_higher;
// float也一样

该声明将为着色器创建 5 种排列(below_zero, zero, positive_less_than_four, fourfive_or_higher),var`区间本身可以通过特殊的预处理器标记 ``##` 在 hlsl 块中访问。

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

必须明白,这种结构并不表示 var 等于 5,而是表示 var` 在声明的区间 five_or_higher 内,因此这种语法也适用于 float 数字。

Warning

请注意,不仅可以通过全局变量创建区间(如上例),还可以通过 staticdynamic 变量创建区间(在 局部变量 中描述)。

``static``变量上的间隔只在材料实例化过程中解析一次(选择适当的着色器变量),因此 ``static``变量的着色器变量不会在运行时切换。

然而,每次使用着色器进行渲染时(调用``setStates()``时),dynamic 和全局变量上的时间间隔都会被解析,因为这些变量在运行时会发生变化。 与``static``时间间隔相比,这对 CPU 性能的影响更大。

可选间隔

如果在 HLSL 代码块中使用了区间,则可以将此区间设为 optional。 HLSL 代码中所有使用 ``optional``区间的条件都将被 HLSL 分支取代,从而减少着色器变量的数量。

Warning

带有 optional 间隔的着色器只能用于 HLSL 块中的条件,并且需要使用 -optionalAsBranches 标志编译(否则 optional 间隔将与常规间隔相同)。 此功能只能用于开发构建。

int test_optional = 0;
optional interval test_optional : zero < 1, one < 2, two < 3, three;

shader testMaterial
{
  // ...
  hlsl
  {
    float3 color = float3(0, 0, 0);
##if test_optional == one
    color = float3(1, 0, 0);
##elif test_optional == two || test_optional == three
    color = float3(0, 0, 1);
##if test_optional == two
    color *= 0.5;
##endif

##else
    color = float3(0, 0, 1);
##endif
  }
}

假设

着色器变量可在编译时通过 assuming 指定一个固定值。这些着色器变量在运行时不会改变,其值在二进制文件中将保持不变。 这样可以减少着色器变量的数量,或禁用特定平台的特定功能。

你可以在着色器编译器的 .blk 配置文件中**假设**间隔。 为此,请在 ``Compile``块内创建一个 ``assume_vars``块,然后按照常规 .blk 语法指定您想要的假设:

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

通过假定一个纹理,例如 bloom_tex:i = 1,您可以声明该纹理永远不会是 NULL

假设语句

您可以在 DSHL 着色器中使用 ``assume interval_name = interval_value;``语句强制固定时间间隔。 当不同着色器共享相同的时间间隔时,这对于禁用不必要的着色器变量非常有用。

include "deferred_shadow_common.dshl"

shader deferred_shadow_classify_tiles
{
  assume use_ssss = off;
  // ...
}