Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Threejs Agents Model Optimizer

  • 20 installs
  • 11 repo stars
  • Updated July 8, 2026
  • openaec-foundation/three.js-claude-skill-package

Helps with ai & agent building tasks.

About

threejs-agents-model-optimizer is a Claude Code skill in the AI & Agent Building category.

  • threejs-agents-model-optimizer
  • AI & Agent Building
  • AI-coding skill

Threejs Agents Model Optimizer by the numbers

  • 20 all-time installs (skills.sh)
  • +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #10,459 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/three.js-claude-skill-package --skill threejs-agents-model-optimizer

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs20
repo stars11
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/three.js-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

threejs-agents-model-optimizer

Quick Reference

Optimization Pipeline Overview

INPUT (.glb/.gltf)
  |
  v
[1. ASSESS] ── polygon count, texture sizes, file size, draw calls
  |
  v
[2. MESH OPTIMIZE] ── dedup, flatten, join, weld, simplify
  |
  v
[3. TEXTURE OPTIMIZE] ── resize, KTX2 compress, atlas
  |
  v
[4. COMPRESS] ── Draco mesh compression, quantize attributes
  |
  v
[5. VALIDATE] ── visual diff, file size check, runtime test
  |
  v
OUTPUT (optimized .glb)

Target File Size Budgets

PlatformMax File SizeMax PolygonsMax Texture Size
Mobile web2 MB50K triangles1024x1024
Desktop web5 MB200K triangles2048x2048
Desktop app20 MB500K triangles4096x4096
Hero asset (single)1 MB30K triangles1024x1024

Tool Selection

ToolBest ForInstall
gltf-transformFull pipeline, scriptable, Node.js APInpm i @gltf-transform/cli
gltfpackFast one-shot compressionnpm i -g gltfpack
BlenderManual mesh editing, UV repackingBlender 3.6+

Critical Warnings

NEVER skip the assessment step -- optimizing blindly wastes time and can produce worse results than the original.

NEVER apply Draco compression AND meshopt compression to the same file -- they are mutually exclusive. Choose ONE.

NEVER use KTX2 UASTC for diffuse color maps on mobile -- UASTC textures are 8-16 bytes/texel in VRAM. ALWAYS use ETC1S for color maps on mobile targets.

NEVER simplify meshes below 10% of original without visual validation -- aggressive simplification destroys silhouettes and UV mapping.

ALWAYS validate optimized models visually before shipping -- automated metrics cannot catch all visual artifacts.

ALWAYS keep the original unoptimized model in version control -- optimization is lossy and irreversible.

---

Step 1: Assessment

Before optimizing, ALWAYS gather these metrics:

# Using gltf-transform CLI
npx gltf-transform inspect model.glb

# Key output to check:
# - Mesh count and total triangle count
# - Texture count, dimensions, and format
# - Total file size (uncompressed)
# - Accessor count (indicates potential deduplication)
# - Animation track count

Assessment Decision Tree

File size > target budget?
├── YES: Textures > 50% of file size?
│   ├── YES → Start with texture optimization (Step 3)
│   └── NO → Start with mesh optimization (Step 2)
└── NO: Draw calls > 50?
    ├── YES → Merge meshes (join/flatten)
    └── NO → Only apply compression (Step 4)

Polygon Count Guidelines

Asset TypeTarget TrianglesNotes
Background prop100-500Minimal detail
Mid-ground object1K-5KVisible but not hero
Hero/focus object10K-50KHigh detail, close-up
Character15K-30KWith LOD chain
Full scene100K-300KAll objects combined
Architectural (BIM)200K-500KSimplified from CAD

---

Step 2: Mesh Optimization

gltf-transform Mesh Pipeline

ALWAYS run these operations in this order:

# 1. Remove duplicate accessors and unused data
npx gltf-transform dedup input.glb deduped.glb

# 2. Flatten node hierarchy (removes empty nodes)
npx gltf-transform flatten deduped.glb flat.glb

# 3. Join meshes sharing the same material
npx gltf-transform join flat.glb joined.glb

# 4. Weld vertices (merge vertices within tolerance)
npx gltf-transform weld joined.glb welded.glb --tolerance 0.0001

# 5. Simplify mesh (reduce triangle count)
npx gltf-transform simplify welded.glb simplified.glb \
  --ratio 0.5 \
  --error 0.001

# 6. Remove unused resources
npx gltf-transform prune simplified.glb output.glb

Combined Pipeline (Single Command)

npx gltf-transform optimize input.glb output.glb \
  --compress draco \
  --texture-compress ktx2

Mesh Simplification Settings

Quality LevelRatioError ToleranceUse Case
Minimal0.750.0005Subtle reduction, preserves detail
Moderate0.500.001Balanced quality/size
Aggressive0.250.005LOD1/LOD2 generation
Extreme0.100.01LOD3, distant objects only

Weld Settings

ToleranceEffect
0.0001Conservative -- merges only nearly-identical vertices
0.001Standard -- good for most models
0.01Aggressive -- may cause visible seams on hard edges

---

Step 3: Texture Optimization

Texture Decision Tree

Texture type?
├── Color/Diffuse (baseColorTexture)
│   ├── Mobile → ETC1S (KTX2), max 1024px
│   └── Desktop → UASTC (KTX2), max 2048px
├── Normal map
│   └── ALWAYS UASTC (KTX2) — ETC1S causes visible artifacts on normals
├── ORM (occlusion/roughness/metallic)
│   └── ETC1S (KTX2) — perceptual quality less critical
├── Emissive
│   └── ETC1S (KTX2) — unless HDR, then keep as-is
└── HDR environment
    └── Keep as .hdr or .exr — do NOT KTX2 compress

KTX2 Compression Commands

# ETC1S: smaller file, lower quality (color maps, ORM)
npx gltf-transform ktx2 input.glb output.glb \
  --slots "baseColorTexture,emissiveTexture,occlusionTexture" \
  --filter "baseColorTexture=etc1s" \
  --quality 128

# UASTC: larger file, higher quality (normal maps)
npx gltf-transform ktx2 input.glb output.glb \
  --slots "normalTexture" \
  --filter "normalTexture=uastc"

KTX2: ETC1S vs UASTC

PropertyETC1SUASTC
File sizeVery small (6-8x smaller)Moderate (2-4x smaller)
VRAM usageSmallLarge (8-16 bytes/texel)
QualityGood for colorNear-lossless
Decode speedFastRequires transcoding
Best forColor maps, ORM, emissiveNormal maps, detail textures

Texture Resize

# Resize all textures to max 1024x1024
npx gltf-transform resize input.glb output.glb --width 1024 --height 1024

# Resize only textures larger than 2048px
npx gltf-transform resize input.glb output.glb --width 2048 --height 2048

---

Step 4: Mesh Compression

Draco Compression

# Default Draco compression
npx gltf-transform draco input.glb output.glb

# Draco with quality settings
npx gltf-transform draco input.glb output.glb \
  --quantize-position 14 \
  --quantize-normal 10 \
  --quantize-texcoord 12 \
  --quantize-color 8

Draco Quantization Bits

AttributeDefaultHigh QualityAggressive
Position14 bits16 bits11 bits
Normal10 bits12 bits8 bits
TexCoord12 bits14 bits10 bits
Color8 bits10 bits6 bits

Higher bits = better quality, larger file. 14-bit position is sufficient for most models.

Quantize Without Draco

# Quantize attributes (reduces file size without Draco dependency)
npx gltf-transform quantize input.glb output.glb

Loading Draco-Compressed Models in Three.js

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

const dracoLoader = new DRACOLoader();
// ALWAYS set the decoder path — Draco uses WASM
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.6/');
dracoLoader.preload();

const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);

gltfLoader.load('model-draco.glb', (gltf) => {
  scene.add(gltf.scene);
});

// ALWAYS dispose when done
dracoLoader.dispose();

Loading KTX2-Compressed Textures

import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';

const ktx2Loader = new KTX2Loader();
// ALWAYS set the transcoder path — KTX2 uses WASM basis_transcoder
ktx2Loader.setTranscoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/basis/');
ktx2Loader.detectSupport(renderer);

const gltfLoader = new GLTFLoader();
gltfLoader.setKTX2Loader(ktx2Loader);

---

Step 5: Validation

Validation Checklist

After optimization, ALWAYS verify:

1. File size -- meets target budget from Step 1 2. Visual quality -- load in Three.js viewer, compare to original 3. Bounding box -- same dimensions as original (no scale errors) 4. Materials -- all textures load, no missing maps 5. Animations -- all clips play correctly (if applicable) 6. Performance -- measure draw calls, frame time

# Compare file sizes
ls -la original.glb optimized.glb

# Validate GLTF structure
npx gltf-transform inspect optimized.glb

# Check for errors
npx gltf-transform validate optimized.glb

---

LOD Generation

LOD Chain Strategy

LOD LevelScreen CoverageTriangle RatioDistance
LOD0>30% screen1.0 (full)Near
LOD110-30% screen0.5Medium
LOD23-10% screen0.25Far
LOD3<3% screen0.10Very far

Generating LODs with gltf-transform

# Generate LOD chain
npx gltf-transform simplify model.glb lod0.glb --ratio 1.0
npx gltf-transform simplify model.glb lod1.glb --ratio 0.5 --error 0.001
npx gltf-transform simplify model.glb lod2.glb --ratio 0.25 --error 0.005
npx gltf-transform simplify model.glb lod3.glb --ratio 0.10 --error 0.01

Three.js LOD Implementation

import * as THREE from 'three';

const lod = new THREE.LOD();

// ALWAYS add LODs from highest to lowest detail
lod.addLevel(meshLOD0, 0);    // distance 0 = closest
lod.addLevel(meshLOD1, 10);   // switch at 10 units
lod.addLevel(meshLOD2, 30);   // switch at 30 units
lod.addLevel(meshLOD3, 80);   // switch at 80 units

scene.add(lod);

// In render loop — ALWAYS call update for LOD switching
lod.update(camera);

---

gltfpack Alternative

For quick one-shot optimization without a pipeline:

# Install
npm install -g gltfpack

# Optimize with meshopt compression
gltfpack -i input.glb -o output.glb -cc -tc

# Flags:
# -cc  mesh compression (meshopt)
# -tc  texture compression (KTX2/BasisU)
# -si N  simplify to ratio (0.0-1.0)
# -tp  texture power-of-two resize

NEVER mix gltfpack meshopt output with gltf-transform Draco -- the compression formats are incompatible.

Loading Meshopt-Compressed Models

import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

const gltfLoader = new GLTFLoader();
gltfLoader.setMeshoptDecoder(MeshoptDecoder);

---

Blender Export Optimization

When exporting from Blender to glTF:

SettingRecommended ValueWhy
FormatglTF Binary (.glb)Single file, smaller
Apply ModifiersONBakes procedural geometry
CompressionOFFCompress with gltf-transform after
TexturesIncludeEmbedded in .glb
Limit toSelected ObjectsAvoid exporting hidden/unused
+Y UpONThree.js convention

NEVER enable Draco in Blender's exporter -- Blender's Draco implementation is outdated. ALWAYS compress with gltf-transform or gltfpack after export.

---

Node.js Scripting with gltf-transform API

import { NodeIO } from '@gltf-transform/core';
import { dedup, flatten, join, weld, simplify,
         textureCompress, draco, prune, quantize } from '@gltf-transform/functions';
import draco3d from 'draco3dgltf';
import sharp from 'sharp';

const io = new NodeIO()
  .registerExtensions(KHRONOS_EXTENSIONS)
  .registerDependencies({
    'draco3d.decoder': await draco3d.createDecoderModule(),
    'draco3d.encoder': await draco3d.createEncoderModule(),
  });

const document = await io.read('input.glb');

// ALWAYS run transforms in dependency order
await document.transform(
  dedup(),
  flatten(),
  join(),
  weld({ tolerance: 0.0001 }),
  simplify({ ratio: 0.5, error: 0.001 }),
  textureCompress({ targetFormat: 'ktx2' }),
  draco(),
  prune(),
  quantize(),
);

await io.write('output.glb', document);

---

Reference Links

  • references/methods.md -- gltf-transform API and Three.js loader methods
  • references/examples.md -- Complete optimization pipeline examples
  • references/anti-patterns.md -- Common optimization mistakes

Official Sources

  • https://gltf-transform.dev/
  • https://threejs.org/docs/#examples/en/loaders/GLTFLoader
  • https://threejs.org/docs/#examples/en/loaders/DRACOLoader
  • https://threejs.org/docs/#examples/en/loaders/KTX2Loader
  • https://threejs.org/docs/#api/en/objects/LOD
  • https://github.com/zeux/meshoptimizer

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.