Shader
Shader
Shader
DreamShader » DreamShaderLang » Shader
A top-level block that declares one Unreal material asset: its parameters, its render-state settings, its output bindings, and the node graph that feeds them.
| Declared in | .dsm — a .dsh holding one is DSH2249 (see Source files) |
| Kind | top-level block |
| Generates | UMaterial (Graph backend) or UDreamShaderMaterialInstance + a hidden UMaterial base (ThinCustom backend) |
| Multiplicity | at most one per file (see Notes) |
Synopsis
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( … ) } ; … }]
}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.
The keyword Shader is matched case-sensitively; section names are matched
case-insensitively. See Lexical elements.
A .dss writes the same material as #pragma material(...), uniforms and one
export void <Name>(inout material m) — see DreamShaderLang 2.0;
dsc migrate rewrites a .dsm that way.
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 (name= works). Values may be quoted or bare; a bare
value ends at the first , or ). A duplicate key keeps the later value, with the warning
DSH2244 (since 2.0.0; silent before). A trailing comma before
) is accepted, as in 1.x (2.0.0 – 2.1.0 refused it with
DSH2243).
Full Name / Root grammar, the accepted root spellings, and the resulting on-disk path are
specified in Asset paths.
Sections
| Section | Accepted | Repeat behaviour | Reference |
|---|---|---|---|
Properties | yes | appends | Properties |
Settings | yes | merges; last key wins, a key written twice is the warning DSH3262 | Shader settings |
Outputs | yes | appends | Output bindings |
Graph | yes | the later body wins, with the warning DSH2258 | Graph |
Layout | yes | resets — a second Layout discards the first, with the warning DSH2258 | Layout |
Code | no — DSH2246 | — | — |
Inputs | no — unknown section, DSH2245 | — | — |
Results | no — unknown section, DSH2245 | — | — |
Options | no — unknown section, DSH2245 | — | — |
Properties in a Shader declares parameter, const and UE.* builtin nodes. This is not the
same grammar Properties gets inside a VirtualFunction, where it is a
synonym for Inputs.
The Outputs / Graph relationship
Outputs holds two kinds of statement, disambiguated per statement:
| Statement shape | Meaning |
|---|---|
<type> <name> ; | output-variable declaration; the Graph must assign it |
<type> <name> = <expression> ; | initialized output declaration (since 1.3.4) |
<target> = <variable> ; | output binding — Base.<Property> or Expression( … ).Pin[<i>] |
Expression( … ) { Pin[<i>] = <variable> ; … } | block form — several pins on one terminal node (since 1.9.0) |
The rule that governs whether Graph is required is evaluated after the whole block is read:
- A
Shaderwith noGraphsection and an emptyOutputsisDSH2255. Without aGraph, theOutputsstatements have to compute the values themselves — an output declaration with an initializer, or (since 2.0.0) a binding whose right side is an expression, such asBase.FrontMaterial = Substrate.Layer(Coat, Body);. - An empty
Graph = { }is legal. - Bindings are what actually connect the material. A
Shaderwith noOutputssection is the warningDSH2256: the material builds, with nothing wired to it (since 2.0.0; through 1.9.x generation then failed).
// 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 = { }
}Generated asset
Name + Root resolve to a package path exactly as described in
Asset paths. Which UClass lands there depends on the resolved
backend:
| Backend | Asset written | Notes |
|---|---|---|
Graph | UMaterial | the node graph is built directly on the material |
ThinCustom (since 1.5.0) | UDreamShaderMaterialInstance whose parent is a hidden UMaterial subobject named MB_DreamThinBase_<leaf> | one asset, one package; parameter overrides you set on the instance are yours to keep — a rebuild captures them and puts back every name the new base still declares (since 1.9.0), see Divergence |
Instance | alias for ThinCustom (deprecated in 1.5.0) |
The backend comes from Settings = { Backend = "…"; } if present, otherwise from the project's
Default Compiler Backend setting. See Backend and
Project settings.
[!NOTE] A
Graph-backendUMaterialis an ordinary asset and is saved on every successful build (since 2.0.0). AThinCustomproduct stays Ephemeral — in memory, no package on disk — until a cook, an explicit Materialize, or a child instance gives it one, and once it has a package it stays on disk. See Ephemeral materials.
[!WARNING] Regeneration clears the target graph. Node positions not pinned by
Layout, added nodes, node property tweaks, and comment boxes whose text begins withDreamShader:are destroyed. Only comment boxes that do not carry theDreamShader:prefix survive. Under the ThinCustom backend the instance's parameter overrides are cleared too, but they are captured first and restored afterwards (since 1.9.0) — a parameter the source no longer declares is the one case that loses its value. See Regeneration.
Notes
- At most one
Shaderper file (DSH2250). Through 1.9.x imports were inlined into one text before parsing, so the rule spanned the import closure; a header is read on its own now and cannot hold aShader(DSH2249), so animportnever adds one. The.dshcheck reads tokens, not text: a comment that mentionsShader(is fine. See Source files. Shader()with no attributes isDSH2242, the missingName.Shadermay share a.dsmwithVirtualFunction,Function,GraphFunctionandNamespaceblocks, which are helpers of the material, and withShaderFunction,ShaderLayerandShaderLayerBlendblocks: one compile of the file builds them all, each into its own asset, and the material may call such a function by name (2.0.0 – 2.1.0 refused it withDSH6201). AShaderin a.dsfisDSH2259.- A
.dsmthat declares noShaderblock is still compilable — it simply produces whatever function assets it does declare. - Binding
Base.MaterialAttributesturns on Use Material Attributes on the material. See Output bindings forBase.FrontMaterialand the other targets.
Diagnostics
Every stage reports all of its errors, each at its own line and column (since 2.0.0).
Parse time
| Code | Raised when |
|---|---|
DSH2241 | Shader is not followed by its attribute list |
DSH2242 | the attribute list has no Name, or an empty one |
DSH2243 | a malformed attribute list — a missing key, = or value, a missing , or ) |
DSH2244 | (warning) an attribute written twice |
DSH2250 | a second Shader block in the file |
DSH2249 | a Shader block in a .dsh |
DSH2257 | the body {, a section name, or a section's { is missing |
DSH2245 | a section other than Properties, Settings, Outputs, Graph and Layout |
DSH2246 | a Code section |
DSH2258 | (warning) a Graph or Layout section written twice |
DSH2255 | no Graph section, and an empty Outputs |
DSH2256 | (warning) no Outputs section |
DSH2150 | the file ends inside the block |
Bind and generation time
| Code | Raised when |
|---|---|
DSH4210 | a property, a function or another name declared twice |
DSH7202 | Settings = { Backend = … } names no backend; Instance is read as ThinCustom with the warning DSH7204 |
DSH8200 | Name / Root do not resolve to a valid asset path |
DSH8201 | the material could not be created or reused — the target path holds another class, or an asset DreamShader did not generate; the reason is appended |
DSH8203 | the same, for a ThinCustom instance |
DSH8206 | the asset is open in an asset editor, so it was not rebuilt |
DSH8207 | the asset was edited by hand since it was generated, so it was not rebuilt; the reason it carries is the DSH8115 text — see Divergence |
The messages of Properties, Settings, Outputs and Graph are on their own pages. Every code:
diagnostics.
Example
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);
}
}Generated asset:
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]
BaseTexis declared asTextureSampleParameter2D, not as the compactTexture2D, because only the sample-parameter family owns the input pins theBaseTex(Coordinates = UV)call form wires. A compactTexture2Dgenerates a texture object parameter, which has no such pins; calling it falls through to the function dispatcher and fails. See Using parameters in Graph.
See also
- Source files — which block kinds each of
.dsm/.dsh/.dsfmay contain - DreamShaderLang 2.0 — the
.dssform of a material - Properties — the
Propertiessection grammar - Inputs / Outputs / Results — typed-parameter sections (functions only)
- Output bindings — the full
Base.*target catalogue andExpression(…).Pin[i] - Layout —
Node/Commentplacement directives and#Region - Graph — the statement/expression language inside
Graph - Shader settings — every key a
Shader'sSettingsaccepts - Backend —
GraphvsThinCustom, and the deprecatedInstancealias - Asset paths —
Name=+Root=→ package path - Ephemeral materials — memory-only generation and materializing to disk
- Regeneration — what survives a rebuild and what does not
- ShaderFunction — the reusable
UMaterialFunctionblock - Diagnostics — every code