CommunityCodierung & Entwicklunggithub.com

threejs-gltf-laden

Lädt glTF/GLB-Modelle in three.js r187 und spielt ihre Animationen ab: GLTFLoader, DRACO-, Meshopt- und KTX2-Decoder, AnimationMixer-Überblendungen und SkeletonUtils-Klone. Verwenden, wenn ein Modell unsichtbar oder winzig ist, Decoder-Dateien mit 404-Fehlern auftreten, Animationen nie abgespielt werden oder Klone sich ein Skelett teilen. Nicht für Szenenaufbau (`threejs-scene-setup`) oder Beleuchtung (`threejs-materials-lighting`).

Was ist threejs-gltf-laden?

Diese Fähigkeit ermöglicht das Laden und Animieren von glTF/GLB-Modellen in three.js Version r187. Sie deckt wichtige Workflows ab, darunter das Dekomprimieren von Geometrien mit DRACO und Meshopt sowie von Texturen mit KTX2. Das Skill beschreibt detailliert, wie man Modelle lädt, benannte Teile findet, AnimationClips abspielt (inklusive Überblendungen mittels AnimationMixer) und wie man Decoder für verschiedene Komprimierungserweiterungen korrekt anbindet. Es ist nützlich, wenn Modelle unsichtbar oder zu klein sind, Decoder-Dateien 404-Fehler verursachen oder Animationen nicht starten. Es gibt klare Anleitungen zur Fehlerbehebung, wie das Überprüfen der Modelldateien mit gltf-transform, das Validieren der Bounding Box und das Debuggen im Browser. Das Skill verweist auf zugehörige Fähigkeiten für Szenenaufbau und Beleuchtung und enthält Versionshinweise für three.js r187 und @gltf-transform/cli 4.5.1.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mext-ai/elearning-agent-skills/tree/HEAD/third-party/gamedev/threejs-gltf-loading

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

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

Dokumentation

glTF-Laden in three.js

Lädt .gltf / .glb-Modelle, einschließlich komprimierter Geometrie (DRACO, Meshopt) und Texturen (KTX2), und spielt deren Animationsclips ab. Die Muster beziehen sich auf r187; ein bestehendes Projekt behält seine fixierte Version, es sei denn, der Benutzer bittet um ein Upgrade. glTF ist das bevorzugte Laufzeitformat: OBJ hat keine Szenengraphik oder Animation, und FBX ist im Browser aufwendig zu parsen.

Wann verwenden

  • Importieren eines Modells oder Charakters, Untersuchen seiner Knotenhierarchie, Abspielen oder Überblenden von Clips, Erstellen vieler Kopien eines animierten Gegners oder Beheben eines Modells, das nicht angezeigt wird.
  • Dateien sind .gltf / .glb, oder Code importiert GLTFLoader, DRACOLoader oder KTX2Loader aus three/addons/loaders/....
  • Nicht für Renderer, Kamera und Schleife (threejs-scene-setup), Beleuchtung und Materialien des Modells (threejs-materials-lighting) oder Modellierungs- und Exporteinstellungen in einem DCC-Tool.

Arbeitsablauf

  1. Datei vor dem Schreiben des Loader-Codes inspizieren, wenn gltf-transform verfügbar ist: npx @gltf-transform/cli inspect model.glb listet Meshes, Erweiterungen (z. B. KHR_draco_mesh_compression, EXT_meshopt_compression, KHR_texture_basisu), Clips und Texturgrößen auf. Jede aufgeführte Komprimierungserweiterung benötigt ihren angeschlossenen Decoder.
  2. Mit GLTFLoader laden (loadAsync in asynchronem Code). Das Ergebnis enthält gltf.scene, die Wurzel Object3D, und gltf.animations, ein AnimationClip[].
  3. gltf.scene hinzufügen und einrahmen. glTF-Einheiten sind Meter; Namen und Grenzen protokollieren, um die Teile zu finden, die der Code steuern wird.
  4. Ein AnimationMixer pro animierter Wurzel, Aktionen aus mixer.clipAction(clip) und mixer.update(seconds) jedes Bild.
  5. Decoder anhängen für die in Schritt 1 gefundenen Erweiterungen. Seit r185 finden DRACOLoader und KTX2Loader ihre gebündelten Decoder-Dateien ohne Pfadangabe.
  6. Überprüfen mit Überprüfen.

Muster

1. Modell laden und einrahmen

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const gltf = await new GLTFLoader().loadAsync('assets/robot.glb');
const root = gltf.scene;
scene.add(root);

const box = new THREE.Box3().setFromObject(root);
console.log('Größe (m):', box.getSize(new THREE.Vector3()).toArray());
console.log('Clips:', gltf.animations.map((c) => c.name));

2. Einen Clip abspielen

const timer = new THREE.Timer();            // THREE.Clock ist seit r183 veraltet
const mixer = new THREE.AnimationMixer(gltf.scene);
const run = THREE.AnimationClip.findByName(gltf.animations, 'Run') ?? gltf.animations[0];
mixer.clipAction(run).play();

renderer.setAnimationLoop(() => {
  timer.update();
  mixer.update(timer.getDelta());           // Sekunden, nicht Millisekunden
  renderer.render(scene, camera);
});

3. Zwischen Clips überblenden

const actions = Object.fromEntries(gltf.animations.map((c) => [c.name, mixer.clipAction(c)]));
let current = actions.Idle;
current.play();

function transitionTo(name, duration = 0.3) {
  const next = actions[name];
  if (!next || next === current) return;
  next.reset().play();                      // Zurückspulen und alte Überblendung löschen
  current.crossFadeTo(next, duration, false);
  current = next;
}

4. Komprimierte Geometrie und Texturen

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader, DRACO_GLTF_CONFIG } from 'three/addons/loaders/DRACOLoader.js';
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

const loader = new GLTFLoader()
  .setDRACOLoader(new DRACOLoader().setDecoderPath(DRACO_GLTF_CONFIG)) // glTF-only WASM-Build (r185+)
  .setKTX2Loader(new KTX2Loader().detectSupport(renderer))             // benötigt den Renderer
  .setMeshoptDecoder(MeshoptDecoder);
// Diesen einen Loader für jedes Modell teilen, sodass Decoder und Worker nur einmal erstellt werden.

Bei Versionen vor r185 oder wenn der Host die gebündelten Dateien nicht ausliefert, die Ordner examples/jsm/libs/draco/ und libs/basis/ aus dem installierten three kopieren und diese Pfade an setDecoderPath / setTranscoderPath übergeben.

5. Ein benanntes Teil finden

const wheels = [];
gltf.scene.traverse((node) => {
  if (node.name.startsWith('Wheel')) wheels.push(node);
});
// In der Schleife: for (const w of wheels) w.rotation.x += dt * 4;

6. Ein Modell verkleinern, ohne die vom Code benötigten Teile zu verlieren

# Meshopt-Komprimierung, WebP-Texturen maximal 1024 px, benannte Knoten und Hierarchie beibehalten.
npx @gltf-transform/cli optimize in.glb out.glb \
  --compress meshopt --texture-compress webp --texture-size 1024 \
  --flatten false --join-named false
npx @gltf-transform/cli validate out.glb

optimize flacht standardmäßig die Hierarchie ab und verbindet Meshes, einschließlich benannter. Das reduziert Draw Calls, aber Code, der Wheel_FL sucht oder einen Türknoten animiert, findet dann nichts. Die beiden Flags für jedes Modell beibehalten, in das der Code eingreift. Die Ausgabe benötigt setMeshoptDecoder (Muster 4).

Überprüfen

  1. Dateiprüfung: npx @gltf-transform/cli validate model.glb für jede neue oder geänderte Datei; gemeldete Fehler beheben, bevor Loader-Code debuggt wird.
  2. Build: npm run build (oder npx tsc --noEmit) läuft durch.
  3. Laufzeitprobe: scene und den Mixer auf window verfügbar machen (Object.assign(window, { scene, mixer })). Diesen Ausdruck als String an Playwrights page.evaluate übergeben, damit er in der Seite und nicht in Node ausgeführt wird (das Smoke-Skript in threejs-scene-setup funktioniert), oder den Benutzer bitten, ihn mit await davor in die Browserkonsole einzufügen und die Ausgabe zu melden:
(async () => {
  const before = window.mixer?.time ?? null;
  await new Promise((r) => setTimeout(r, 500));
  const meshes = [];
  window.scene.traverse((o) => { if (o.isMesh) meshes.push(o.name || o.type); });
  return { meshes: meshes.length, mixerAdvanced: before !== null && window.mixer.time > before };
})();

Eine Mesh-Anzahl ungleich null und mixerAdvanced: true erwarten, dann einen Screenshot auf Maßstab und Ausrichtung überprüfen.

Fallstricke

  • Modell lädt, aber nichts wird angezeigt → PBR-Materialien ohne Licht oder Umgebung (siehe threejs-materials-lighting), oder der Maßstab ist um den Faktor 100 falsch (ein Zentimeter-Export). Die Bounding Box aus Muster 1 protokollieren.
  • gltf ist außerhalb des Callbacks undefiniert → load ist asynchron. loadAsync verwenden oder gemeinsame Referenzen innerhalb des Callbacks zuweisen.
  • Animation bewegt sich nie → mixer.update wird nicht jedes Bild aufgerufen, erhält Millisekunden oder play() wurde nie aufgerufen.
  • 404 für draco_*- oder basis_*-Dateien oder ein Dekodierungsfehler → Die Decoder-Dateien werden nicht ausgeliefert oder stammen aus einer anderen three.js-Version. Die Kopien aus dem installierten three ausliefern und den Loader darauf verweisen.
  • setKTX2Loader must be called before loading KTX2 textures oder setMeshoptDecoder must be called before loading compressed files → Die Datei verwendet KHR_texture_basisu oder Meshopt-Komprimierung; den Decoder anhängen (Muster 4).
  • .hasFeature() called before the backend is initialized → KTX2Loader.detectSupport wurde auf einem WebGPURenderer ausgeführt, bevor await renderer.init() abgeschlossen war.
  • Das gleiche Modell zweimal hinzufügen verschiebt es → Ein Object3D hat einen Elternteil. Klonen verwenden, und für geskinehte Meshes SkeletonUtils.clone (siehe Referenz).
  • Klone animieren gemeinsam oder nur einer bewegt sich → Ein einfaches .clone() teilt sich das Skelett; SkeletonUtils.clone und einen separaten Mixer pro Klon verwenden.
  • Benannte Teile verschwinden nach gltf-transform optimize → Die Standardeinstellungen zum Abflachen und Verbinden haben sie zusammengeführt. Mit --flatten false --join-named false erneut ausführen.
  • Gebackene Offsets bekämpfen die Laufzeitsteuerung → Exporteure können Maßstab oder Rotation in Kindknoten einbrennen. Zuerst Namen und lokale Transformationen ausgeben; ein Teil unter einem frischen Object3D für einen sauberen Drehpunkt neu anordnen oder einen Neuexport mit angewendeten Transformationen anfordern.

Referenzen

  • references/loaders-and-animation.md lesen für eine LoadingManager-Fortschrittsanzeige für viele Loader, das Erzeugen vieler animierter Gegner mit SkeletonUtils.clone, Details zu AnimationAction-Schleifen und -Überblendungen, Hinweise zum Hosten von Decodern und Checklisten für den Export zur Weitergabe an einen Künstler.

Verwandte Fähigkeiten

  • threejs-scene-setup: Renderer, Kamera und Schleife.
  • threejs-materials-lighting: Beleuchtung und Umgebung, damit PBR-Modelle richtig aussehen.
  • create-game-assets: Briefing, Beschaffung und Prüfung der 3D-Assets selbst.
  • fps-shooter: Ein 3D-Genre, das auf diesen Fähigkeiten aufbaut.

Versionshinweise

Zuletzt geprüft: 2026-11-11 gegen three r187 (npm [email protected], veröffentlicht 2026-10-30) und @gltf-transform/cli 4.5.1.

  • r185: DRACOLoader und KTX2Loader verwenden standardmäßig ihre gebündelten Decoder-Ordner; DRACO_GLTF_CONFIG hinzugefügt; DRACOLoader.setDecoderConfig() veraltet (Entfernung für r194 geplant). r183: KHR_meshopt_compression wird zusätzlich zu EXT_meshopt_compression unterstützt. r181: KTX2Loader.detectSupportAsync() veraltet.
  • gltf-transform 4.5.1 optimize-Standardeinstellungen: --compress meshopt, --flatten true, --join true, --join-named true, --simplify true, --texture-compress auto. --texture-compress ktx2 benötigt den ktx-Befehl aus KTX-Software 4.4.0 oder neuer im PATH.
  • Quellen: r187 Versionshinweise, r187 DRACOLoader.js, r187 GLTFLoader.js, glTF Transform CLI, npx @gltf-transform/cli optimize --help.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills