Asset & Resource Problems

Blender 4.x glTF ORM Packing Looks Blown Out in Godot 4.5 - Metallic Roughness Standard Material Fix (2026)

Fix Blender 4.x glTF exports that import into Godot 4.5 with blown-out metallics or muddy roughness after ORM channel packing - aligns Principled BSDF, glTF exporter, Godot 4.5 Standard Material 3D import, and web GLES verification.

By GamineAI Team

If your Blender 4.x model looks correct in the viewport but the Godot 4.5 importer renders the surface as blown-out chrome, muddy plastic, or fully matte gray after you switched to ORM-packed textures for a smaller web build, you are almost certainly hitting one of four channel-assignment bugs in the glTF metallic-roughness path. This page is for 2026 stylized pipelines packing Occlusion-Roughness-Metallic (ORM) into a single texture to fit itch.io size budgets and web GLES3 memory caps - the fastest safe fix takes about 8 minutes and validates against a neutral light probe.

Who is affected and which versions this applies to

  • Affected: solo devs and small teams exporting Blender 4.0 / 4.1 / 4.2 / 4.3 / 4.4 LTS GLBs into Godot 4.5 projects (Standard Material 3D on web or desktop).
  • Trigger: switched from three separate metallic + roughness + occlusion textures to one ORM-packed PNG/WebP to shrink web payload in early-to-mid 2026 stylized pipelines.
  • Symptom set: metallics read way too high, roughness reads like wet plastic, AO darkens too aggressively, or one channel reads gray while another spikes white.
  • Not affected (out of scope): Godot 4.4 and earlier 3D import (different ORM hint UI), Blender 3.x Principled BSDF v1 (different roughness input node), models still using three separate textures.

What changed in the ecosystem (why this spikes now)

In 2026 the stylized-web wave on itch.io and Steam web demos pushed teams to merge three single-channel textures into one ORM texture (R = Occlusion, G = Roughness, B = Metallic) so the GLB stays under typical 4–6 MB web budgets. Blender 4.x can export those packed textures via glTF 2.0 metallic-roughness, but the MR extension only consumes G + B, and the R channel is consumed via the separate KHR_materials_occlusion slot - dropping AO if you do not also link it in the Material Output. Godot 4.5 added a clearer ORM import hint and a separate AO assignment in Standard Material 3D, but most templates still default to the older split-texture flow, so a packed ORM texture lands with one channel doubled, one ignored, and one read in the wrong color space. Result: chrome where there should be cloth, mud where there should be metal.

Fastest safe fix (8 minutes)

Do these four steps in order. Do not skip the verification render at the end - the same misconfiguration can look "almost right" until you put it under neutral studio lighting.

  1. In Blender, open Shading workspace. Confirm the final shader is Principled BSDF v2 (Blender 4.x default) feeding Material Output > Surface. Plug your packed ORM image into a Separate Color (RGB) node, not directly into Principled.
  2. Wire G of Separate Color into Roughness, B into Metallic. Leave R unconnected on Principled itself.
  3. Add an AO input via a second image node or the same Separate Color R output, but route it into the glTF occlusion slot using the glTF Material Output node from the Node: glTF Material Output add-on (bundled with Blender 4.x glTF exporter). This is what tells the exporter to write occlusionTexture rather than dropping it.
  4. Export with File → Export → glTF 2.0 (.glb/.gltf): choose GLB, set Materials → Export → Placeholder, enable Images → Automatic (the exporter will reuse your packed texture for MR and AO slots when the slot names match), and disable any "Original PNG" override unless you have already verified your packed file is in non-color data space.

Re-import into Godot. In the Import dock select the asset, switch Import As to Scene, and under Materials → Storage choose Built-In. Then open the generated mesh, select its Standard Material 3D, and confirm:

  • Albedo → Color uses your sRGB color texture.
  • Metallic → Texture points to the ORM image, Texture Channel = Blue.
  • Roughness → Texture points to the ORM image, Texture Channel = Green.
  • Ambient Occlusion → Enabled is on, Texture = ORM image, Texture Channel = Red, Light Affect = 1.0.

Verify the fix under neutral lighting

Drop the model into a fresh scene with a single DirectionalLight3D (energy 1.0, neutral color), no Environment, and a 0.5-gray plane. You should see:

  • Metallic regions reflect the sky stand-in but do not blow to pure white at glancing angles.
  • Roughness gradient (if your texture has one) shows a smooth highlight falloff, not a binary chrome/matte cut.
  • AO darkens only the cavity / contact areas; the rest of the surface reads at your intended mid value.

If anything is still off, run this 30-second triage: temporarily set Albedo → Color to flat 50% gray. With color out of the picture, you can see channel issues directly - blown metallic now reads as full chrome over the whole mesh; swapped roughness reads as a mirror that should be cloth.

Root cause - why this packed export drifts

  1. glTF metallic-roughness reads two channels, not three. The spec uses G for roughness, B for metallic. The R channel of the same texture is not interpreted by the MR extension at all; it is read separately via occlusionTexture. Plugging the entire packed image straight into Principled Metallic in Blender doubles up the AO mask into the metallic signal - this is the #1 cause of blown metallics on a web GLES3 target.
  2. Color space drift. The packed ORM texture must be non-color / linear. If Blender or Godot tags it as sRGB, roughness G is gamma-encoded twice and reads muddier than authored, while metallic B looks artificially hot.
  3. Godot 4.5 ORM channel routing. Standard Material 3D in Godot 4.5 lets you point the same texture at three slots and assign different channels, but if Texture Channel is left at the default (Gray/Red) for both metallic and roughness, both slots sample R - which is your AO mask - and you get the inverse of the intended look.
  4. AO routing in Blender 4.x glTF. Without the glTF Material Output node, the exporter has no place to write occlusionTexture, so it silently drops AO from the GLB; some teams compensate by raising Principled roughness, which then reads wrong everywhere else.

Alternative fixes for edge cases

Edge case: you cannot install the glTF Material Output add-on

Use File → Export → glTF 2.0 and check Include → Custom Properties, then post-process the GLB with a one-line gltf-transform command:

npx -y @gltf-transform/cli@latest copy in.glb out.glb --metallic-roughness-occlusion same

This rewrites the occlusionTexture slot to reference the same packed texture used for MR. Re-import in Godot 4.5 and the AO channel will route correctly.

Edge case: Godot 4.5 web GLES3 target shows correct metallic but flat AO

This usually means the importer downcast the ORM PNG to RGB565 to fit web texture budgets and dropped the R channel precision. In the Import dock, set Compression → Mode = VRAM Uncompressed for the ORM texture only (small payload cost on web, large correctness win), or re-encode the ORM as WebP lossless before export.

Edge case: roughness gradient looks correct but metallic flickers in motion

Your packed texture is sRGB-tagged. In Godot, select the ORM texture in the FileSystem dock, open the Import tab, set sRGB → Disable, and click Reimport. The flicker disappears because metallic B is no longer gamma-encoded.

Edge case: model came from a marketplace asset that already ships an ORM map

Confirm the channel order in a fresh file: open the texture in GIMP / Krita, view each channel separately. Some marketplaces ship RMO or MRA instead of ORM - if so, either re-pack with gltf-transform or use Godot's Texture Channel dropdown to remap R/G/B per slot until the neutral-light render matches.

Prevention - lock this in for the project

  • Add a project-level import preset to .gdignore'd source assets that enforces Texture Channel = Red/Green/Blue on ORM textures, then commit a single-source ORM authoring template (Blender + Substance/Photoshop/GIMP exports) to your repo.
  • Bake a 5-second golden render of a single ORM-packed sphere into tests/golden/ and diff it against the live mesh in CI. Any channel routing regression fails the build before it reaches your web demo.
  • Stamp the Blender version and Godot version into the asset's extras metadata via the glTF Material Output node so future contributors see exactly which exporter wrote the file. This is especially important across Blender 4.x point releases in 2026 where the glTF exporter UI has shifted twice.
  • For Steam web demos and itch.io pages: keep an ORM authoring checklist next to your project.godot so the same packing decision is made every time. Inconsistency across assets is what makes the bug feel intermittent.

Verification checklist (paste into your PR template)

  • [ ] Packed texture is ORM (R = AO, G = Roughness, B = Metallic), not RMO or MRA.
  • [ ] Blender Principled BSDF receives G → Roughness, B → Metallic via Separate Color.
  • [ ] Blender glTF Material Output node routes R → Occlusion.
  • [ ] Godot Standard Material 3D sets Metallic Channel = Blue, Roughness Channel = Green, AO Channel = Red.
  • [ ] Godot Import → sRGB = Disabled on the ORM texture.
  • [ ] Neutral-light render shows correct metallic falloff, smooth roughness gradient, cavity-only AO.
  • [ ] Web GLES3 build matches editor render at 90% or better visual parity.

FAQ

Why does the metallic look fine in Blender but explode in Godot 4.5?
Blender's viewport reads the AO channel of your packed image as part of Principled Metallic only if you wired the whole texture into Metallic. Godot reads it correctly when Texture Channel = Blue, so the same packed file looks "right" in one viewer and "wrong" in the other until you fix channel routing.

Can I keep three separate textures instead of packing?
Yes, and for desktop targets that is often the easier path. Packing pays off on web GLES3 and small Steam demo builds where every megabyte counts. If you do not need a sub-6 MB GLB, skip ORM packing and use three single-channel textures with Standard Material 3D defaults.

Does this apply to Godot 4.4 or earlier?
The general channel-routing rules apply, but the Standard Material 3D import UI was simpler before Godot 4.5 added explicit AO channel routing on packed textures. Earlier versions often required an editor plugin or manual tres edit to set per-channel sampling. If you can, move the project to 4.5 to get the cleaner ORM import path.

Does this fix also apply to Blender 4.x → Unity?
Partially. Unity's glTFast importer follows the same MR + AO channel split, but Unity's Standard / URP Lit shader exposes AO differently. For Unity specifics, see the related help article on Blender to Unity color space.

Related help articles

Outbound references

Bookmark this fix for quick reference when you next compress textures for a web demo. Share it with a teammate the moment they merge an ORM-packed asset into a Godot 4.5 scene.