Charger des modèles gltfpack dans Three.js
Pour charger les fichiers produits par cet outil avec GLTFLoader, ajoutez MeshoptDecoder pour la compression Meshopt et KTX2Loader pour les textures KTX2. Le panneau de résultat indique les extensions requises par votre fichier.
Installer des dépendances compatibles
Utilisez cet exemple dans un projet npm avec un outil de regroupement de modules ES, comme une application Vite existante. Les versions ci-dessous correspondent au visualiseur du site. Les imports sans chemin ne fonctionnent pas en ouvrant simplement le fichier JavaScript dans un navigateur.
npm install [email protected] [email protected]
Copiez les fichiers du transcodeur Basis du paquet Three.js installé vers votre répertoire public. Si ce répertoire est servi à la racine du site, les fichiers ci-dessous seront accessibles sous /basis/. Utilisez la même version de Three.js que pour KTX2Loader.
node -e "require('fs').cpSync('node_modules/three/examples/jsm/libs/basis', 'public/basis', {recursive:true})"
Brancher les décodeurs avant le chargement
Placez le fichier optimisé dans public/models/optimized.glb et créez un canvas avec l'identifiant model. Utilisez le code suivant comme module d'entrée de votre application. Il cadre le modèle chargé et lit sa première animation, s'il en possède une.
<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);
}
Vérifier l'extension et la requête en échec
| Symptôme | Vérification |
|---|---|
| Erreur du décodeur Meshopt | Appelez setMeshoptDecoder avant loadAsync et conservez le paquet meshoptimizer dans le bundle. |
| Les textures KTX2 ne se chargent pas | Associez KTX2Loader à GLTFLoader, appelez detectSupport avec le moteur de rendu et vérifiez l'URL du transcodeur. |
| Du HTML est renvoyé à la place d'un modèle ou d'un fichier WASM | Un fichier absent peut être remplacé par la page de votre application. Vérifiez le statut HTTP, le contenu de la réponse et les chemins de base du déploiement. |
Sur un site doté d'une Content Security Policy stricte, recherchez dans la console les Web Workers ou WebAssembly bloqués. Configurez explicitement leur distribution ; ne supprimez pas la politique pour masquer une erreur. Une réponse réseau réussie ne confirme pas à elle seule le décodage.
L'exemple configure les deux décodeurs pour charger l'un ou l'autre résultat. Les fichiers qui conservent des textures PNG ou JPEG n'ont pas besoin de KTX2Loader. WebP nécessite la prise en charge du navigateur et du chargeur, mais pas le transcodeur Basis. Dans une application où les modèles changent souvent, libérez les anciennes géométries, textures et matériaux ; libérez aussi le chargeur KTX2 lorsqu'il n'est plus utilisé.
Three.js GLTFLoader · Three.js KTX2Loader
Vérifier les autres exigences de compatibilité →
Référence du moteur : gltfpack
Ouvrir l'optimiseur ↗