Skip to content
All articles

Guides 6 min read 1,355 words

GLB, FBX, OBJ, USDZ: picking the right format for the engine you actually use

The same 38k-triangle model ships at 22.3 MB or 1.8 MB depending on the container. Here is what each format carries, what it drops, and which to pick.

Export the same 38,400-triangle statue four ways and you get files of 22.3 MB, 20.5 MB, 19.7 MB and 1.8 MB. The geometry is identical in all four. The difference is what the container is allowed to compress, what it is allowed to embed, and how much of a 1992 text format you are still dragging around.

Format choice gets treated as a shrug — “whatever the engine takes” — until the day an animation arrives with no skin weights, or a client’s iPhone refuses to open the AR preview, or a web build takes eleven seconds to load a single prop. All three are format problems, and all three are avoidable by picking deliberately.

What each format actually carries

Capability glTF 2.0 / GLB FBX (binary 7.4+) OBJ + MTL USDZ
Mesh and UVs Yes Yes Yes Yes
Multiple UV channels Yes, up to spec limit Yes No, one set only Yes
Metal/rough PBR Native Non-standard, lossy No, MTL is Blinn-Phong Native
Vertex colours Yes Yes Unofficial extension Yes
Skeleton and skinning Yes Yes, best in class No Yes
Animation clips Yes Yes, multi-take No Yes
Blend shapes / morphs Yes Yes No Yes
Embedded textures Yes, in GLB Optional No, always external Required
Geometry compression Draco, meshopt No No No
Texture compression KTX2 / Basis No No No
Cameras and lights Yes, lights via extension Yes No Yes
Specification Khronos, open Autodesk, proprietary De facto, unversioned Pixar / AOUSD, open

The same asset, packaged eight ways

One statue: 38,400 triangles, 20,100 vertices, one material, three 2048 × 2048 maps (base colour, normal, and an occlusion/roughness/metallic pack).

Packaging Geometry Textures Total
OBJ + MTL + 3 × PNG 4.1 MB 18.2 MB 22.3 MB
FBX binary, textures external 2.3 MB 18.2 MB 20.5 MB
FBX binary, textures embedded 2.4 MB 18.2 MB 20.6 MB
USDZ, PNG (stored, not deflated) 1.6 MB 18.3 MB 19.9 MB
GLB, PNG embedded 1.5 MB 18.2 MB 19.7 MB
GLB, JPEG q90 colour + PNG normal 1.5 MB 6.9 MB 8.4 MB
GLB + Draco + KTX2 (UASTC normal, ETC1S rest) 0.18 MB 4.4 MB 4.6 MB
GLB + Draco + KTX2 (ETC1S everywhere) 0.18 MB 1.6 MB 1.8 MB

Two things fall out of that table. First, textures are 85–95% of your payload in every uncompressed row, so arguing about mesh format while shipping PNGs is arguing about the wrong thing. Second, the all-ETC1S row is twelve times smaller than the honest baseline, and the price is visible blocking on the normal map. That last row is a fine choice for a product configurator and a bad one for a hero asset.

OBJ: still around, rarely the right answer

OBJ is a plain-text format with no version number, no scene graph, no skeleton, no animation, one UV set, and a material sidecar that describes a lighting model nobody has used since 2005. Every OBJ importer disagrees slightly about smoothing groups and about whether Ka means anything.

It still has three legitimate uses: a quick sanity check that a mesh is watertight, a round-trip into a sculpting tool that only speaks OBJ, and handing static geometry to a collaborator whose software you cannot identify. Outside those, shipping OBJ as a delivery format costs you roughly 2.5× the file size of binary FBX for strictly less information.

The specific trap: OBJ stores no explicit smoothing information beyond an s group index, and many exporters write per-vertex normals as vn lines while many importers ignore them and recalculate. That is why a model can arrive faceted in one tool and smooth in the next.

FBX: the animation workhorse with version landmines

If you are moving a rigged, animated character between DCC tools and Unity or Unreal, FBX is still the safest choice and will be for a while. Skinning, multiple takes, custom attributes and node hierarchies all survive.

Three things bite people:

  • Units. FBX declares a scene unit, and the historical default is centimetres. Blender works in metres. A 1.7 m character exported carelessly arrives as 170 m or 0.017 m. Check the transform of one known object immediately after import rather than eyeballing it against a grid.
  • ASCII versus binary. Unity refuses ASCII FBX outright. If your exporter offers the choice, always pick binary. It is also roughly 3× smaller.
  • Material translation. FBX has no real PBR material model. Exporters fake it by writing metal/rough values into legacy Phong slots or into custom properties, and importers guess. Expect to rebuild materials by hand on the far side and treat the FBX purely as a geometry and animation carrier.

GLB: the sane default for delivery

glTF 2.0 was designed as a runtime format rather than an interchange format, and it shows. One file, one well-specified metal/rough material model, embedded textures, real compression, and an open spec you can read in an afternoon. GLB is the binary single-file flavour and it is what you should be shipping unless you have a reason not to.

Support is broad: Godot, three.js, Babylon.js, model-viewer, Blender, Substance Painter and Unreal all import it natively, and Unity does through glTFast. Where it is weaker: there is exactly one material model, so if your asset depends on a custom shader graph, glTF will flatten it. Custom per-vertex data needs an extension. And a few older DCC tools still export glTF poorly enough that a round trip loses precision.

USDZ: an AR delivery target, not a pipeline format

USDZ exists to be opened by AR Quick Look on iOS. It is a zip archive with no compression at all, because files must be byte-aligned for memory mapping, which is why the USDZ row in the size table is barely smaller than raw PNGs on disk.

Practical constraints for AR Quick Look: textures must be PNG or JPEG, geometry compression is unavailable, and Apple’s own guidance puts the comfortable ceiling around 100k triangles and 25 MB per file. Above that, older phones stall on load or thermally throttle within a minute.

Do not confuse USDZ with USD. Plain USD, with layers and references and variants, is a genuinely good pipeline format for large scenes in Houdini, Maya and Omniverse. USDZ is the flattened, sealed delivery box at the end of it.

Pick by target

Target First choice Fallback Watch for
Unity, static prop FBX GLB via glTFast Scale factor, ORM channel order
Unity, animated character FBX Binary only, rig naming
Unreal 5 FBX or GLB USD for scenes Nanite fallback, collision naming
Godot 4 GLB FBX via converter Import hints in node names
three.js / web GLB + Draco + KTX2 GLB + JPEG Decoder hosting, first-frame cost
iOS AR Quick Look USDZ 25 MB and 100k triangle ceiling
Android Scene Viewer GLB Draco decoder support
Blender or DCC round trip FBX USD Unit scale, custom normals
3D print STL or 3MF OBJ Manifold geometry, mm units

What breaks in conversion

Every conversion is lossy in a specific, predictable way. FBX to glTF drops custom material properties and any node attribute the exporter does not recognise. glTF to FBX turns a metal/rough material into an approximated specular one that will not match. Anything to OBJ drops the skeleton, animation, all but one UV set, and vertex colours. USDZ export flattens instancing into unique geometry, which is how a 4 MB scene becomes 60 MB.

Keep a lossless master. In practice that means: a native DCC file if you have one, otherwise the highest-fidelity export you received, stored untouched. Every delivery format is generated from that master by a script, never by hand, and never by converting a previous conversion.

Do and don’t

  • Do compress textures before you optimise geometry. That is where 90% of the bytes are.
  • Do verify scale with a 1 m reference cube on every first import from a new source.
  • Do ship GLB for anything running in a browser, and Draco the geometry.
  • Don’t use ETC1S on normal maps unless you have looked at the result on a curved surface under a moving light.
  • Don’t chain conversions. OBJ to FBX to glTF produces problems that are impossible to diagnose later.
  • Don’t treat USDZ as an archive format. It has no compression and no editability.
  • Don’t ship ASCII FBX. It is larger, slower to parse, and Unity rejects it.

Where to start tomorrow

Take the largest asset in your current build and run it through the eight packagings in the size table above. It takes about twenty minutes and gives you your project’s real compression ratio rather than a generic one. Then write the winning recipe into your export script so nobody has to remember it.

If your models arrive from a generator, check what it hands you by default. MeshyFlix exports GLB, FBX and OBJ from the same source mesh, which means the format decision stays yours rather than being fixed at generation time, and you can keep the GLB as your master while handing FBX to whoever needs it.