A GLB that looks right in a browser viewer is not yet a file you can hand to someone else. A web page, Apple Quick Look, and a slicer store different things. Decide which of those three will open the file, then check the GLB against that choice.

I work on NovaGen3D. Later in this article I use its browser converter as one concrete implementation of these rules. The formats still come first. The converter does not define them.

Target format at a glance

Destination Target Container Distance Unit Up Axis Appearance / Material Support Animation
Browser / WebGL GLB / glTF Meter (strict) +Y up PBR (Metallic-Roughness, textures) Full support (skeletal & morph)
Apple AR Quick Look USDZ Meter (AR default) +Y up UsdPreviewSurface (JPEG, PNG, EXR, AVIF) Dropped in static converters
Slicer (Mesh-only) STL Unitless (slicer assumes mm) Slicer-dependent (commonly +Z up) None (pure geometry facets) None
Slicer (Production) 3MF Explicit (default mm) +Z up (+Y points back) Base material colors (no image PBR textures) None

Read the units and the up axis first

glTF 2.0, the format inside a GLB, measures linear distances in meters. After you apply a node's transform, vertex positions remain meters. The coordinate system is right-handed: +X points right, +Y points up, and +Z points toward the viewer (forward from the model's rest view, with cameras looking along -Z). The Khronos specification states both rules.

That difference sends the wrong size to a printer. Take a vertex that lands at x = 0.05 after the node transform. The specification says that number is 0.05 meters, which is 50 millimeters. An STL file can store the number 0.05, and the STL specification gives that number no unit. Marshall Burns's reprint of the 3D Systems StereoLithography Interface Specification says the coordinates are in arbitrary units and the file contains no scale information. If you then tell a slicer to read those numbers as millimeters, the part is 0.05 mm across. If your exporter multiplies meter values by 1000 and you tell the slicer the result is millimeters, the same vertex is 50 mm. The multiplication is an exporter choice. It is not part of STL.

3MF can name the unit. In the 3MF Core Specification 1.3.0, the model element's unit attribute defaults to millimeter. Allowed values also include meter, centimeter, inch, foot, and micron. 3MF's axis is different from glTF: +Z is up, +X points to the right of the printer bed, and +Y points toward the back. A conversion that only multiplies by 1000 leaves the glTF up-axis on 3MF's depth axis. The model then lies on its side relative to the bed, even when the millimeter count is right.

Before you export, write down one known size in millimeters and which axis should point up. After you export, open the new file and check that same size and axis.

Match the container to the program that will open it

Use a self-contained GLB when a browser or a game engine will load the model. glTF may point at buffers and images with a data URI, a relative path, or a full http, https, or file URI. The specification says assets that use those extra URI forms are less portable. A file named .glb can still point at an external texture. The file contains a JSON chunk, so search that JSON for image and buffer entries (or inspect it using tools like @gltf-transform/cli inspect model.glb). If the next machine does not have an external texture, the mesh can load without it. Pack those buffers and images into the GLB, or switch to a container that packages them.

Use USDZ when the file is going to Apple Quick Look or another Apple viewer that expects a single package. Apple describes USDZ as a zip archive that bundles the USD scene with its textures and other dependencies, and as the distribution format behind AR Quick Look. Apple's current guidance for USDZ textures lists JPEG, PNG, EXR, and AVIF. Web-optimized GLBs often rely on texture extensions like KTX2 / Basis Universal (KHR_texture_basisu) or WebP (EXT_texture_webp). Quick Look will not decode KTX2 or unhandled extensions natively, leading to untextured white or black models. Transcode textures to PNG or JPEG before packing them into the USDZ archive, then open the result in Quick Look to verify the material surfaces appear as expected.

Use STL when the slicer needs a triangle surface and you can set the unit in the slicer yourself. The Library of Congress format description says STL has no standard way to store color, texture, or other appearance. The color you see in a PBR viewer comes from glTF metallic-roughness parameters and textures. Those parameters have nowhere standard to go in an STL file. Two incompatible color conventions exist for binary STL, which is a reason to keep the colored preview out of the print file.

Use 3MF when you want the manufacturing file to carry an explicit unit. You still have to remap Y-up to Z-up and check the bed origin. 3MF puts that origin at the bottom-front-left of the printer's output area.

Drop what the destination cannot store

glTF mesh primitives default to triangles, and they may also be points, lines, line loops, line strips, triangle strips, or triangle fans. STL stores a list of triangular facets. Each facet has a unit normal and three vertices. Points and lines have no STL representation unless some other tool first builds a surface from them. Triangle strips and fans are still triangles, but the exporter has to expand them into separate facets.

An animation track is also absent from STL. glTF can store animation separately from the node's rest transform. A viewer can show a posed frame while the rest pose stays in the file. An STL or other static triangle export records one set of coordinates. Pose the model the way the print or the static preview should look, export, and open the export. Do not assume the frame on screen is the frame in the new file.

The reprinted STL specification adds two checks a screenshot will not do. Adjacent triangles must meet vertex to vertex: a vertex of one triangle may not land in the middle of another triangle's edge. The same document says vertex coordinates must be positive. Your exporter may write negative numbers anyway. Look at where the slicer places the part on the bed.

What NovaGen3D's converter does with a GLB

The NovaGen3D 3D converter runs this handoff in the browser. It accepts GLB, GLTF, OBJ, FBX, STL, PLY, and 3MF, up to 100 MB. It stops when the model exceeds 1 million triangles or 3 million vertices. A GLB whose buffers or images use a URI other than a data URI is rejected. A GLTF that points at external images is rejected too. Point clouds and line-only objects are rejected, because the exporter needs triangles. The local result can be downloaded without an account. Nothing in this path repairs holes or measures wall thickness.

For a GLB or GLTF, the scene is already in meters. STL export multiplies that baked scene by 1,000 and writes a binary STL, so the 0.05 meter vertex above becomes 50. The file still has no unit field. You confirm in the slicer that 50 means 50 millimeters. The export uses the model's default pose. It drops materials and animation. A frame paused in a viewer is not the pose that gets written. The locked pair for that job is the NovaGen3D GLB to STL page.

STL, OBJ, and PLY inputs are different. Those files have no reliable unit of their own, so the converter asks whether the source numbers are millimeters, centimeters, or meters. The default is millimeters. It converts that choice into meters, and the STL writer then multiplies by 1,000 on the way out. An STL whose source unit is millimeters should come back at the same millimeter size. Choose the wrong source unit and the round trip scales the part.

3MF export starts from the same baked meter, Y-up scene. It writes millimeters and remaps the axes: glTF X stays X, glTF Z becomes negative Y, and glTF Y becomes Z. That matches 3MF's Z-up space. The file can carry base material colors. It does not carry image textures, printer settings, or an automatic repair. The export also does not validate that the solid is printable.

USDZ export from this converter keeps the default pose and the materials the exporter supports, and it drops animation. Apple's USDZ container can describe more than this exporter writes. If Quick Look is the destination, open the USDZ there and look at the texture.

These are this converter's implementation choices. The 0.05 meter figure is arithmetic plus this scale. Another converter can leave the meters untouched or skip the axis remap. I have not printed this example.

Run this preflight on the file you have

  1. Name the program that will open the next file: a browser or engine, Quick Look, or a slicer.
  2. In the GLB JSON chunk, find image and buffer URIs. Pack any uri that is not a data URI before you send the GLB onward. NovaGen3D's converter rejects that GLB instead of guessing where the texture is.
  3. For Quick Look, export USDZ and confirm the textures are inside the package (and transcoded to PNG or JPEG if the source GLB used KTX2 or WebP). Then open that USDZ, not the original GLB.
  4. For a slicer, pick STL if you only need triangles, or 3MF if you need a unit in the file. Record one dimension in millimeters and the up-axis. On a GLB, NovaGen3D's STL path multiplies meters by 1,000, and its 3MF path also remaps Y-up to Z-up. Then compare the exported number with your note in the slicer.
  5. Open the exported file in the destination program. Compare that dimension and the up-axis with your notes.
  6. Leave holes, wall thickness, and supports to the slicer. A shaded viewer does not measure them. The STL vertex-to-vertex rule is one defect you can look straight at and still miss. NovaGen3D does not close that gap for you.

The 0.05 meter example is arithmetic from the specifications, then run through this converter's scale. It is not a measurement from a printed part.

Sources