DreamShaderLang
DreamShaderLang 2.0

材质实例

.dsi —— 把材质实例写成源码。一个父材质、它覆盖的属性和它设置的参数,并对照父材质真实的参数表做检查。

一个 .dsi 文件就是一个 UMaterialInstanceConstant:一个父材质、几个被覆盖的属性,以及它设置的参数。 它没有图,所以没有函数、没有 #include、也没有 #pragma material —— 只有一条 pragma 和若干 uniform 行。

项目值
产物一个 UMaterialInstanceConstant,以文件名命名,落在同位置的 .dss 会放产物的地方
检查依据父材质真实的参数 —— 名字、类型、是否静态
起始版本since 2.0.0
// MI_HeroSkin.dsi
#pragma instance(Parent = "M_Skin", BlendMode = Masked, TwoSided = true)

uniform float Roughness = 0.35;
uniform float3 Tint = float3(1.0, 0.82, 0.76);

/// @static
uniform bool UseDetail = true;

/// @default /Game/Characters/Hero/T_Hero_Skin_D
uniform Texture2D Albedo;

/// @name Base Color Boost
uniform float BaseColorBoost = 1.2;

父材质

Parent 要么是一个裸名字 —— 同一个源码根下由某个 DreamShader 源文件生成的材质或另一个实例 —— 要么是一个对象路径(/Game/Materials/M_Skin),指向任意材质或实例,不论是不是 DreamShader 生成的。

来自源码的父材质,如果资产不存在或比源码旧,会先被编译,所以构建实例时永远不会看到过期的参数表。 实例的实例可以用;成环的链会被拒绝。

覆盖

一条覆盖就是一个 uniform,按父材质声明该参数的方式来声明,带上它要设成的值。

父参数覆盖写法
标量uniform float Gain = 2.0; —— int 与 bool 参数也是标量
向量uniform float3 Tint = float3(0, 1, 0); —— float3 保留父材质的 alpha,float4 四个分量都设
静态开关/// @static + uniform bool UseDetail = false;
静态分量遮罩/// @static + uniform bool4 Mask = bool4(true, false, false, false);
纹理/// @default <资产> + uniform Texture2D Albedo; —— 不写初始值;/// @default None 表示清空
字体、Runtime Virtual Texture、Sparse Volume Texture、纹理 / 参数集合/// @default <资产> + 对应类型的 uniform
写错了什么诊断码
父材质没有的名字DSH7258 —— 只差大小写时是 DSH7264(引擎会悄悄什么都不设)
类型与父材质不一致DSH7259
编译器折不成常量的值DSH7265
@group、@sort、@slider、@desc —— 它们属于父材质DSH7262,警告
只存在于材质层或层混合上的参数DSH7268

名字不是标识符的参数,用任意标识符声明,再加 /// @name <真实名字>。从文件里删掉的覆盖, 下次构建时也会从资产里删掉:实例是按文件重建的,不是打补丁。

从编辑器来,回到编辑器去

  • Material Content Browser 的 New Instance 会在父材质源文件旁边写出一个 .dsi。
  • dsc decompile /Game/Materials/MI_Steel_Worn 写出的 .dsi 只包含与父材质不同的部分。
  • 被手改过的生成实例就是一次普通的手改分歧;Adopt Into Source 会逐个值地改写 .dsi,注释和顺序都保留。

本页目录