The pre-publish checklist for e-commerce 3D models
Most 3D product models ship broken in a way nobody notices until a customer does. This is the list of things worth checking, in the order that finds problems fastest.
Last reviewed July 27, 2026
Every item below has failed on a real storefront. They are ordered so that the cheapest checks — the ones that need nothing but the file — come first, and the ones needing a device come last.
1. Does it parse at all?
Run the Khronos glTF-Validator before anything else. It catches structurally invalid files that some viewers tolerate and others reject outright — bad GLB chunk lengths, out-of-range index accessors, buffer views that overrun their buffer. A file that renders in Blender can still be invalid glTF. See decoding validation errors.
2. Size, in three currencies
- Bytes on disk. Shopify's partner checklist targets about 4 MB; above 15 MB Shopify silently re-optimizes for you.
- Texels in GPU memory. A 2048 × 2048 texture is ~16 MB of VRAM once decoded, plus mips, no matter how small the JPEG was.
- Triangles. The Khronos Asset Creation Guidelines put the web-suitable ceiling around 500,000 triangles; past 2 million an asset is not a product-page asset.
3. Texture dimensions and power-of-two
Non-power-of-two textures are legal glTF — the validator only raises IMAGE_NPOT_DIMENSIONS as information — but they cannot be block-compressed into KTX2 without padding, and some mobile GPUs handle their mip chains poorly. KHR_texture_basisu additionally requires dimensions that are multiples of 4. Keep maps at 512, 1024 or 2048 and this whole class of problem disappears.
4. Are the maps packed correctly?
glTF expects occlusion, roughness and metalness in the red, green and blue channels of a single texture. Three separate greyscale files is triple the memory for identical output. Check also that base colour is sRGB and that normal, ORM and any data map are linear — a normal map tagged sRGB produces subtly wrong lighting that reads as "cheap".
5. Tangents where normal maps need them
If a material has a normal texture and the mesh has no TANGENT attribute, the validator emits MESH_PRIMITIVE_GENERATED_TANGENT_SPACE: "Runtime-generated tangent space may be non-portable across implementations." That is the polite description of a model whose surface detail looks different in three.js, Quick Look and your DCC. Either export tangents or accept that the normal map is decorative.
6. Scale and origin
Model in real-world units. Shopify wants the base of the product on the grid origin, because AR viewers place objects on a floor plane using the origin. Separately, in USDZ, metersPerUnit must be 1 — Safari 27 shipped a fix for <model> elements "displaying at 100x the expected size for assets authored in tools that use centimeter units", which tells you exactly how common that bug is.
7. Disconnected geometry and floaters
Scanned, sculpted and AI-generated meshes routinely carry small disconnected islands — a stray tetrahedron a metre from the product, an interior shell nobody will see. They inflate bounds (so the camera frames the product wrong), inflate triangle counts, and occasionally appear as visible specks in AR. See cleaning up AI-generated models.
8. UV island spacing
Block-compressed formats work on 4 × 4 texel tiles. Two UV islands sitting closer than about four texels will bleed into each other once the texture is compressed, producing coloured fringes along seams. It is invisible in an uncompressed preview and obvious in production — which is why it is worth checking mechanically rather than by eye.
9. Material features that USDZ cannot carry
If your model uses KHR_materials_transmission, KHR_materials_volume, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_iridescence, KHR_materials_anisotropy or KHR_materials_specular, the iOS AR version will not look like the web version. Transmission and volume are the severe ones: refractive glass collapses to something opaque. Bake those looks into base colour, metallic and roughness before export — why converters break PBR has the detail.
10. USDZ packaging
If you are shipping your own USDZ rather than letting the platform generate one, the archive itself has rules: every entry stored uncompressed, each entry's data starting on a 64-byte boundary, the default .usd* stage as the first entry, and every referenced texture actually inside the bundle. Break any of them and Quick Look shows nothing — see why a USDZ will not open.
11. Look at it on a phone
Everything above is checkable from the bytes. This one is not. Apple exposes no headless Quick Look renderer, so nobody — us included — can promise a device-accurate preview from a validator. For your top SKUs, open the model in AR on a real iPhone and a real mid-range Android, and look at it.
Reading about it is slower than measuring it. Drop your .glb, .gltf, or .usdz in and get every blocker on this page checked against the real bytes — packaging, textures, geometry, AR parity — with the fix for each one.