DreamShaderLang
Settings

Backend

Graph versus ThinCustom — which object carries the graph, which one is addressable, and how the per-file setting resolves against the project default.

Backend selects how a source file is materialized: as a visible UMaterial node graph, or as a thin material instance over a hidden base material.

Shader(Name = "<asset-path>")
{
    Settings [=] {
        Backend = { "Graph" | "ThinCustom" | "Instance" };
    }
}

The value is matched case-insensitively after trimming and quote-stripping; quotes are optional. Backend is a special key and never reaches the reflection resolver. Its current form arrived in since 1.5.0.

Accepted values

ValueResolves toProduces
GraphGraphone UMaterial at the resolved asset path, with the node graph built directly on it
ThinCustomThinCustoma UDreamShaderMaterialInstance at the resolved asset path, parented to a hidden UMaterial named MB_DreamThinBase_…
InstanceThinCustomidentical to ThinCustom — deprecated in 1.5.0
(empty string)Graphas Graphnot the project default
(key absent)the project's Default Compiler Backendsee Precedence
anything elsehard error, Unsupported Backend '{Value}'. Supported values: Graph, Instance, ThinCustom.

Deprecated since 1.5.0

Use ThinCustom instead.

Backend = "Instance" is an alias for ThinCustom; the legacy graphless instance backend is retired and there is no runtime Instance backend left. The spelling is kept for one deprecation window so existing sources keep compiling, and it produces no diagnostic. Replace it with Backend = "ThinCustom"; — or delete the key and let the project default apply.

Backend = ""; resolves to Graph, not to the project default. Only omitting the key falls back to Default Compiler Backend. An empty value is otherwise indistinguishable from a typo, so prefer removing the whole statement.

Precedence

Settings = { Backend }Project Default Compiler BackendResolved backend
absentThinCustom (the shipped default)ThinCustom
absentInstanceThinCustom
absentGraphGraph
"Graph"anyGraph
"ThinCustom"anyThinCustom
"Instance"anyThinCustom
""anyGraph

An explicit Backend always wins over the project setting, which is documented on Project Settings.

Backend is resolved before any material object exists and before the rest of Settings is validated, so an unrecognized value fails the compile first and no other settings diagnostic is reported for that file.

What each backend produces

Graph

AspectBehaviour
Asset writtena UMaterial at the package path derived from Name and Root
Graphbuilt directly on the material, then laid out and recompiled
In-memory modethe package is flagged newly-created and its dirty flag cleared afterwards, so a Save All cannot silently persist it
Persist modethe package is marked dirty, source metadata is stamped, and the package is saved
Reuse conflictAsset '{ObjectPath}' already exists and is not a Material.

ThinCustom — the default

since 1.5.0
AspectBehaviour
Asset writtena UDreamShaderMaterialInstance — a UMaterialInstanceConstant subclass — at the resolved asset path. This instance is the addressable asset.
Hidden base name, in-memory modeMB_DreamThinBase_<sanitized Name> — the whole Shader Name, with every character outside [A-Za-z0-9_] replaced by _. Name="Docs/M_Tint" gives MB_DreamThinBase_Docs_M_Tint
Hidden base name, persist modeMB_DreamThinBase_<instance leaf name> — the instance's own object name, no path component. Name="Docs/M_Tint" gives MB_DreamThinBase_M_Tint
Base ownership, in-memory modeowned by the transient package, flagged public, standalone and transient
Base ownership, persist modea subobject of the instance, so the pair shares one package and one .uasset
Graph and settingsbuilt on the base; every Settings key lands there, not on the instance
Instance wiringparent set to the base, parameter overrides cleared, source path and hash stamped, static permutation updated
Reuse conflictAsset '{ObjectPath}' already exists and is not a DreamShader instance material. Delete it (or remove Backend="Instance") before switching backends.

UDreamShaderMaterialInstance overrides two engine behaviours:

OverrideRule
HasOverridenBaseProperties()forced true when the parent is a UMaterial — that is, for the root instance over the hidden base. Any other parent falls through to the stock implementation, so a child instance parented to a DreamShader instance shares the root's compiled shader map instead of compiling its own.
IsAsset()false while the package is newly created and Show In-Memory Materials In Content Browser is off. Memory-only materials are hidden from the Content Browser, asset-registry enumeration and save pickers. The setting is read live, on every call.

Both backends log a warning when in-memory generation is shadowed by an already-saved asset:

In-memory material mode: '{Asset}' already exists as a saved asset, which shadows in-memory
regeneration. Delete the saved asset to make it fully in-memory.

See In-memory Materials.

Changing the project default

Changing Default Compiler Backend while the editor is running regenerates every source file in memory and logs DreamShader default compiler backend changed; regenerating all source files in memory. If persisted generated assets exist, a notification points at the cleanup action:

{Count} previously generated asset(s) are still saved on disk and shadow the in-memory materials.
Run Tools > DreamShader > Clean Persisted Generated Assets to remove them.

Switching an individual material between backends leaves the previous asset behind, and the next compile hits one of the reuse-conflict errors above. Delete the stale asset, then regenerate.

Notes

  • The backend does not change the language surface. Both build a real node graph and accept the identical feature set; they differ only in which object carries the graph and which object is addressable.
  • Under ThinCustom, reading BlendMode or the shading model off the generated instance shows the value inherited from the hidden base — that is where the settings were written.
  • Neither backend writes a .uasset during ordinary editor work. Assets reach disk at cook time, through the commandlet, or through an explicit Materialize action.
  • Backend is honoured only in a Shader block. In a ShaderFunction Settings block it is one of the keys that is silently ignored.

Diagnostics

MessageCauseFix
Unsupported Backend '{Value}'. Supported values: Graph, Instance, ThinCustom.The value is not Graph, ThinCustom, Instance or empty.Fix the spelling, or remove the key to use the project default.
Asset '{ObjectPath}' already exists and is not a Material.Graph backend: the target path holds another UClass.Delete the stale asset and regenerate.
Asset '{ObjectPath}' already exists and is not a DreamShader instance material. Delete it (or remove Backend="Instance") before switching backends.ThinCustom backend: the target path holds a non-DreamShader object.
Failed to create ThinCustom base material for '{Name}'.The hidden base could not be created.
Cannot create a persisted ThinCustom base without an instance for '{Name}'.Persist mode reached base creation with no instance.
Failed to create ThinCustom base material for instance '{Name}'.The base subobject could not be created under the instance.

Informational messages worth recognising in the log:

MessageMeaning
Generated {Asset} from {File}.{Virtual}Graph backend success; {Virtual} is (virtual) for in-memory generation and empty otherwise
Generated DreamShader thin-custom material {Asset} from {File}.ThinCustom backend success
Skipped {Asset} from {File}; source hash is unchanged.the source-hash cache suppressed the rebuild
In-memory material mode: '{Asset}' already exists as a saved asset, …a saved asset shadows the memory-only one

Example

Shader(Name="Docs/M_ThinCustom", Root="Game")
{
    Properties {
        VectorParameter Tint = float4(0.2, 0.6, 1.0, 1.0) [Group="Look"];
    }

    Settings {
        Backend      = "ThinCustom";
        Domain       = "Surface";
        ShadingModel = "DefaultLit";
        BlendMode    = "Opaque";
        TwoSided     = true;
    }

    Outputs {
        vec3 Color;
        Base.BaseColor = Color;
    }

    Graph {
        Color = Tint.rgb;
    }
}

Generated assets, in persist mode:

package     /Game/Docs/M_ThinCustom
asset       /Game/Docs/M_ThinCustom.M_ThinCustom      UDreamShaderMaterialInstance
subobject   MB_DreamThinBase_M_ThinCustom             UMaterial  (hidden base, same package)

Settings applied to:  MB_DreamThinBase_M_ThinCustom
  BlendMode    = BLEND_Opaque
  ShadingModel = MSM_DefaultLit
  TwoSided     = true

In the editor's ordinary memory-only mode the instance is the same object, but the base is a separate transient-package object named MB_DreamThinBase_Docs_M_ThinCustom — the sanitized Name, not the leaf. The same file with Backend = "Graph"; instead produces a single UMaterial at /Game/Docs/M_ThinCustom carrying the graph and the settings itself.

Next

On this page