ShaderLayer / ShaderLayerBlend
ShaderLayer / ShaderLayerBlend
ShaderLayer / ShaderLayerBlend
DreamShader » DreamShaderLang » ShaderLayer / ShaderLayerBlend
Two top-level blocks that declare Unreal's material-layer function assets: a layer, which produces one
MaterialAttributes value, and a layer blend, which combines two of them.
| Declared in | .dsf or .dsm, beside a Shader too; in a .dsh either one is DSH2249 (see Source files) |
| Kind | top-level block |
| Generates | UMaterialFunctionMaterialLayer (ShaderLayer) / UMaterialFunctionMaterialLayerBlend (ShaderLayerBlend) |
| Multiplicity | any number per file |
| Since | 1.3.0 |
The legacy front end reads a ShaderLayer as a 2.0 /// @layer export void L(inout material m) and a
ShaderLayerBlend as /// @layerblend export void B(material …, inout material Result); see
the 2.0 language and dsc migrate.
Synopsis
ShaderLayer(Name = "<asset-path>" [, Root = "<root>"])
{
[Properties [=] { <property-declaration> ; … }]
[Inputs [=] { MaterialAttributes <name> ; }]
{ Outputs | Results } [=] { MaterialAttributes <name> ; }
Graph [=] { <graph-statement> … }
[Settings [=] { <key> = <value> ; … }]
[Layout [=] { { Node( … ) | Comment( … ) } ; … }]
}ShaderLayerBlend(Name = "<asset-path>" [, Root = "<root>"])
{
[Properties [=] { <property-declaration> ; … }]
Inputs [=] { MaterialAttributes <name> ; MaterialAttributes <name> ; }
{ Outputs | Results } [=] { MaterialAttributes <name> ; }
Graph [=] { <graph-statement> … }
[Settings [=] { <key> = <value> ; … }]
[Layout [=] { { Node( … ) | Comment( … ) } ; … }]
}The = between a section name and its { … } block is optional sugar (since 1.5.0); a ; after a
section's closing } is optional. Sections may appear in any order and may be repeated.
Both keywords are matched case-sensitively, as whole words; section names are matched case-insensitively.
Header attributes
| Attribute | Required | Value | Effect |
|---|---|---|---|
Name | yes | string | The asset's logical path. The last /-separated segment is the asset name; preceding segments become folders. |
Root | no | string | The package root the folders hang off. Defaults to /Game when absent or empty. |
NoGeneration | no | true | false | (after 2.1.2) Only a compile that names the file builds this block's asset; see NoGeneration. Another value is DSH2260. |
Attribute keys are matched case-insensitively. Values may be quoted or bare; a bare value runs to the
next , or ) outside parentheses. A key written twice is a warning
(DSH2244) and the later value wins. A trailing comma
before ) is accepted, as in 1.x (2.0.0 – 2.1.0 refused it with
DSH2243). See
Asset paths.
Sections
Both blocks share the ShaderFunction body parser, so the section
table is identical.
| Section | Accepted | Repeat behaviour | Reference |
|---|---|---|---|
Properties | yes — function-local parameter, const and UE.* nodes; this is where layer controls belong | appends | Properties |
Inputs | yes — constrained, see below | appends | Inputs / Outputs / Results |
Outputs | yes — one MaterialAttributes output | appends | Inputs / Outputs / Results |
Results | yes — alias for Outputs, no warning | appends | Inputs / Outputs / Results |
Settings | yes — the keys a ShaderFunction honours | merges; a key written twice is a warning (DSH3262) | Function settings |
Graph | yes | the later one wins, with a warning (DSH2258) | Graph |
Layout | yes | the later one replaces the earlier, with DSH2258 | Layout |
Code | no — DSH2246 | — | — |
anything else, Options included | no — DSH2245 | — | — |
Interface rules
These are the rules that distinguish a layer or blend from a plain
ShaderFunction. (since 2.0.0) They are the 2.0 signature rules of @layer
and @layerblend, checked when the file is bound.
| # | Applies to | Rule | Code |
|---|---|---|---|
| 1 | both | a MaterialAttributes output is declared | DSH3278 |
| 2 | ShaderLayer | the material is all there is: any input that is not MaterialAttributes, and any output besides the material, breaks the signature | DSH6204 |
| 3 | ShaderLayerBlend | at least one MaterialAttributes input, and no output besides the material | DSH6205 |
A layer's material flows through it: (since 2.0.0) the layer always has exactly one
MaterialAttributes input, named after its output — also when the 1.x block declared no input at
all. A 1.x MaterialAttributes input with another name becomes that input, and the pin changes its
name with a warning (DSH3277); the body still reads it under
its 1.x name. The input is optional only when the 1.x input was declared opt.
A blend's output starts empty, and each of its inputs is a pin of its own. The binder takes any number
of MaterialAttributes inputs from one up; the engine's layer stack blends exactly two.
MaterialAttributes is one word, matched ignoring case; Material Attributes with a space is
DSH3271 (since 2.0.0). A missing Graph is not reported.
[!NOTE] Scalars, vectors and textures cannot be layer inputs — rule 2 rejects them. Expose them through
Propertiesinstead: they become parameter nodes inside the generated function and appear on the layer stack's parameter panel. Do the same for blend controls.
Blend input relevance (since UE 5.7)
On UE 5.7 and newer, each MaterialAttributes input of a ShaderLayerBlend gets a
BlendInputRelevance derived from its declared name. The name is normalized by removing spaces, _
and -, then compared case-insensitively.
| Normalized input name | BlendInputRelevance |
|---|---|
Top, TopLayer | Top |
Bottom, BottomLayer, Base, BaseLayer | Bottom |
anything else — the first MaterialAttributes input | Bottom |
anything else — a later MaterialAttributes input | Top |
Inputs of a ShaderLayer, and any non-MaterialAttributes input, get no relevance and keep the
engine's General. On UE 5.3 – 5.6 the property does not exist and nothing is written.
Generated asset
Name + Root resolve to a package path exactly as described in
Asset paths.
| Block | UClass created | EMaterialFunctionUsage |
|---|---|---|
ShaderLayer | UMaterialFunctionMaterialLayer | MaterialLayer |
ShaderLayerBlend | UMaterialFunctionMaterialLayerBlend | MaterialLayerBlend |
When an asset already exists at the target path it is reused if it is a subclass of the expected
class; the exact-class rule that applies to ShaderFunction is relaxed here.
Switching a block between ShaderFunction and ShaderLayer without moving or deleting the existing
asset therefore fails with DSH8110.
Everything else about generation — the honoured Settings keys, lazy property-node creation,
input/output Id preservation across regeneration, the source-hash skip, and what stops a rebuild —
is identical to ShaderFunction.
A blend's MaterialAttributes output starts as an empty material. A layer's starts as the material
that came in through its input — or empty, when the 1.x input had another name (see
Interface rules). Either way member writes such as Attrs.BaseColor = …; are
legal in the Graph. See MaterialAttributes.
Deprecated spellings
[!WARNING]
MaterialLayer(...)andMaterialLayerBlend(...)are deprecated since 1.3.0. Both still parse and generate exactly the same assets as their modern spellings, and each is a warning (DSH2251). UseShaderLayer/ShaderLayerBlendin new code.
| Deprecated spelling | Replacement | Behaves as |
|---|---|---|
MaterialLayer(Name = …) | ShaderLayer(Name = …) | identical: same sections, same rules, same asset |
MaterialLayerBlend(Name = …) | ShaderLayerBlend(Name = …) | identical |
A missing Name (DSH2242) names the spelling the author
actually typed.
Notes
- One compile of a file builds every asset it declares: every layer, blend and
ShaderFunctionof a.dsmor.dsf, and theShaderof a.dsm(2.0.0 – 2.1.0 refused aShaderbeside a layer or blend withDSH6201). See Source files. - The file-kind restriction is a parse, decided per block (since 2.0.0). A
.dshholding any of the four spellings isDSH2249; a comment or a string that mentionsShaderLayer(is fine. - The consumer of a layer or blend is Unreal's material layer stack on a material or material
instance. (since 2.0.0) Neither can be called from a
Graph:DSH6208. - The
Codesection is rejected outright (DSH2246); useGraph.
Diagnostics
Each code carries the line and column of the construct; the code's page has the message. The
parse-time codes of the shared body parser — attributes, sections, parameter statements, metadata,
Settings — are listed on ShaderFunction § Diagnostics.
| Code | Raised when |
|---|---|
DSH2251 | MaterialLayer or MaterialLayerBlend (warning) |
DSH2242 | no Name, or an empty one |
DSH3278 | no MaterialAttributes output |
DSH3277 | the layer's MaterialAttributes input is renamed after the output (warning) |
DSH6204 | a ShaderLayer with any other input or output |
DSH6205 | a ShaderLayerBlend without a MaterialAttributes input, or with another output |
DSH6208 | a Graph calls a layer or blend |
DSH8110 | an asset of an incompatible class is at the target path |
The emit-time codes for the asset itself — DSH8111,
DSH8112, DSH8114,
DSH8206, DSH8207 — are
a ShaderFunction's.
On success the compile output has a Generated <Kind> <AssetPath> from <SourceFile>. line, <Kind>
being MaterialLayer or MaterialLayerBlend.
The complete cross-stage list lives in the diagnostics index.
Example
ShaderLayer(Name="Layers/L_Rust", Root="Game")
{
Properties = {
Group("Rust") {
vec3 RustColor = vec3(0.35, 0.13, 0.05) [Description="Base colour of the rust"];
float RustRough = 0.85 [Slider(0, 1)];
}
}
Outputs = {
MaterialAttributes Attrs;
}
Graph = {
Attrs.BaseColor = RustColor;
Attrs.Roughness = RustRough;
Attrs.Metallic = 0.0;
}
}
ShaderLayerBlend(Name="Layers/LB_Wear", Root="Game")
{
Properties = {
float WearAmount = 0.5 [Slider(0, 1); Description="0 keeps Bottom, 1 keeps Top"];
}
Inputs = {
MaterialAttributes Bottom;
MaterialAttributes Top;
}
Outputs = {
MaterialAttributes Attrs;
}
Graph = {
Attrs.BaseColor = lerp(Bottom.BaseColor, Top.BaseColor, WearAmount);
Attrs.Roughness = lerp(Bottom.Roughness, Top.Roughness, WearAmount);
Attrs.Normal = lerp(Bottom.Normal, Top.Normal, WearAmount);
}
}Generated assets:
package /Game/Layers/L_Rust
object path /Game/Layers/L_Rust.L_Rust
class UMaterialFunctionMaterialLayer (usage: MaterialLayer)
in Attrs MaterialAttributes (the material the layer is applied to; required, no `opt` input in the source)
out Attrs MaterialAttributes
package /Game/Layers/LB_Wear
object path /Game/Layers/LB_Wear.LB_Wear
class UMaterialFunctionMaterialLayerBlend (usage: MaterialLayerBlend)
in Bottom MaterialAttributes (BlendInputRelevance: Bottom, UE 5.7+)
in Top MaterialAttributes (BlendInputRelevance: Top, UE 5.7+)
out Attrs MaterialAttributes
parameters WearAmount ScalarParameter, slider 0..1See also
- ShaderFunction — the plain
UMaterialFunctionblock these two specialize - Shader — the
UMaterial-producing top-level block - VirtualFunction — declaring an existing
UMaterialFunctioninstead of generating one - Source files — which block kinds each of
.dsm/.dsh/.dsfmay contain - Keywords — the complete keyword index, including deprecated spellings
- Properties — the
Propertiessection grammar,Group(…)scopes andconst - Inputs / Outputs / Results — the typed-parameter grammar in full
- MaterialAttributes — the value type these blocks are built around
- Function settings — the keys a material-function
Settingshonours - Asset paths —
Name=+Root=→ package path - Regeneration — what survives a rebuild and what does not
- Diagnostics index — every code, by stage