Go to file
2026-08-30 22:19:14 +10:00
src SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
.gitignore SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
index.html SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
package-lock.json SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
package.json SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
README.md SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00
vite.config.js SHRINKGOD v1: local GLB optimizer — synced compare viewer, rig-protected simplify, texture crunch 2026-08-30 22:19:14 +10:00

🗜️ SHRINKGOD — local GLB optimizer

Drop in a heavy GLB, pick a target, compare original vs optimized side-by-side (synced camera, animation playback, wireframe), export. Everything runs client-side in the browser — gltf-transform + meshoptimizer WASM. No uploads, files never leave the machine.

Run

npm install
npm run dev        # http://localhost:5173
npm run build      # static build in dist/ — host anywhere, still fully local

Dev test hook: ?test=<file-in-public>.glb&run=1 auto-loads and optimizes.

Pipeline

dedup → flatten+join (static models only) → weld → per-primitive meshopt simplify → animation resample → prune → texture resize/re-encode → quantize → (optional) meshopt compression.

Rig protection (automatic)

  • Skinned meshes never go below 50% kept geometry and error is capped at 0.5% — vertex collapse near joints wrecks skin weights in motion.
  • Morph-target (blendshape) primitives are left untouched.
  • Mesh joining is disabled for rigged/animated models (would break node animation).
  • Best results: optimize before rigging — static geometry can be crunched far harder.

Textures

  • Longest side clamped to the chosen max (canvas re-encode).
  • Color/emissive maps optionally converted to WebP (quality slider); normal/roughness/occlusion maps always stay lossless PNG.
  • Re-encode is skipped if it wouldn't shrink the file.

Presets

geometry kept error max texture webp
Light 50% 0.5% 2048 no
Balanced 25% 1% 1024 yes
Crunch 10% 5% 512 yes

Known limits

  • Draco-compressed input not supported yet (friendly error; re-export without Draco).
  • Meshopt compression output (EXT_meshopt_compression) reads fine in three.js but not in Blender — leave it off for assets going back into a DCC.
  • KTX2/basis textures pass through untouched.

Bench (M5 MacBook Pro, Balanced preset)

  • 15.8 MB photogrammetry room scan (151k tris, 13 MB textures) → 1.5 MB (90%) in 5 s.
  • 3.5 MB rigged character (18.6k tris, 20 clips) → 2.7 MB (24%), clips + skinning intact (rig clamp limits geometry reduction by design).