Carregar modelos gltfpack em Three.js

Um GLB otimizado pode precisar de mais do que apenas GLTFLoader. Este guia cobre a configuração do carregador para as saídas Meshopt e KTX2 desta ferramenta. Não escolhe configurações de compactação; use o painel de resultados para ver quais extensões seu arquivo exportado requer.

Instale dependências correspondentes

Use este exemplo em um projeto npm com um empacotador de módulo ES, como um aplicativo Vite existente. As versões abaixo correspondem ao visualizador deste site. As importações simples não funcionam simplesmente abrindo o arquivo JavaScript em um navegador.

npm install [email protected] [email protected]

Copie os arquivos do transcodificador Basis do pacote Three.js instalado em seu diretório público. Com um diretório público convencional servido na raiz do site, os arquivos abaixo estarão disponíveis em /basis/. Mantenha-os da mesma versão Three.js que 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 uma tela com modelo de id. Use o seguinte como módulo de entrada do aplicativo. Ele ajusta a câmera aos limites carregados e reproduz a primeira animação quando presente.

<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);
}

Verifique a extensão e a solicitação com falha

SintomaVerificar
Erro do decodificador MeshoptChame setMeshoptDecoder antes de loadAsync e mantenha o pacote meshoptimizer no pacote configurável.
Texturas KTX2 não carregamDefina KTX2Loader em GLTFLoader, chame detectSupport com o renderizador e verifique o URL do transcodificador.
HTML retornado em vez de um modelo ou arquivo WASMUm arquivo ausente pode estar caindo na página do seu aplicativo. Verifique o status HTTP, o conteúdo da resposta e os caminhos básicos de implantação.

Em um site com uma política de segurança de conteúdo rígida, verifique se há Web Workers bloqueados ou WebAssembly no console. Configure deliberadamente o trabalhador do seu aplicativo e a entrega WASM; não remova a política apenas para ocultar um erro. Uma resposta de rede bem-sucedida por si só não confirma o sucesso da decodificação.

O exemplo instala ambos os decodificadores para que possa carregar qualquer uma das saídas. Arquivos que mantêm texturas PNG ou JPEG não precisam de KTX2Loader. WebP precisa de suporte de navegador e carregador, mas não usa o transcodificador Basis. Em uma aplicação com repetidas alterações de modelo, descarte geometrias, materiais e texturas antigas; libere o carregador KTX2 quando ele não for mais necessário.

Three.js GLTFLoader · Three.js KTX2Loader

Verifique outros requisitos de compatibilidade de saída →

Referência do motor: gltfpack

Abra o otimizador ↗