Pipeline Overview: 7 Steps
CAD Source → Format Conversion → Retopology → UV Unwrap → Channel Split → Texture Compress → glTF Pack → Ship
① ② ③ ④ ⑤ ⑥ ⑦
Every step has an explicit pass/fail threshold. Skip any and all downstream optimizations get diluted.
① CAD Source Acceptance
Ranked by suitability (best → worst):
| Format | Preserves Topology | Preserves Assembly | Preserves Material Names | Grade |
|---|---|---|---|---|
| STEP / Parasolid (.x_t) | ✅ | ✅ | ⚠️ | ⭐⭐⭐⭐⭐ |
| SolidWorks .sldasm | ✅ | ✅ | ✅ | ⭐⭐⭐⭐ |
| Rhino .3dm | ⚠️ | ⚠️ | ⚠️ | ⭐⭐⭐ |
| FBX / OBJ (render exports) | ❌ (over-tessellated) | ❌ | ⚠️ | ⭐⭐ last resort only |
| STL | ❌ | ❌ | ❌ | ⭐ NEVER USE |
Acceptance checklist:
- Part names are human-readable (e.g.
FAB-001-Leg-Left— notMesh.287) - Assembly hierarchy is clean (≤ 5 sub-assembly levels deep)
- No part interpenetrations (causes AO baking artifacts)
② Format Conversion: Preserve Assembly Hierarchy
Most common mistake right here: people dump CAD straight into Blender → export OBJ → lose the entire assembly tree → spend 10× engineering effort later re-splitting individual parts for the configurator.
Correct toolchain, ranked:
- Datakit CrossManager (industry gold — 99% format coverage)
- Autodesk Forge (cloud API, great for batch workflows)
- ANSYS SpaceClaim (indispensable for healing CAD geometry issues)
Output target: An intermediate .fbx (or equivalent) that retains part naming + assembly hierarchy — zero decimation at this stage.
③ Retopology & Decimation: Triangle Budget
| Category | Target tris per SKU | Mobile target |
|---|---|---|
| Chairs / small furniture | 8,000 – 15,000 | ≤ 12,000 |
| Sofas / modular seating | 20,000 – 40,000 | ≤ 30,000 |
| Doors / windows / arch parts | 15,000 – 35,000 | ≤ 25,000 |
| Small consumer electronics | 6,000 – 12,000 | ≤ 8,000 |
| Industrial machinery (lite) | 50,000 – 100,000 | ≤ 70,000 |
Decimation tools ranked:
- Simplygon (best-in-class automated; protects UVs & seams)
- InstaLOD (price-friendly, near-Simplygon quality)
- Blender Decimate modifier (manual fallback, not recommended for batch)
⚠️ Hard constraint: No visible normal tearing after decimation. If it exists → go back to the original CAD and heal the geometry first. Don’t try to patch it in decimation.
④ UV Unwrap: You Need (at least) 2 UV Sets
PBR pipelines require a minimum of 2 UV sets — we recommend 3:
| UV Set | Purpose | Rules |
|---|---|---|
| UV0 | BaseColor / Normal / Roughness / Metallic | Zero overlap in 0–1 space, ≥ 85% utilization |
| UV1 | Ambient Occlusion / Lightmap | Overlap OK by bake policy; keep 4–8px gutter between charts |
| UV2 | (Optional) Decals / custom engraving | Per-face, as needed |
Best-in-class tool: RizomUV (fastest auto-symmetric unwrap by a wide margin).
⑤ Channel Split: Only 4 Textures Matter for Web
Web PBR ≠ offline render PBR. Don’t export all 8 Substance maps — only 4 are required for production WebGL:
| Map | Format | Compression | Typical Size |
|---|---|---|---|
| BaseColor (+ Alpha if needed) | PNG → KTX2 | UASTC + RDO | 1024² or 2048² |
| Normal (OpenGL convention) | PNG → KTX2 | UASTC Normal mode | same as above |
| ORM (Occlusion-Roughness-Metallic packed) | PNG → KTX2 | R=AO, G=Rough, B=Metal | same as above |
| Emissive (if applicable) | PNG → WebP | Lossy 85% | same as above; delete if unused |
⚠️ Common gotcha: Roughness MUST be gamma-corrected correctly. If your roughness map looks too dark, 9 times out of 10 it’s an sRGB/linear tag mismatch.
⑥ Texture Compression: KTX2 or Bust
It’s 2026 — stop shipping raw PNG / JPG textures:
| Format | Size ratio (quality-matched) | iOS | Android | Desktop Chrome |
|---|---|---|---|---|
| PNG | 100% (baseline) | ✅ | ✅ | ✅ |
| WebP | ~50% | ✅ 14+ | ✅ | ✅ |
| KTX2 (UASTC) | ~25% | ✅ 16+ | ✅ 12+ | ✅ 106+ |
| KTX2 (Basis ETC1S) | ~15% | ✅ | ✅ | ✅ |
Compression tool: Khronos’ official toktx CLI, or our online batch compressor.
Hard target per SKU: All assets (geometry + textures) combined ≤ 3MB first-screen; ≤ 2MB on mobile.
⑦ glTF Pack & Deploy
Final pass with glTF Transform — 3 operations:
- Inline all textures into a single
.glb(prevents request waterfalls) - Draco-compress geometry (~70% typical compression)
- Batch-convert all remaining PNG textures → KTX2
// Minimal glTF Transform snippet
import { NodeIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';
import { draco, textureCompress } from '@gltf-transform/functions';
const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS);
const document = await io.read('input.glb');
await document.transform(
draco({ method: 'edgebreaker' }),
textureCompress({ encoder: 'ktx2' })
);
await io.write('output.glb', document);
Final 4-Point Gate Before Ship
Every SKU must pass before going live.
| Metric | Threshold | Measurement |
|---|---|---|
| LCP | < 1.5s (4G) | Chrome Lighthouse |
| FPS | ≥ 60 desktop / ≥ 45 mid-tier mobile | Manual spot-check via renderer.info |
| Peak RAM | ≤ 250 MB (mobile) | Chrome DevTools Memory |
| Texture fidelity | No visible blocking at 200% zoom | Visual sign-off + side-by-side |
Fail any gate → go back to the relevant step. Do not ship broken assets.
Closing
A high-quality asset pipeline is the bedrock of a configurator’s perceived quality. Invest a week standardizing your pipeline now — it pays for itself 10× over in firefighting avoided later.