MGIR
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.