← All text IRs

MGIR

Round-trip Material graphs

A material in Unreal is a shader node network — constants, parameters, math, texture samples, and output pins — stored inside a binary .uasset you can only really read by opening the Material Editor and tracing wires across the canvas. MGIR turns that same network into a compact, line-based text document: every expression, every connection, and every property value written out as text that decompiles out of the asset and compiles back in.

Why it matters

Diffable in version control

A recolor or a rewired output becomes a few changed lines in a pull request instead of an opaque binary asset your reviewers have to open the editor to inspect.

Reviewable like code

You read the whole graph top to bottom — which constant feeds which output, which parameters exist — in plain text, so an AI edit to a material is as auditable as an edit to your source.

A format an AI can author

One consistent language for the node network, with expressions named by qualified Unreal class path. The assistant reads the whole graph, edits a few lines, and hands it back, instead of firing dozens of blind create-node / connect-pin calls that compound small mistakes.

Faithful and deterministic

Decompile is stable, and the same decompiler path backs both live inspection and the mgir.txt asset-dump sidecar. A round-trip preserves nodes, connections, and property values — logical equivalence, not editor cosmetics.

A taste

An entry block names its target material as a backtick-delimited path. Expressions bind to %names, an optional @(x, y) gives layout, and output lines wire values into the material's pins:

entry material `/Game/Materials/M_Rim` {
    %tint = constant Float3(0.2, 0.4, 1.0) @(0, 0)
    %fres = call `/Script/Engine.MaterialExpressionFresnel`() @(200, 0)
    output BaseColor: %tint
    output EmissiveColor: %fres
}

Expressions are named by qualified class path (call `/Script/Engine.MaterialExpressionAdd`()); short aliases are intentionally rejected inside MGIR so the round-trip form stays unambiguous. Decompiling with Substrate sugar enabled additionally presents common Substrate topology nodes as short assigned calls like %front = slab(DiffuseAlbedo: %albedo).

How your assistant uses it

Your assistant reads the graph out with material.decompile_mgir, edits the text, and compiles it back with material.compile_mgir — you never touch the syntax yourself:

You: In M_Rim, make the rim tint green instead of blue.

  call("material.decompile_mgir", {assetPath:"/Game/Materials/M_Rim"})
    → {text:"entry material `/Game/Materials/M_Rim` {\n  %tint = constant Float3(0.2, 0.4, 1.0) ... }"}
  call("material.compile_mgir", {mode:"Append",
        text:"entry material `/Game/Materials/M_Rim` {\n  %tint = constant Float3(0.1, 0.9, 0.3) @(0,0)\n  output BaseColor: %tint\n}"})
    → {ok:true}

Done. Rim tint recolored green.
A round-trip is logical, not visual: nodes, connections, and property values survive a decompile → compile cycle, but pure editor cosmetics (comment boxes, node colors, list ordering, layout-only reroutes) are out of scope by design. Material authoring is still early access — close the Material Editor for a material before compiling MGIR into it, so the editor's working copy does not clobber the write.

← Back to all text IRs