Communitygithub.com

zipang/Three.js und glTF Web-Pipeline

Optimieren Sie 3D-Assets (.glb und .gltf) und integrieren Sie sie in interaktive Web-Animationen mit Three.js, React Three Fiber, GSAP und gltf-transform. Verwenden Sie es für Komprimierung (Draco, Meshopt, KTX2), Pivot- und Animations-Setup sowie Web-Rendering.

Was ist Three.js und glTF Web-Pipeline?

Diese Fertigkeit beschreibt eine vollständige Pipeline zur Optimierung und Integration von 3D-Modellen im glTF-Format für das Web, speziell für die Verwendung mit Three.js. Sie deckt den gesamten Workflow ab: von der korrekten Exportkonfiguration in Blender oder vcad (mit Schwerpunkt auf Node-Namen, Pivots, Transformationen und Geometriebudget), über die CLI-Optimierung mit @gltf-transform/cli (Meshopt-, Draco- und KTX2-Komprimierung), bis hin zur endgültigen Integration in Three.js. Die Anleitung umfasst das robuste Laden von komprimierten Modellen (mit DRACOLoader und MeshoptDecoder), zwei Methoden zur Animation (prozedural über Node-Transforms und gebackene Clips mit AnimationMixer), PBR-Beleuchtung für Metallteile und wichtige Performance-Regeln. Die Pipeline ist plattformunabhängig und kann mit Bun oder Node.js ausgeführt werden. Sie ist besonders nützlich für Entwickler, die performante, interaktive 3D-Webanwendungen mit reibungslosen Animationen und effizienter Asset-Nutzung erstellen möchten.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/zipang/bender-agent/tree/HEAD/.agents/skills/threejs-web

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Three.js und glTF Web-Pipeline?

Diese Fertigkeit beschreibt die Schritte, die ein Blender- oder vcad-Modell in eine kleine .glb-Datei verwandeln. Die Datei muss schnell laden und sich in Three.js einfach animieren lassen.

1. Export-Checkliste für Blender und vcad

Node-Namen

  • Benennen Sie jedes bewegliche Teil mit einem klaren und stabilen Namen: Head, Visor, Eye_L, Eye_R, Torso_Door, Wheel_FL, Wheel_FR, Steering_Wheel.
  • Three.js findet das Teil dann mit model.getObjectByName("Torso_Door").

Pivots

  • Setzen Sie den Ursprung der Wurzel in die Mitte der Basis des Modells. In Three.js sitzt das Modell dann auf dem Boden bei Y = 0.
  • Setzen Sie den Pivot jedes artikulierten Teils auf seine Rotationsachse. Beispiele: Türscharnier, Radmitte, Halsbasis, Antennenbasis.

Transformationen

  • Wenden Sie vor dem Export alle Transformationen an.
  • Der Maßstab muss 1, 1, 1 sein. Die Ruhe-Rotation muss 0, 0, 0 sein.
  • Diese Regel verhindert Drift und Scherung während der prozeduralen Animation.

Geometrie-Budget

  • Verbinden Sie statische Meshes, die ein Material teilen. Dieser Schritt reduziert die Draw Calls.
  • Behalten Sie ein Mesh nur dann separat, wenn ein Skript es allein animiert. Verwenden Sie ein SkinnedMesh mit einer Armature für weiche Verformung.
  • Zielen Sie auf einige tausend Dreiecke pro Hero-Asset. Streben Sie unter 1.000 Dreiecke für Hintergrund-Props an.

2. CLI-Optimierung mit @gltf-transform/cli

Das Projekt verwendet Bun. Führen Sie das Tool mit bunx aus. npx funktioniert auch auf Maschinen mit Node.js.

# Meshes, Texturen und Animationen anzeigen
bunx @gltf-transform/cli inspect model.glb

# Vollständige Optimierung für das Web: Meshopt plus WebP plus Bereinigung
bunx @gltf-transform/cli optimize model.glb model-optimized.glb \
  --compress meshopt \
  --texture-compress webp \
  --texture-size 2048

# Alternative: Draco-Geometriekomprimierung
bunx @gltf-transform/cli draco model.glb model-draco.glb

Meshopt oder Draco

  • Meshopt (EXT_meshopt_compression) dekodiert sehr schnell. Es behält die Vertex-Reihenfolge bei und komprimiert auch Animations-Keyframes und Morph-Targets. Verwenden Sie es für animierte Assets.
  • Draco (KHR_draco_mesh_compression) ergibt die kleinste Datei für dichte statische Meshes. Beispiele: Autokarosserien und Scans. Der Decoder benötigt mehr Zeit beim Start.

Weitere nützliche Schritte

# Doppelte Meshes und ungenutzte Daten entfernen
bunx @gltf-transform/cli dedup model.glb model.glb

# Texturen in KTX2 (BasisU) konvertieren
bunx @gltf-transform/cli etc1s model.glb model-ktx2.glb

Überprüfen Sie die Datei nach jedem Schritt. Bestätigen Sie die Dateigröße, die Dreiecksanzahl und die Texturgröße.

3. Three.js-Integration

Robuster Lader mit Draco und Meshopt

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');

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

const gltf = await gltfLoader.loadAsync('/models/bender-optimized.glb');
const root = gltf.scene;
scene.add(root);

Zwei Animationsmethoden

  1. Prozedurale Animation mit Node-Transformationen. Verwenden Sie diese Methode für Roboter, Fahrzeuge und andere starre Teile. Beispiele: Radrotation, Türöffnung, Kopfbewegung, Antennenschwanken.
const head = root.getObjectByName('Head');
const door = root.getObjectByName('Torso_Door');
const antenna = root.getObjectByName('Antenna');

function animate(time) {
  if (antenna) {
    antenna.rotation.z = Math.sin(time * 0.005) * 0.15;
  }
  if (head) {
    head.rotation.y = THREE.MathUtils.lerp(head.rotation.y, targetYaw, 0.1);
  }
}
  1. Gebackene Clips mit THREE.AnimationMixer. Verwenden Sie diese Methode für komplexe Zyklen aus Blender: Gehen, Tanzen und Gesichts-Morphs.
const mixer = new THREE.AnimationMixer(root);
const idleClip = THREE.AnimationClip.findByName(gltf.animations, 'Idle');
if (idleClip) {
  mixer.clipAction(idleClip).play();
}

// In der Render-Schleife:
// mixer.update(clock.getDelta());

PBR-Beleuchtung für Metallteile

Ein Metallmaterial (metalness > 0.8) sieht in Three.js schwarz aus, wenn es von nichts umgeben ist. Setzen Sie eine Umgebungsmap:

import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

const pmremGenerator = new THREE.PMREMGenerator(renderer);
scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;

Verwenden Sie scene.environmentIntensity, um die Reflexionsstärke anzupassen. Behalten Sie das Tone-Mapping bei THREE.ACESFilmicToneMapping für Metall-Assets.

Performance-Regeln

  • Ein Material pro Mesh-Gruppe. Jedes Material kostet einen Draw Call.
  • Texturen wiederverwenden. Packen Sie kleine Texturen in ein Atlas.
  • Setzen Sie renderer.outputColorSpace = THREE.SRGBColorSpace. Der glTF-Loader setzt die Textur-Farbräume.
  • Verwenden Sie THREE.InstancedMesh, wenn ein Asset mehrfach vorkommt.
  • Geben Sie ein Modell frei, wenn Sie es entfernen: Durchlaufen Sie die Szene, dann rufen Sie geometry.dispose() und material.dispose() auf.

Verwandte Skills