mcpField
T
threejs-agents-model-optimizer

threejs-agents-model-optimizer

github.com/impertio-studio開発23153 回インストール30 週間前に更新
リポジトリ

threejs-agents-model-optimizer について

Three.js プロジェクトの開発者向けに、GLB と glTF モデルを最適化するスキルです。評価からメッシュ・テクスチャ処理、圧縮、LOD 生成、検証までの手順を示します。

主な機能

  1. 01モデル容量と複雑さの評価
  2. 02メッシュの整理と簡略化
  3. 03テクスチャのリサイズと圧縮
  4. 04Draco と meshopt の圧縮ガイド
  5. 05LOD の生成と検証

活用シーン

  1. 01Web の容量予算に合わせた GLB の準備
  2. 02テクスチャとメッシュの容量削減
  3. 03モデルの LOD 生成と確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/impertio-studio/three.js-claude-skill-package --skill threejs-agents-model-optimizer

インストール後、Claude Code で/threejs-agents-model-optimizerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.gitkeep
references/
anti-patterns.md
examples.md
methods.md

詳細

threejs-agents-model-optimizer

クイックリファレンス

最適化パイプラインの概要
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)
目標ファイルサイズの上限
プラットフォーム最大ファイルサイズ最大ポリゴン数最大テクスチャサイズ
モバイルウェブ2 MB50K triangles1024x1024
デスクトップウェブ5 MB200K triangles2048x2048
デスクトップアプリ20 MB500K triangles4096x4096
ヒーローアセット(単体)1 MB30K triangles1024x1024
ツールの選択
ツール最適な用途インストール
gltf-transformフルパイプライン、スクリプト化可能、Node.js APInpm i @gltf-transform/cli
gltfpack高速な単発圧縮npm i -g gltfpack
Blender手動でのメッシュ編集、UVの再パックBlender 3.6+
重要な警告

絶対に 評価のステップを省略しないでください。闇雲な最適化は時間の無駄になり、元のモデルよりも悪い結果を招く可能性があります。

絶対に 同じファイルにDraco圧縮とmeshopt圧縮を適用しないでください。この2つは併用できません。どちらか一方を選んでください。

絶対に モバイル向けのディフューズカラーマップにKTX2 UASTCを使用しないでください。UASTCテクスチャはVRAMで1テクセルあたり8〜16バイトを使用します。モバイル向けのカラーマップには、必ずETC1Sを使用してください。

絶対に 視覚的な検証をせずに、メッシュを元の10%未満に簡略化しないでください。過度な簡略化はシルエットとUVマッピングを損ないます。

必ず 最適化したモデルを出荷前に目視で検証してください。自動計測ではすべての視覚的なアーティファクトを検出できません。

必ず 最適化前の元のモデルをバージョン管理に残してください。最適化は非可逆であり、元に戻せません。


ステップ1:評価

最適化の前に、必ず次の指標を収集してください。

# 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
評価の判断ツリー
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)
ポリゴン数のガイドライン
アセットの種類目標三角形数備考
背景小道具100-500ディテールは最小限
中景オブジェクト1K-5K見えるが、主役ではない
主役/フォーカス対象のオブジェクト10K-50K高精細、クローズアップ
キャラクター15K-30KLODチェーンを使用
シーン全体100K-300K全オブジェクトの合計
建築(BIM)200K-500KCADから簡略化

ステップ2:メッシュの最適化

gltf-transformのメッシュパイプライン

必ず次の操作をこの順序で実行してください。

# 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
統合パイプライン(単一コマンド)
npx gltf-transform optimize input.glb output.glb \
  --compress draco \
  --texture-compress ktx2
メッシュ簡略化の設定
品質レベル比率誤差許容値用途
最小限0.750.0005わずかな削減で、ディテールを維持
中程度0.500.001品質とサイズのバランス
強め0.250.005LOD1/LOD2の生成
極端0.100.01LOD3、遠景オブジェクトのみ
頂点結合の設定
許容値効果
0.0001控えめ — ほぼ同一の頂点のみを結合
0.001標準 — ほとんどのモデルに適しています
0.01強め — ハードエッジに目に見える継ぎ目が生じる場合があります

ステップ3:テクスチャの最適化

テクスチャの判断ツリー
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圧縮コマンド
# 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とUASTCの比較
特性ETC1SUASTC
ファイルサイズ非常に小さい(6〜8倍小さい)中程度(2〜4倍小さい)
VRAM使用量少ない多い(1テクセルあたり8〜16バイト)
品質カラーマップに適していますほぼロスレス
デコード速度高速トランスコードが必要
最適な用途カラーマップ、ORM、エミッシブノーマルマップ、ディテールテクスチャ
テクスチャのリサイズ
# 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

ステップ4:メッシュ圧縮

Draco圧縮
# 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の量子化ビット数
属性デフォルト高品質強め
位置14 bits16 bits11 bits
法線10 bits12 bits8 bits
テクスチャ座標12 bits14 bits10 bits
色8 bits10 bits6 bits

ビット数を増やすと品質が向上し、ファイルサイズも大きくなります。ほとんどのモデルでは、位置に14ビットあれば十分です。

Dracoを使わない量子化
# Quantize attributes (reduces file size without Draco dependency)
npx gltf-transform quantize input.glb output.glb
Three.jsでのDraco圧縮モデルの読み込み
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();
KTX2 圧縮テクスチャの読み込み
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/[email protected]/examples/jsm/libs/basis/');
ktx2Loader.detectSupport(renderer);

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

ステップ 5:検証

検証チェックリスト

最適化後は、必ず以下を確認してください。

  1. ファイルサイズ -- ステップ 1 の目標サイズを満たしていること
  2. ビジュアル品質 -- Three.js ビューアーで読み込み、元のデータと比較すること
  3. バウンディングボックス -- 元のデータと同じ寸法であること(スケールの誤りがないこと)
  4. マテリアル -- すべてのテクスチャが読み込まれ、マップが欠落していないこと
  5. アニメーション -- 該当する場合、すべてのクリップが正しく再生されること
  6. パフォーマンス -- ドローコールとフレーム時間を測定すること
# 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 の生成

LOD チェーンの戦略
LOD レベル画面占有率三角形の比率距離
LOD0画面の >30%1.0(全量)近距離
LOD1画面の 10~30%0.5中距離
LOD2画面の 3~10%0.25遠距離
LOD3画面の <3%0.10非常に遠い
gltf-transform での LOD 生成
# 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 実装
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 を使う方法

パイプラインを使わず、手早く一度だけ最適化する場合:

# 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

絶対に gltfpack の meshopt 出力と gltf-transform の Draco を混在させないでください。圧縮形式に互換性がありません。

Meshopt 圧縮モデルの読み込み
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

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

Blender のエクスポート最適化

Blender から glTF にエクスポートする場合:

設定推奨値理由
形式glTF Binary(.glb)単一ファイルで、サイズが小さい
モディファイアーを適用ONプロシージャルジオメトリをベイクする
圧縮OFFエクスポート後に gltf-transform で圧縮する
テクスチャ含める.glb に埋め込まれる
対象を限定選択したオブジェクト非表示または未使用のオブジェクトのエクスポートを防ぐ
+Y を上方向にするONThree.js の規約

絶対に Blender のエクスポーターで Draco を有効にしないでください。Blender の Draco 実装は古くなっています。エクスポート後は、必ず gltf-transform または gltfpack で圧縮してください。


gltf-transform API を使用した Node.js スクリプティング

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);

参考リンク

公式ソース

コメント