3D model optimization

How to optimize 3D models for web & AR

Short version: cut the triangle count to tens of thousands, compress the geometry with Draco or meshopt, shrink and supercompress textures with KTX2, ship a GLB for the web and a USDZ for iOS, and hold every asset to a file-size budget you verify on real phones. Do that and a model that once stalled will load fast in the browser and place instantly in AR.

Why optimization matters

Mobile AR and in-browser 3D viewers are bandwidth- and CPU-constrained. A model exported straight from a scanner, sculpt, or CAD package can carry millions of triangles and multiple 4K textures — fine for a workstation, fatal on a phone over a cellular connection. An oversized asset means a slow first paint, a spinning loader, dropped frames while orbiting, and an AR session that takes too long to start. Each of those frictions costs you viewers, and 3D commerce only pays off when shoppers actually reach the model: Shopify reports that adding 3D content raises conversion by an average of 94%. Getting performant 3D right is what lets that uplift land instead of getting lost behind a loading spinner.

The good news: optimization is mostly mechanical. The steps below take a heavy source asset and turn it into a lean runtime asset without a visible drop in quality.

The optimization steps

Each step lists what it is, why it helps, and how to do it.

  1. 1. Reduce polygon count

    What: bring the triangle count down to a sensible budget for the web — think tens of thousands of triangles per product, not millions. Why: every triangle costs memory and per-frame work, and phones have far less of both than a workstation. How: retopologize the mesh by hand for hero products, or run automatic decimation for catalog-scale work. Spend your polygon budget on the silhouette and the surfaces a shopper actually sees, and delete hidden interior geometry entirely.

  2. 2. Compress geometry with Draco or meshopt

    What: apply a geometry compressor to the vertex and index data. Why: on an untextured model the mesh is usually the largest part of the payload, and these codecs cut it dramatically. How: encode with Draco or the meshopt compressor (both are supported by glTF tooling and <model-viewer>). Pick a quantization level that holds visual quality, and remember the client pays a small decode cost at load.

  3. 3. Optimize textures

    What: cap resolution, atlas maps, and supercompress. Why: textures often dwarf the mesh in download size and eat GPU memory. How: cap each map to what is visible (1K–2K is usually plenty for a product), atlas several maps into fewer textures to reduce draw calls, and encode as KTX2 with Basis Universal supercompression so textures stay compressed on the GPU rather than decoding to full-size RGBA in memory.

  4. 4. Ship glTF/GLB for the web and USDZ for iOS

    What: deliver the right runtime format per platform. Why: GLB is the self-contained web and Android AR format, while Apple's native Quick Look AR needs USDZ. How: export GLB as your web runtime asset and generate a matching USDZ alongside it so AR works on both Android and iOS. If you are unsure which format does what, the format guide covers choosing a format in detail.

  5. 5. Test on real mobile devices

    What: verify the optimized asset on actual phones. Why: a model that flies on your laptop can still stutter on a mid-range phone over mobile data, and emulators hide that. How: drop the model into Google's <model-viewer> — the same component the viewer here uses — and load it on real mid-range Android and iOS devices to check load time, frame rate, and AR placement before you publish.

  6. 6. Set a file-size budget

    What: commit to a hard size ceiling per model. Why: without a budget, assets quietly bloat back up over time. How: pick a target — for example a few megabytes for a typical product — and treat it as a gate. If an asset exceeds it, go back and re-optimize geometry and textures until it fits. A budget turns optimization from a one-off cleanup into a repeatable standard across the catalog.

Optimization checklist

  • Triangle count reduced to a web-sane budget (tens of thousands, not millions).
  • Hidden interior geometry removed.
  • Geometry compressed with Draco or meshopt.
  • Texture resolution capped to what is visible (often 1K–2K).
  • Maps atlased to reduce draw calls.
  • Textures encoded as KTX2 / Basis Universal.
  • GLB exported as the web/Android runtime asset.
  • USDZ generated for native iOS Quick Look AR.
  • Loaded and checked in <model-viewer>.
  • Tested on real mid-range Android and iOS phones.
  • Final file size within the agreed budget.

References

Authoritative specification and documentation sources for the tools and formats above.

  • Khronos glTF — glTF is the Khronos Group's royalty-free runtime 3D asset format.
  • Google <model-viewer> — Google's open-source web component for rendering 3D models and launching AR.
  • Draco — Draco is Google's open-source mesh compression library.
  • KTX / Basis — KTX2 is the Khronos container for GPU textures, used with Basis Universal supercompression.

Last updated June 2026 · Photo-to-3D AR Viewer editorial

Frequently asked questions

What's a good polygon budget for web 3D?

For a single product on the web or in AR, aim for tens of thousands of triangles rather than the millions a raw scan or CAD export can carry. A clean retail product in roughly the 20,000–150,000 triangle range usually looks good while staying light enough for a mid-range phone. Use retopology or decimation to get there, and spend the polygons on the silhouette and visible detail, not on hidden interiors.

glTF or USDZ — which should I ship?

Ship both. glTF/GLB is the runtime format for the web and Android AR and is what <model-viewer> loads directly. USDZ is what Apple's iOS Quick Look needs for native AR. The common pattern is to author once, export GLB as the web runtime asset, and generate a matching USDZ so AR works on iPhones and iPads too. See the format guide for how the formats relate.

How do I shrink texture file size?

Cap texture resolution to what is actually visible (often 1K or 2K is plenty for a product), atlas several maps into fewer textures to cut draw calls, and encode textures as KTX2 with Basis Universal supercompression. KTX2 stays compressed on the GPU, so it reduces both download size and video memory compared with shipping large PNG or JPEG maps.

Does Draco compression hurt quality?

Draco is primarily a geometry compressor, and at sensible quantization settings the visual difference is usually imperceptible while the geometry payload shrinks dramatically. Very aggressive quantization can introduce small positional or normal artifacts, so test on your model and back off the settings if you see faceting or seams. Draco does add a decode step at load time, which is a minor CPU cost on the client.