Shader
Shader
Shader
DreamShader » DreamShaderLang » Shader
一个顶层块,用于声明一个 Unreal 材质资产:其参数、渲染状态设置、输出绑定以及为它们提供输入的节点图。
| 声明于 | .dsm — 包含它的 .dsh 是一个 DSH2249(参见源文件) |
| 类型 | 顶层块 |
| 生成 | UMaterial(Graph 后端)或 UDreamShaderMaterialInstance + 一个隐藏的 UMaterial 基础(ThinCustom 后端) |
| 多重性 | 每个文件最多一个(参见备注) |
概要
Shader(Name = "<asset-path>" [, Root = "<root>"])
{
[Properties [=] { <property-declaration> ; … }]
[Settings [=] { <key> = <value> ; … }]
[Outputs [=] { { <output-declaration> ; | <output-binding> ; | Expression( … ) { Pin[i] = <source> ; … } } … }]
[Graph [=] { <graph-statement> … }]
[Layout [=] { { Node( … ) | Comment( … ) } ; … }]
}节名与其 { … } 块之间的 = 是可选的语法糖 (自 1.5.0 起);节结束 } 之后的 ; 是可选的。各节可以以任意顺序出现,并且可以重复。
关键字 Shader 采用区分大小写匹配;节名采用不区分大小写匹配。参见词法元素。
一个 .dss 写入的材质与 #pragma material(...)、uniform 和一个 export void <Name>(inout material m) 相同 — 参见 DreamShaderLang 2.0;dsc migrate 会按该方式重写一个 .dsm。
头部属性
| 属性 | 必需 | 值 | 效果 |
|---|---|---|---|
Name | 是 | 字符串 | 资产的逻辑路径。最后一个由 / 分隔的段是资产名称;前面的段成为文件夹。 |
Root | 否 | 字符串 | 文件夹所依附的包根目录。缺省或为空时默认为 /Game。 |
NoGeneration | 否 | true | false | (2.1.2 之后) 只有指定该文件名的编译才会构建此块的资产;参见 NoGeneration。另一个值是 DSH2260。 |
属性键采用不区分大小写匹配(name= 也可以)。值可以带引号或不带引号;不带引号的值在第一个 , 或 ) 处结束。重复的键保留后一个值,并给出警告 DSH2244 (自 2.0.0 起;之前为静默)。) 之前的尾随逗号可被接受,与 1.x 相同 (2.0.0 – 2.1.0 曾以 DSH2243 拒绝它)。
完整的 Name / Root 语法、可接受的根目录拼写以及最终生成的磁盘路径在资产路径中说明。
节
| 节 | 可接受 | 重复行为 | 参考 |
|---|---|---|---|
Properties | 是 | 追加 | 属性 |
Settings | 是 | 合并;后一个键胜出,重复写入同一个键会给出警告 DSH3262 | 着色器设置 |
Outputs | 是 | 追加 | 输出绑定 |
Graph | 是 | 后一个主体胜出,并给出警告 DSH2258 | 图 |
Layout | 是 | 重置 — 第二个 Layout 会丢弃第一个,并给出警告 DSH2258 | 布局 |
Code | 否 — DSH2246 | — | — |
Inputs | 否 — 未知节,DSH2245 | — | — |
Results | 否 — 未知节,DSH2245 | — | — |
Options | 否 — 未知节,DSH2245 | — | — |
Shader 中的 Properties 声明参数、const 和 UE.* 内置节点。这不是 Properties 在 VirtualFunction 内部所使用的同一语法,在那里它是 Inputs 的同义词。
Outputs / Graph 关系
Outputs 包含两种语句,按语句进行消歧:
| 语句形式 | 含义 |
|---|---|
<type> <name> ; | 输出变量声明;Graph 必须为其赋值 |
<type> <name> = <expression> ; | 带初始化的输出声明 (自 1.3.4 起) |
<target> = <variable> ; | 输出绑定 — Base.<Property> 或 Expression( … ).Pin[<i>] |
Expression( … ) { Pin[<i>] = <variable> ; … } | 块形式 — 在一个终端节点上有多个引脚 (自 1.9.0 起) |
决定 Graph 是否必需的规则在整个块读取完毕后进行求值:
- 一个没有
Graph节且Outputs为空的Shader是DSH2255。没有Graph时,Outputs语句必须自行计算这些值 — 带初始化器的输出声明,或者 (自 2.0.0 起) 右侧为表达式的绑定,例如Base.FrontMaterial = Substrate.Layer(Coat, Body);。 - 空的
Graph = { }是合法的。 - 绑定才是真正连接材质的部分。没有
Outputs节的Shader会给出警告DSH2256:材质可以构建,但没有任何连线 (自 2.0.0 起;到 1.9.x 为止则生成会失败)。
// Legal: no Graph body needed, the output declaration carries its own initializer.
Shader(Name="M_Flat")
{
Properties = { vec3 Tint = vec3(1.0, 0.2, 0.2); }
Outputs = {
vec3 Color = Tint;
Base.EmissiveColor = Color;
}
Graph = { }
}生成的资产
Name + Root 解析为包路径的方式与资产路径中所述完全一致。最终落在那里的是哪个 UClass 取决于解析出的后端:
| 后端 | 写入的资产 | 备注 |
|---|---|---|
Graph | UMaterial | 节点图直接构建在材质上 |
ThinCustom (自 1.5.0 起) | UDreamShaderMaterialInstance,其父级是一个名为 MB_DreamThinBase_<leaf> 的隐藏 UMaterial 子对象 | 一个资产,一个包;你在实例上设置的参数覆盖由你保留 — 重建会捕获它们,并恢复新基础仍然声明的每个名称 (自 1.9.0 起),参见分歧 |
Instance | ThinCustom 的别名 (自 1.5.0 起弃用) |
后端来自 Settings = { Backend = "…"; }(如果存在),否则来自项目的 Default Compiler Backend 设置。参见后端和项目设置。
[!NOTE]
Graph后端的UMaterial是一个普通资产,并在每次成功构建时保存 (自 2.0.0 起)。ThinCustom产物会保持**临时(Ephemeral)**状态 — 在内存中,磁盘上没有包 — 直到某次 cook、显式 Materialize 或子实例赋予它一个包;而一旦它有了包,就会保留在磁盘上。参见临时材质。
[!WARNING] 重新生成会清除目标图。未被
Layout固定的节点位置、添加的节点、节点属性调整,以及文本以DreamShader:开头的注释框都会被销毁。只有不带DreamShader:前缀的注释框会保留下来。在 ThinCustom 后端下,实例的参数覆盖也会被清除,但会先被捕获并在之后恢复 (自 1.9.0 起) — 源不再声明的参数是唯一会丢失其值的情况。参见重新生成。
备注
- 每个文件最多一个
Shader(DSH2250)。在 1.9.x 之前,导入会在解析前内联到一个文本中,因此该规则会跨越导入闭包;现在头文件会单独读取,因此不能包含Shader(DSH2249),所以import永远不会添加一个。.dsh检查读取的是 token,而不是文本:提及Shader(的注释没有问题。请参阅源文件。 - 没有属性的
Shader()是DSH2242,缺少的是Name。 Shader可以与VirtualFunction、Function、GraphFunction和Namespace块共享一个.dsm,这些块是材质的辅助块,并且也可以与ShaderFunction、ShaderLayer和ShaderLayerBlend块共享:对该文件的一次编译会将它们全部构建出来,每个都构建为各自的资源,并且材质可以按名称调用这样的函数 (2.0.0 – 2.1.0 曾以DSH6201拒绝这样做)。.dsf中的Shader是DSH2259。- 未声明任何
Shader块的.dsm仍然可以编译——它只会生成其声明的那些函数资源。 - 绑定
Base.MaterialAttributes会开启材质上的 Use Material Attributes。有关Base.FrontMaterial和其他目标,请参阅输出绑定。
诊断
每个阶段都会报告其所有错误,每个错误都在各自的行和列 (自 2.0.0 起)。
解析时
| 代码 | 触发条件 |
|---|---|
DSH2241 | Shader 后面没有其属性列表 |
DSH2242 | 属性列表没有 Name,或该列表为空 |
DSH2243 | 格式错误的属性列表——缺少键、= 或值,缺少 , 或 ) |
DSH2244 | (警告) 一个属性被写了两次 |
DSH2250 | 文件中出现第二个 Shader 块 |
DSH2249 | .dsh 中出现 Shader 块 |
DSH2257 | 正文 {、节名称或节的 { 缺失 |
DSH2245 | 出现 Properties、Settings、Outputs、Graph 和 Layout 以外的节 |
DSH2246 | 出现 Code 节 |
DSH2258 | (警告) Graph 或 Layout 节被写了两次 |
DSH2255 | 没有 Graph 节,且 Outputs 为空 |
DSH2256 | (警告) 没有 Outputs 节 |
DSH2150 | 文件在该块内结束 |
绑定与生成时
| 代码 | 触发条件 |
|---|---|
DSH4210 | 一个属性、一个函数或另一个名称被声明了两次 |
DSH7202 | Settings = { Backend = … } 未指定任何后端;Instance 被读取为 ThinCustom,并带有警告 DSH7204 |
DSH8200 | Name / Root 未解析为有效的资源路径 |
DSH8201 | 无法创建或复用材质——目标路径中存放着另一个类,或存放着 DreamShader 未生成的资源;原因会附加在后面 |
DSH8203 | 对于 ThinCustom 实例,情况相同 |
DSH8206 | 该资源已在资源编辑器中打开,因此未被重新构建 |
DSH8207 | 该资源自生成以来被手动编辑过,因此未被重新构建;其携带的原因是 DSH8115 文本——请参阅差异 |
Properties、Settings、Outputs 和 Graph 的消息位于各自的页面。所有代码:诊断。
示例
Shader(Name="Materials/M_Emissive", Root="Game")
{
Properties = {
Group("Look") {
vec3 Tint = vec3(1.0, 0.4, 0.1) [Description="Emissive tint"];
float Intensity = 2.0 [Slider(0, 10)];
}
TextureSampleParameter2D BaseTex = Path(Game, "Textures/T_Noise");
}
Settings = {
ShadingModel = "Unlit";
BlendMode = "Translucent";
TwoSided = true;
}
Outputs = {
vec3 Color;
float Alpha;
Base.EmissiveColor = Color;
Base.Opacity = Alpha;
}
Graph = {
vec2 UV = UE.TexCoord(Index = 0);
vec4 Tex = BaseTex(Coordinates = UV);
Color = Tex.rgb * Tint * Intensity;
Alpha = Tex.a;
}
Layout = {
Comment(Name="Sampling", X=-1200, Y=-200, W=900, H=400);
Node(Var="UV", X=-1100, Y=-120);
}
}生成的资源:
package /Game/Materials/M_Emissive
object path /Game/Materials/M_Emissive.M_Emissive
on disk <Project>/Content/Materials/M_Emissive.uasset (once Materialized, or under the Graph backend)[!NOTE]
BaseTex被声明为TextureSampleParameter2D,而不是紧凑的Texture2D,因为只有 sample-parameter 系列拥有BaseTex(Coordinates = UV)调用形式所连接的输入引脚。紧凑的Texture2D会生成一个纹理 对象 参数,而它没有这样的引脚;调用它会落到函数分发器并失败。请参阅 在 Graph 中使用参数。
另请参阅
- 源文件 —
.dsm/.dsh/.dsf各自可以包含哪些块类型 - DreamShaderLang 2.0 — 材质的
.dss形式 - 属性 —
Properties节语法 - 输入 / 输出 / 结果 — 类型化参数节(仅函数)
- 输出绑定 — 完整的
Base.*目标目录和Expression(…).Pin[i] - 布局 —
Node/Comment放置指令和#Region - Graph —
Graph内部的语句/表达式语言 - 着色器设置 —
Shader的Settings所接受的每个键 - 后端 —
Graph对比ThinCustom,以及已弃用的Instance别名 - 资源路径 —
Name=+Root=→ 包路径 - 临时材质 — 仅内存生成与落盘实体化
- 重新生成 — 重新构建后哪些内容会保留、哪些不会
- ShaderFunction — 可复用的
UMaterialFunction块 - 诊断 — 每个代码