dream-shader-decompile · git:20260802.8b61e01 · 2026-08-02 · sha256 7bf40db76d19611d
dream-shader-decompile git:20260802.8b61e01A
Immutable. This exact content never changes and is served at /api/v1/blob/7bf40db76d19611d.
--- name: dream-shader-decompile description: Export an existing Unreal UMaterial or UMaterialFunction back into DreamShaderLang source headlessly, so a hand-built material graph can be migrated to a text source file. Use when asked to decompile, export, reverse, convert, or migrate a material / material function / material layer asset to .dsm or .dsf. --- # dream-shader-decompile `<asset>` Walk an existing `UMaterial` / `UMaterialFunction` node graph and write the equivalent DreamShaderLang source. This is the front half of a migration; the back half is [`dream-shader-optimize`](../dream-shader-optimize/SKILL.md). Paths below are relative to the plugin root, `Plugins/DreamShader/`. ## Run it ```bash pwsh -File Plugins/DreamShader/.skill/dsc.ps1 decompile /Game/Materials/M_Steel ``` ```bash pwsh -File Plugins/DreamShader/.skill/dsc.ps1 decompile /LGUI/Materials/LexUI_RectBlock -Out I:/Work/LexUI_RectBlock.dsm ``` Exit `0` writes the file and logs where: ```text LogDreamShader: Display: DreamShader decompiled '/Game/DreamShaderSkillProbe/M_SkillProbe.M_SkillProbe' to '…/M_SkillProbe.roundtrip.dsm'. dsc: OK (exit 0) ``` Without `-Out` the destination is computed from the asset's package path: | Asset class | Lands in | Extension | | :-- | :-- | :-- | | `UMaterial` | `DShader/Decompiled/Materials/<package path>` | `.dsm` | | `UMaterialFunction` | `DShader/Decompiled/Functions/<package path>` | `.dsf` | | `UMaterialFunctionMaterialLayer` | `DShader/Decompiled/Layers/<package path>` | `.dsf` | | `UMaterialFunctionMaterialLayerBlend` | `DShader/Decompiled/LayerBlends/<package path>` | `.dsf` | So `/Game/Materials/Metal/M_Steel` → `DShader/Decompiled/Materials/Game/Materials/Metal/M_Steel.dsm`. ## After the export — do this, in order 1. **Read the `// Warning:` lines** under the `// Decompiled from …` header. Each names something the exporter could not reproduce. They are the migration work list. 2. **Compile it as-is**, to establish that the export is at least buildable: ```bash pwsh -File Plugins/DreamShader/.skill/dsc.ps1 compile DShader/Decompiled/Materials/…/M_Steel.dsm -Force -CleanNew ``` This is safe by construction: the emitted `Name=` points into `Decompiled/…`, so it builds a *new* asset and leaves the original alone. 3. **Clean it up** — [`dream-shader-optimize`](../dream-shader-optimize/SKILL.md). 4. **Only then** retarget `Name=` / `Root=` at the original path, and delete the original asset. ## Gotchas - **This is a migration starting point, not a round-trip guarantee.** The exporter reproduces the graph's structure and the node state it can express, and leaves a `// Warning:` comment for the rest. Read [`Docs/tools/decompiler.md`](../../Docs/tools/decompiler.md#known-round-trip-gaps) before deleting any original. - **Struct-, array-, map- and set-valued node properties are dropped silently** — no warning names them. A fallback `UE.Expression` node comes back with that state at its class default. - **Material instances are rejected outright.** `UMaterialInstanceConstant` is not supported — export the parent `UMaterial` and re-create the instance. For a thin-custom DreamShader material, the graph lives on the hidden `MB_DreamThinBase_*` base, so pass the instance's parent. - **In Git Bash, a leading-slash asset path is mangled.** `/LGUI/Materials/X` becomes `C:/Program Files/Git/LGUI/Materials/X` and the asset "cannot be loaded". Run decompiles from PowerShell. - The asset path is normalised: `\` → `/`, and a path starting with `/` that contains no `.` gets the short name appended, so `/Game/Path/Asset` is loaded as `/Game/Path/Asset.Asset`. Both forms work. - **`Layout` export is a project setting** (*Export Decompiled Layout*, default on). With it off you lose node positions and the regenerated graph is auto-laid-out. `#Region` directives are emitted regardless. - Comment boxes whose text begins with `DreamShader: ` are generated markers and are deliberately not re-emitted. ## Troubleshooting | Message | Cause | | :-- | :-- | | `DreamShader could not load asset '…'.` | the object path is wrong, or the plugin/mount point is not loaded. Check the path in the Content Browser's *Copy Reference* | | `DreamShader decompile supports Material and MaterialFunction assets only: …` | wrong asset class — most often a material **instance** | | `MaterialFunction '…' does not expose any outputs.` | the function declares no outputs; nothing to export | | `DreamShader failed to create output directory '…'.` | bad `-Out` path | | exports, but the graph is full of `UE.Expression` | expected for nodes with no curated case. Pass 2 of the argument builder still exports reflected literal properties that differ from the class default | ## See also - [`Docs/tools/decompiler.md`](../../Docs/tools/decompiler.md) — what is exported faithfully, and what is not - [`Docs/builtins/ue-expression.md`](../../Docs/builtins/ue-expression.md) — the generic fallback call - [`dream-shader-optimize`](../dream-shader-optimize/SKILL.md) — the required next step - [`dream-shader-verify`](../dream-shader-verify/SKILL.md) — the compile gate