Carregar modelos gltfpack no Three.js
Para carregar os arquivos gerados por esta ferramenta com GLTFLoader, adicione MeshoptDecoder para compressão Meshopt e KTX2Loader para texturas KTX2. Consulte no painel de resultados quais extensões o arquivo exige.
Instale dependências compatíveis
Use este exemplo em um projeto npm com um empacotador de módulos ES, como uma aplicação Vite existente. As versões abaixo correspondem ao visualizador deste site. Imports sem caminho não funcionam simplesmente abrindo o arquivo JavaScript no navegador.
npm install [email protected] [email protected]
Copie os arquivos do transcodificador Basis do pacote Three.js instalado para o diretório público. Em um diretório público convencional servido na raiz do site, os arquivos abaixo ficam disponíveis em /basis/. Use a mesma versão do Three.js que o KTX2Loader.
node -e "require('fs').cpSync('node_modules/three/examples/jsm/libs/basis', 'public/basis', {recursive:true})"
Conecte os decodificadores antes de carregar
Coloque o arquivo otimizado em public/models/optimized.glb e crie um canvas com id model. Use o código a seguir como módulo de entrada da aplicação. Ele ajusta a câmera aos limites do modelo carregado e reproduz a primeira animação, quando houver.
<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);
}
Confira a extensão e a requisição que falhou
| Sintoma | Verificação |
|---|---|
| Erro do decodificador Meshopt | Chame setMeshoptDecoder antes de loadAsync e mantenha o pacote meshoptimizer no bundle. |
| As texturas KTX2 não carregam | Associe KTX2Loader ao GLTFLoader, chame detectSupport com o renderizador e confira a URL do transcodificador. |
| HTML retornado no lugar de um modelo ou arquivo WASM | Um arquivo ausente pode estar sendo redirecionado para a página da aplicação. Confira o status HTTP, o conteúdo da resposta e os caminhos-base da implantação. |
Em sites com Content Security Policy restrita, confira no console se Web Workers ou WebAssembly foram bloqueados. Configure cuidadosamente a entrega de workers e WASM da aplicação; não remova a política apenas para esconder um erro. Uma resposta de rede bem-sucedida, sozinha, não confirma que a decodificação funcionou.
O exemplo instala os dois decodificadores para carregar qualquer uma das saídas. Arquivos que mantêm texturas PNG ou JPEG não precisam de KTX2Loader. WebP requer suporte do navegador e do carregador, mas não usa o transcodificador Basis. Em aplicações que trocam modelos repetidamente, libere geometrias, materiais e texturas antigos; libere o carregador KTX2 quando não for mais necessário.
Three.js GLTFLoader · Three.js KTX2Loader
Confira outros requisitos de compatibilidade da saída →
Referência do mecanismo: gltfpack
Abrir o otimizador ↗