Laden Sie gltfpack-Modelle in Three.js
Ein optimierter GLB kann mehr als GLTFLoader allein benötigen. In dieser Anleitung wird das Loader-Setup für die Meshopt- und KTX2-Ausgabe dieses Tools beschrieben. Es werden keine Komprimierungseinstellungen ausgewählt. Verwenden Sie das Ergebnisfenster, um zu sehen, welche Erweiterungen Ihre exportierte Datei erfordert.
Installieren Sie passende Abhängigkeiten
Verwenden Sie dieses Beispiel in einem npm-Projekt mit einem ES-Modul-Bundler, beispielsweise einer vorhandenen Vite-Anwendung. Die folgenden Versionen entsprechen dem Viewer dieser Website. Bloße Importe funktionieren nicht durch einfaches Öffnen der JavaScript-Datei in einem Browser.
npm install [email protected] [email protected]
Kopieren Sie die Basis-Transcoder-Dateien aus dem installierten Three.js-Paket in Ihr öffentliches Verzeichnis. Mit einem herkömmlichen öffentlichen Verzeichnis im Stammverzeichnis der Site sind die folgenden Dateien unter /basis/ verfügbar. Behalten Sie sie aus der gleichen Three.js-Version wie KTX2Loader.
node -e "require('fs').cpSync('node_modules/three/examples/jsm/libs/basis', 'public/basis', {recursive:true})"
Schließen Sie die Decoder vor dem Laden an
Legen Sie die optimierte Datei unter public/models/optimized.glb ab und erstellen Sie eine Leinwand mit ID-Modell. Verwenden Sie Folgendes als Bewerbungseinstiegsmodul. Es passt die Kamera an die geladenen Grenzen an und spielt die erste Animation ab, sofern vorhanden.
<canvas id="model"></canvas>
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
import { MeshoptDecoder } from 'meshoptimizer';
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#model'), antialias: true,
});
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);
scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 3));
const light = new THREE.DirectionalLight(0xffffff, 3);
light.position.set(3, 5, 4);
scene.add(light);
const camera = new THREE.PerspectiveCamera(45, 1, 0.01, 1000);
const ktx2 = new KTX2Loader()
.setTranscoderPath('/basis/')
.detectSupport(renderer);
const loader = new GLTFLoader()
.setMeshoptDecoder(MeshoptDecoder)
.setKTX2Loader(ktx2);
function resize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
window.addEventListener('resize', resize);
resize();
try {
await MeshoptDecoder.ready;
const gltf = await loader.loadAsync('/models/optimized.glb');
scene.add(gltf.scene);
const bounds = new THREE.Box3().setFromObject(gltf.scene);
const center = bounds.getCenter(new THREE.Vector3());
const radius = Math.max(bounds.getBoundingSphere(new THREE.Sphere()).radius, 0.01);
const verticalFov = THREE.MathUtils.degToRad(camera.fov);
const horizontalFov = 2 * Math.atan(Math.tan(verticalFov / 2) * camera.aspect);
const distance = 1.2 * radius / Math.sin(Math.min(verticalFov, horizontalFov) / 2);
camera.position.copy(center).add(new THREE.Vector3(1, 0.6, 1).normalize().multiplyScalar(distance));
camera.near = radius / 100;
camera.far = distance + radius * 10;
camera.lookAt(center);
camera.updateProjectionMatrix();
const mixer = new THREE.AnimationMixer(gltf.scene);
if (gltf.animations.length) mixer.clipAction(gltf.animations[0]).play();
const clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
mixer.update(Math.min(clock.getDelta(), 0.1));
renderer.render(scene, camera);
});
} catch (error) {
console.error('Model loading failed:', error);
const message = document.createElement('p');
message.textContent = 'Model loading failed. Check the browser console and network requests.';
document.body.prepend(message);
}
Überprüfen Sie die Erweiterung und die fehlgeschlagene Anfrage
| Symptom | Überprüfen |
|---|---|
| Meshopt Decoderfehler | Rufen Sie setMeshoptDecoder vor loadAsync auf und behalten Sie das Paket meshoptimizer im Bundle. |
| KTX2-Texturen werden nicht geladen | Setzen Sie KTX2Loader auf GLTFLoader, rufen Sie detectSupport mit dem Renderer auf und überprüfen Sie die Transcoder-URL. |
| Anstelle einer Modell- oder WASM-Datei wurde HTML zurückgegeben | Möglicherweise gelangt eine fehlende Datei auf Ihre Bewerbungsseite. Überprüfen Sie den HTTP-Status, den Antwortinhalt und die Bereitstellungsbasispfade. |
Überprüfen Sie auf einer Site mit einer strengen Inhaltssicherheitsrichtlinie die Konsole auf blockierte Web Worker oder WebAssembly. Konfigurieren Sie den Worker und die WASM-Bereitstellung Ihrer Anwendung bewusst. Entfernen Sie die Richtlinie nicht, nur um einen Fehler zu verbergen. Eine erfolgreiche Netzwerkantwort allein bestätigt nicht, dass die Dekodierung erfolgreich war.
Das Beispiel installiert beide Decoder, sodass beide Ausgaben geladen werden können. Dateien, die die Texturen PNG oder JPEG behalten, benötigen kein KTX2Loader. WebP benötigt Browser- und Loader-Unterstützung, verwendet jedoch nicht den Basis-Transcoder. Entsorgen Sie bei einer Anwendung mit wiederholten Modelländerungen alte Geometrien, Materialien und Texturen. Geben Sie den KTX2-Loader frei, wenn er nicht mehr benötigt wird.
Three.js GLTFLoader · Three.js KTX2Loader
Überprüfen Sie andere Anforderungen an die Ausgabekompatibilität →
Motorreferenz: gltfpack
Öffnen Sie den Optimierer ↗