材质

材质是着色器和资源(漫反射、法线和其他参数)的组合。

通常情况下,多个资产共享相同的着色器,但需要具有不同的纹理和属性。 在这种情况下,每个资产都将拥有自己的材质*实例*和特定资源。

DSHL 有一种方法可以在着色器中以通用的、非特定资产的方式访问这些纹理。

纹理

可以使用 material 关键字引用纹理。

作为着色器创建者,只需在代码中引用这些插槽,即可指定着色器必须有多少个 material.texture[..] 插槽。 然后,在编译着色器后,引用的纹理插槽将出现在着色器的 bindump 中。 例如,在 Asset Viewer 材质编辑器中选择着色器时,这些插槽就会显示出来,你就可以为它们指定想要的纹理。

使用示例

shader materials_example
{
  texture diffuse = material.texture.diffuse;
  texture normal = material.texture[1];
  // 至此,材质纹理通道已经定义,并可在资产查看器中查看

  (ps)
  {
    diffuse_tex@static = diffuse;
    normal_tex@static = normal;
  }
  // 现在可以通过 hlsl{} 块访问这些纹理了
}

Note

material.texture.diffuse 等同于 material.texture[0]

参数

除纹理外,材质还可以包含任意参数。 您可以在着色器中使用 “静态”( static)或 “动态”( dynamic)关键字将这些参数声明为局部变量,请查看 局部变量 了解两者的区别。 使用一些有意义的默认值来初始化它们是一种好的做法。

与纹理类似,这些参数将保存到着色器绑定块中,并可在重新编译着色器后在 “资产查看器 ”中进行编辑。

static float some_parameter = 1.5;
dynamic float4 another_parameter = (1, 2, 3, 4);

(ps)
{
  some_parameter@f1 = some_parameter;
  another_parameter@f4 = another_parameter;
}

Warning

如果没有必要,请勿使用 dynamic 参数,因为这会带来更多开销。请参阅 局部变量 获取更多信息。

双面渲染

DSHL 中有两个特殊的材质参数: two_sidedreal_two_sided。 这两个参数默认存在于**每个**材质中,并可在资产查看器中设置。

这些参数在 DSHL 中就像布尔值: 您可以对它们执行条件语句 条件 (这将导致创建着色器变体)。

if (two_sided)
{
  cull_mode = none;
}

two_sided 是一个提示,表示该材质的每个三角形都应从两侧渲染,因此应禁用该着色器的剔除功能(示例中已禁用)。

real_two_sided 是一个提示,表示将使用一个特殊的网格来渲染此着色器: 每个三角形都会被复制和翻转,因此网格的两面都会被渲染。 请注意,在这种情况下无需禁用剔除功能,因为我们使用的是*真正*的双面网格(因此得名)。

render_stage 指令

可以使用 render_stage <stage_name> 为着色器指定渲染阶段。

shader materials_example
{
  render_stage opaque;
  // ...
}

它用于根据渲染阶段区分 ShaderMesh 类中的不同材质(该类可包含许多材质和网格)。 (类中的不同材质(该类可能包含许多材质和网格)。

例如,您可以调用 ShaderMesh::getElems(STG_opaque) 从一个 ShaderMesh 中获取所有在其 DSHL 着色器中指定了 render_stage opaque 的材质。 如果您希望按特定顺序绘制材质,这将非常有用。

可用的阶段

  • opaque – 不透明

  • atest – alpha 测试

  • imm_decal – 即时贴花

  • decal – 贴花

  • trans – 半透明

  • distortion – 扭曲

还有一个 render_trans 传统别名用于 render_stage trans

Color write mask

可以使用 static int 材质参数来设置颜色遮罩 颜色书写掩码。 请注意,您需要同时为 所有 渲染目标指定遮罩。

static int writemask = 1904; // = (0b0111 << 4) | (0b0111 << 8)
// 其中 0b0111 是 RGB 的位掩码
color_write = static writemask;

// 1904 的写掩码相当于
// color_write[0] = rgb;
// color_write[1] = rgb;

此示例将渲染目标 1 和 2 的颜色写入掩码设置为 rgb``(如果您使用的是 ``writemask 材质参数的默认值)。 其他渲染目标的遮罩值为 0b0000,这意味着不会绘制任何内容。