The Root Cause: Y-Up vs Z-Up
There is no universal agreement in the 3D industry about which axis points "up." This single disagreement is the cause of almost every orientation problem you will encounter when moving models between software, formats, and viewers.
The two camps break down like this. Y-up is used by Three.js, Unity, Unreal Engine, glTF, USDZ, Maya, and most web-based 3D viewers. In this system, the Y axis points toward the sky, X points to the right, and Z points toward the camera. Z-up is used by Blender, 3ds Max, AutoCAD, most CAD software, and the STL format. Here, Z points to the sky, X points to the right, and Y points away from the camera.
When you export a model from a Z-up application and load it in a Y-up viewer without any conversion, the model's "up" (Z) gets interpreted as "forward" (Z in the viewer's coordinate system). The model appears to be lying on its back, rotated 90 degrees around the X axis. If additional axis conventions differ — for example, some software uses a left-handed coordinate system while others use right-handed — you can get models that appear mirrored or rotated in unexpected ways.
Why STL Files Are Especially Problematic
The STL format is one of the oldest 3D file formats still in widespread use. It was created in 1987 for stereolithography and contains nothing but triangle data — vertex positions and face normals. Crucially, STL files contain no axis metadata whatsoever. There is no header field that says "this model was authored in Z-up" or "the unit is millimeters." The file is just a list of triangles floating in abstract space.
This means that when a viewer opens an STL file, it has to guess the orientation. Most viewers simply display the data as-is, which works fine if the authoring software and the viewer agree on axis conventions. But if they do not — and they often do not — the model appears rotated. A model designed upright in Blender (Z-up) will appear to be lying on its back in a Y-up viewer like Three.js.
Other formats handle this better. GLTF explicitly specifies Y-up in the specification. FBX includes an "UpAxis" property in its header. COLLADA (DAE) has an <up_axis> element. OBJ files are ambiguous but conventionally Y-up. When these formats are loaded by a well-written importer, the axis conversion happens automatically. STL offers no such luxury.
Fixing Orientation in Blender Before Export
The cleanest fix is to handle orientation at export time. In Blender, when you export to a Y-up format like GLTF or FBX, the exporter has built-in axis conversion options. For GLTF export, Blender automatically converts from Z-up to Y-up — this is handled by the exporter and you usually do not need to change any settings. For FBX export, you will see "Forward" and "Up" dropdown menus in the export dialog. Set "Up" to "Y Up" and "Forward" to "-Z Forward" for the most universally compatible result.
For STL export, Blender writes raw vertex data in Z-up coordinates. If your target software or viewer expects Y-up, you have two options. First, you can rotate the model in Blender before exporting: select all geometry, press R, X, -90, Enter to rotate -90 degrees around the X axis, then apply the rotation with Ctrl+A > Rotation. Now the model's "up" aligns with the Y axis in the raw vertex data. Second, you can rely on the viewer to handle the conversion, which brings us to the next section.
Fixing Orientation in Code and Viewers
If you are building a web application that loads 3D models, you will eventually need to handle orientation mismatches in code. In Three.js, the most common approach is to rotate the loaded model after import:
- For a Z-up model displayed in Three.js (Y-up), apply
model.rotation.x = -Math.PI / 2. - For a model that appears mirrored, apply
model.scale.x = -1and update the face winding order. - For a model that faces the wrong direction, rotate around the up axis:
model.rotation.y = Math.PI.
These rotations should be applied to the root of the loaded scene graph, not to individual meshes. Applying them to the root ensures that all children — meshes, lights, cameras — rotate together and maintain their relative positions.
A more sophisticated approach is to read the file format's axis metadata (if available) and compute the correct rotation matrix automatically. This is what well-built viewers do. The FBX loader in Three.js, for example, reads the FBX header's axis properties and applies the correct transformation during import. The GLTF loader does not need to because GLTF always specifies Y-up.
How GeometryViewer Handles Orientation
GeometryViewer auto-detects common orientation mismatches and corrects them. When you load an STL file, GeometryViewer analyzes the bounding box of the model. If the model's height (the extent along the axis perpendicular to the largest face) aligns with Z rather than Y, GeometryViewer applies an automatic 90-degree rotation to display the model upright. This heuristic works correctly for the vast majority of models — particularly mechanical parts, 3D printing models, and architectural elements.
For formats that include axis metadata — GLTF, FBX, COLLADA — GeometryViewer reads the metadata and applies the mathematically correct transformation. No heuristic guessing is needed. This is one of the reasons we recommend using GLTF or GLB when possible: the format removes ambiguity.
Quick Fix Guide
Model on its back? It is a Z-up model in a Y-up viewer. Rotate -90 degrees around X.
Model on its face? Forward axis is swapped. Rotate 90 or -90 degrees around X.
Model mirrored? Coordinate handedness mismatch. Scale -1 on one axis.
Model facing backwards? Rotate 180 degrees around Y (up axis).
Or drop your file into GeometryViewer and let it auto-correct.
Preventing Orientation Issues in Your Workflow
The best strategy is to standardize on a single coordinate convention across your pipeline. If you are working on web 3D, adopt Y-up as your standard — it is what the browser ecosystem expects. Configure your 3D software to export with the correct axis settings. Test every export in your target viewer before publishing. And whenever possible, use GLTF or GLB — the format's explicit Y-up convention eliminates an entire class of bugs.
If you receive models from clients or collaborators and cannot control the export settings, keep a small test pipeline ready. Load the model, check the orientation, apply the correction, and re-export in a standardized format. A five-minute fix at the start of a project saves hours of debugging later.
Orientation issues are one of the most common — and most confusing — problems in 3D development. The underlying cause is simple: the industry never agreed on which way is up. Once you understand the two conventions and know how to convert between them, the problem becomes mechanical to solve. Every 3D developer encounters this, and now you know exactly what to do about it.