Blender Fab ORM Metallic Looks Flat in Godot 4.5 After Node Group Change - 2026 Art Pipeline
You duplicated Fab_ORM_Pack_v3 as Fab_ORM_Pack_v3_copy, swapped a Combine RGB socket “just for the sword,” and re-exported the kit. Blender viewport still shows brass highlights. Godot 4.5 shows gray plastic on every metal trim—and players screenshot the fest demo before art lead notices the node group diff.
July 2026 teams already fixed 0.01 scale and some ran the seven-day ORM proof sphere challenge. Godot 4.3+ import and StandardMaterial3D texture slot wiring still punish channel swizzles and sRGB ORM when Fab node groups change mid-sprint. This Art & Design pipeline is the recovery map after a node edit—not a second week-long challenge.
Non-repetition note: The challenge URL owns G1–G7 calendar gates and mandatory proof-sphere week. This URL owns post-change diagnosis, A1–A6 art gates, and orm_metallic_flat_receipt_v1.json. Planned help: ORM metallic flat Godot fix. 8K ORM editor hang is texture size—not metallic response.
Pair with blender-to-engine resource refresh, Fab MegaGrants pressure, BUILD_RECEIPT, Wednesday demo smoke, and Thursday row review.
Why this matters now (July 2026)
- Godot 4.3+ material import — ORM textures map to Metallic, Roughness, and AO slots with stricter non-color defaults; old Fab presets assumed different socket names.
- Fab kit velocity — Studios import metal-heavy environment packs after scale fixes; one node group tweak propagates to forty props.
- Store vs in-game PBR — Trailer brass ≠ plastic swords drives “broken graphics” refunds and social clips.
- Node group forks — “Copy for hero sword” is the #1 swizzle accident in Discord art channels this quarter.
- Receipt culture — fab_pipeline_receipt now expects ORM proof rows—flat metal fails promotion without a receipt, not a Slack thread.
Direct answer: Freeze orm_channel_legend_v1.json, diff the node group, re-export non-color ORM glTF, validate metallic channel, assign Godot slots, pass A6 with tolerance screenshots—then merge Fab props.
Who this is for
| Role | Outcome |
|---|---|
| Environment artist | Know which socket not to swap |
| Technical artist | glTF + Godot import preset lock |
| Art lead | Approve tolerance table before kit merge |
| Producer | orm_metallic_flat_receipt_v1.json blocks fest branch |
Time: ~45 minutes read; 2–6 hours first recovery (one hero prop + proof sphere).
Prerequisites: Blender 4.x, Godot 4.5, Fab kit already on disk, scale pipeline GREEN.
Symptom matrix (route correctly)
| What you see | Likely cause | Read next |
|---|---|---|
| Everything mirror-chrome | Metallic in albedo alpha or inverted roughness | A2 swizzle audit |
| All props dull plastic | Metallic channel zero or ORM not connected | A4–A5 |
| Only one sword wrong | Forked node group on hero only | A2 node diff |
| Blender OK, Godot flat | sRGB on ORM or wrong Godot slot | A3, A5 |
| Editor freeze on import | 8K ORM texture | 8K help when live |
| Tiny giant props | Scale | 12-free scale tools |
Three-layer model
Layer 1: Blender Fab node group (authoring truth)
Layer 2: glTF 2.0 transport (ORM packed texture + extensions)
Layer 3: Godot StandardMaterial3D (slot assignment + import preset)
Flat metallic almost always means Layer 1 ≠ Layer 3 after a node change—not “Godot PBR is broken.”
Gates A1–A6 (metallic recovery pass)
| Gate | Name | Pass criterion |
|---|---|---|
| A1 | Legend pin | orm_channel_legend_v1.json matches active node group version |
| A2 | Node group diff | No unversioned *_copy groups in export path |
| A3 | Non-color ORM export | ORM image non-color in Blender + glTF |
| A4 | glTF metallic channel | Validator shows metallic in expected texture |
| A5 | Godot slot map | Metallic/Roughness/AO textures on correct slots |
| A6 | Receipt + tolerance | orm_metallic_flat_receipt_v1.json + screenshots |
A4–A5 block fest art merge when RED.
A1 — Lock orm_channel_legend_v1.json
After any node group edit, bump orm_legend_version and republish legend to #art-pipeline:
{
"schema": "orm_channel_legend_v1",
"orm_legend_version": 2,
"texture_color_space": "non-color",
"channels": {
"R": "ambient_occlusion",
"G": "roughness",
"B": "metallic"
},
"metallic_workflow": "metallic_roughness",
"fab_node_group": "Fab_ORM_Pack_v3",
"forbidden_groups": ["Fab_ORM_Pack_v3_copy"],
"notes": "v2 after sword socket swap rollback"
}
Pass: Every .blend in assets/fab/ header comment links version 2.
Legend mistakes that read as flat metal
| Mistake | Godot symptom |
|---|---|
| sRGB on ORM | Washed plastic, weak specular |
| Roughness in B, metallic in G | Inverted response—chrome or mud |
| Metallic painted into albedo without extension doc | Validator warning, flat in engine |
| AO multiplied in engine and albedo | Props look clay-like |
A2 — Node group change audit
Run this before re-exporting forty kit pieces:
- Outliner → File → External Data → Report — list blends using
Fab_ORM_Pack_v3_copy. - Open Shader Editor on hero sword—compare socket wiring to locked
proof_sphere.blendfrom challenge week. - Archive
node_group_diff.md:
# Node group diff — 2026-05-25
- Changed: Combine RGB input 2 (roughness ← metallic socket)
- Reverted: yes
- Assets affected: hero_sword_01, hero_sword_02
- Re-export required: only affected GLBs (not full kit)
Pass: Zero forbidden group names in export queue; diff filed under release-evidence/blender/orm-recovery/.
Fork policy (studio rule)
| Action | Allowed? |
|---|---|
Edit locked Fab_ORM_Pack_v3 in place |
Only TA + version bump |
| Duplicate group for “quick test” | No — use scratch blend |
| Per-asset unique ORM without legend bump | No |
A3 — Non-color ORM export discipline
Blender image settings for *_ORM.png:
| Setting | Value |
|---|---|
| Color space | Non-Color |
| Bit depth | 8-bit OK for fest; 16-bit for hero only |
| Compression | Lossless PNG for proof; JPEG not for ORM |
glTF export checklist:
| Option | Fest demo |
|---|---|
| Format | glTF 2.0 binary .glb |
| Apply transforms | Yes |
| +Y Up | Match Godot import doc |
| Images | ORM separate from albedo |
| Materials | Export as metallic-roughness |
Outbound: Blender glTF exporter.
A4 — glTF validator metallic proof
Run Khronos glTF Validator on one affected hero_sword.glb and proof_sphere.glb:
| Check | Pass |
|---|---|
| Errors | 0 |
KHR_materials_pbrMetallicRoughness |
Present |
| Metallic texture | Linked to ORM, not albedo-only |
| Warnings | Logged in validator_log.json |
Archive logs beside BUILD_RECEIPT fab_orm row.
A5 — Godot 4.5 StandardMaterial3D slot map
Import test scene scenes/orm_recovery_smoke.tscn:
- Import
proof_sphere.glbwith presetfab_orm_recovery.tres. - Open imported material—confirm:
| Godot slot | Source channel (legend v2) |
|---|---|
| Metallic | ORM B |
| Roughness | ORM G |
| Ambient Occlusion | ORM R (if used) |
| Albedo | Base color sRGB |
- Never mark ORM texture as sRGB in Import dock.
- Capture
godot_metallic_recovery.pngbeside Blender still same camera.
Godot docs: Importing glTF.
Quick proof sphere (30 minutes)
If challenge week was skipped, build three spheres (metal / plastic / dielectric) today—same lighting, one export. Metal must not read plastic; plastic must not read chrome. Full calendar still lives in the seven-day challenge.
Tolerance table (Blender vs Godot)
Agree slack before art arguments:
| Material | Roughness Δ max | Metallic Δ max |
|---|---|---|
| Polished metal | ±0.08 | ±0.05 |
| Matte plastic | ±0.10 | ≤0.02 metallic |
| Painted wood | ±0.12 | ≤0.03 metallic |
Outside tolerance → A5 fail until import preset or legend fixed.
A6 — orm_metallic_flat_receipt_v1.json
{
"schema": "orm_metallic_flat_receipt_v1",
"build_id": "nextfest-oct-2026-rc5",
"orm_legend_version": 2,
"node_group_incident": "Fab_ORM_Pack_v3_copy reverted 2026-05-25",
"proof_sphere_pass": true,
"hero_prop_ab": "hero_sword_01",
"gltf_validator_pass": true,
"godot_version": "4.5.stable",
"gates": {
"A1_legend_pin": "pass",
"A2_node_group_diff": "pass",
"A3_non_color_export": "pass",
"A4_gltf_metallic": "pass",
"A5_godot_slots": "pass",
"A6_receipt": "pass"
},
"metallic_flat_resolved": true,
"paired_receipts": [
"release-evidence/blender/orm_channel_receipt_v1.json",
"release-evidence/fab/fab_pipeline_receipt_v1.json"
],
"promotion_allowed": true
}
Wire orm_metallic_flat: verified into BUILD_RECEIPT and Thursday row review fab_pipeline column.
Remediation playbook (one afternoon)
| Step | Owner | Minutes |
|---|---|---|
| Roll back node group fork | TA | 20 |
| Re-export affected GLBs only | Artist | 45–90 |
| Validator + Godot smoke | TA | 30 |
| Receipt + producer sign-off | Lead | 15 |
Do not re-import entire kit until A6 GREEN—fixes propagate from two hero props + proof sphere.
Fab kit A/B after incident
| Asset class | Action |
|---|---|
| Hero metal prop | Full A4–A5 repeat |
| Organic wood/stone | Spot-check ORM dull, not metal |
| Batch environment | Defer until hero passes |
Link fab_pipeline_receipt max texture and ORM legend version rows.
Beginner path (non-technical art lead)
- Stop new Fab merges in Discord—post “ORM incident OPEN.”
- Ask TA for legend version number—must match monitors.
- Approve three proof sphere screenshots (metal / plastic / wood).
- Compare one Godot screenshot to Blender still—same angle.
- Sign receipt only when metal sphere ≠ plastic.
- Allow two hero props back into demo branch— not full kit.
Technical artist path
- Add
scripts/validate_gltf.shto CI onassets/fab/**/*.glb. - Pin
fab_orm_recovery.tresin repo—no per-artist Import dock drift. - Grep CI for
Fab_ORM_Pack_v3_copyin.blendbinaries (fail build). - Thumbnail render proof sphere on PR touching
assets/fab/.
Troubleshooting (fest week)
| Symptom | First check |
|---|---|
| Everything chrome | G/B swap in Combine RGB |
| Flat metal | Metallic zero—A4 texture graph |
| Sparkly fireflies | Normal tangents + ORM sRGB |
| Godot darker than Blender | HDRI energy mismatch—freeze lights |
| Only Web build wrong | Separate KTX path—not this article |
Relationship to scale and challenge content
| Topic | Scale resource | 7-day challenge | This pipeline |
|---|---|---|---|
| 0.01 import | Primary | Prerequisite | Assumes GREEN |
| Proof sphere week | Optional | Mandatory calendar | 30-min minimum |
| Post node-group incident | — | — | Primary |
orm_channel_receipt |
Mentioned | Gate 7 output | Paired in A6 |
Store and marketing alignment
Animated GIF capsule and trailer frames may show correct brass—fix in-game before updating store art, or players call “bait and switch.” Pair store-demo mismatch discipline: evidence folder beats opinion.
Engine notes beyond Godot
| Engine | ORM note |
|---|---|
| Unity URP | Metallic-Roughness map in linear |
| Unreal | ORM packed as R=Ambient, G=Roughness, B=Metallic—confirm Fab pack |
| Godot 4.5 | StandardMaterial3D slot map in A5 |
Teams on multi-engine ports should keep one orm_channel_legend_v1.json—Godot is the fest gate here.
Godot import preset — fab_orm_recovery.tres (reference)
Pin a team import preset so artists do not hand-tweak the Import dock per file:
# fab_orm_recovery.tres — attach to proof_sphere.glb + affected heroes
meshes/ensure_tangents=true
meshes/generate_lods=false
meshes/create_shadow_meshes=true
materials/extract=0
materials/extract_format=0
textures/normal_map=1
# ORM textures: verify Non-Color on ORM only, sRGB on albedo
After bulk re-import, run Reimport on the assets/fab/ folder once—watch VCS diff size. Pair with Friday Block 5 to confirm import preset hash unchanged week to week.
StandardMaterial3D sanity script (optional)
# orm_smoke.gd — attach to proof_sphere root for one-click QA
func _ready() -> void:
for c in get_children():
if c is MeshInstance3D:
var mat := c.get_active_material(0) as StandardMaterial3D
assert(mat != null, "Missing StandardMaterial3D on %s" % c.name)
assert(mat.metallic_texture != null, "Metallic slot empty on %s" % c.name)
assert(mat.roughness_texture != null, "Roughness slot empty on %s" % c.name)
Log results into godot_orm_smoke.md beside Blender stills—producers read markdown, not the inspector.
Studio lighting lock (stop false “flat” diagnoses)
ORM comparisons fail when lighting changes between Blender and Godot captures:
| Rule | Why |
|---|---|
| Same HDRI file path in both apps | Exposure mismatch reads as dull metal |
| Fixed key fill ratio | Artists blame engine when contrast changed |
| No bloom in compare shots | Bloom hides roughness errors |
| Capture 1920×1080 PNG | Downscale breaks specular read |
Archive lighting_lock.md under release-evidence/blender/orm-recovery/ with HDRI filename and rotation—immutable during A4–A6.
Evidence folder layout
release-evidence/blender/orm-recovery/
orm_channel_legend_v1.json # bumped version
node_group_diff.md # incident write-up
validator_log.json # glTF Validator output
proof_renders/
blender_metal.png
godot_metallic_recovery.png
godot_orm_smoke.md # tolerance table results
orm_metallic_flat_receipt_v1.json # A6 promotion gate
Thursday row review should list this folder path in fab_pipeline notes—same discipline as audio receipts.
CI guardrails (technical artists)
| Check | Command sketch | Fail message |
|---|---|---|
| Forbidden node group name | rg -l "Fab_ORM_Pack_v3_copy" assets/ |
Remove copy group before merge |
| ORM sRGB | Blender batch script on *_ORM.png |
Non-color required |
| glTF errors | gltf_validator CLI |
Zero errors on changed GLBs |
Blocking one bad hero_sword.glb is cheaper than reverting a fest branch Friday night.
When metallic reads “almost” right
Teams accept YELLOW tolerance on dielectric wood but promote RED on hero brass:
| Signal | Action |
|---|---|
| Metal dull but not plastic | Check AO double-multiply |
| Edge highlights missing | Normal map tangent space |
| Roughness too glossy | Inverted G channel in legend |
| Fest trailer OK, demo flat | Wrong branch art folder—compare build_id |
Cross-check store-demo mismatch patterns—label drift also hits art depots.
Facilitator README snippet (playtest nights)
Add to facilitator packet so testers file useful bugs:
## Graphics — metallic materials
If brass looks plastic, capture:
- build_id from pause menu
- scene name + prop name
- screenshot + graphics preset
Do NOT adjust Godot Import dock locally.
File under label: orm-metallic-flat
Routes QA to A6 receipt owners instead of random shader hacks in playtest branches.
Promotion checklist (art → production)
- [ ]
orm_metallic_flat_receipt_v1.jsoncommitted - [ ]
orm_legend_versionmatches BUILD_RECEIPT - [ ] Wednesday demo smoke includes one metal prop in golden path
- [ ] Thursday row review shows
orm_metallic_flat: verified - [ ] No
*_copynode groups in export manifest - [ ] Forward help published or linked as planned
FAQ
We already ran the seven-day challenge—why flat metal again?
Node groups changed after Gate 7. Re-run A1–A6, not the full calendar, unless legend version was never bumped.
Can we fix only in Godot Import dock?
Import presets can compensate once—authoring must match or the next export re-breaks.
Is Fab “broken”?
Fab kits ship authoring assumptions. Your studio owns legend + lock—see MegaGrants pipeline pressure.
Plastic looks metallic instead?
Inverted roughness or metallic in albedo alpha—see symptom matrix; often paired with sRGB mistake.
Do we need 8K ORM?
No for fest props—downscale in Blender; 8K hang is a different help article.
Key takeaways
- Godot 4.3+ punishes ORM swizzle drift after Fab node group edits.
- A1–A6 recover metallic response without re-buying kits.
- Non-color ORM and correct Godot slots fix most “flat plastic” reports.
orm_metallic_flat_receipt_v1.jsonblocks promotion—pair withorm_channel_receipt.- Planned help fix complements this pipeline URL.
Related reading
- 7-Day Blender Fab ORM proof sphere challenge
- 12 free Blender Fab Godot scale proof tools
- 25 free blender-to-engine workflow resources
- Epic Fab MegaGrants asset pipeline pressure
- BUILD_RECEIPT beginner pipeline
- Wednesday demo build smoke
- Thursday BUILD_RECEIPT row review
- Animated GIF capsule safe-zone pass