材质
材质是着色器和资源(漫反射、法线和其他参数)的组合。
通常情况下,多个资产共享相同的着色器,但需要具有不同的纹理和属性。 在这种情况下,每个资产都将拥有自己的材质*实例*和特定资源。
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_sided 和 real_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,这意味着不会绘制任何内容。