Załaduj modele gltfpack do Three.js
Zoptymalizowany GLB może potrzebować więcej niż sam GLTFLoader. W tym przewodniku opisano konfigurację modułu ładującego dla danych wyjściowych Meshopt i KTX2 tego narzędzia. Nie wybiera ustawień kompresji; użyj panelu wyników, aby sprawdzić, jakich rozszerzeń wymaga eksportowany plik.
Zainstaluj pasujące zależności
Użyj tego przykładu w projekcie npm z pakietem modułu ES, takim jak istniejąca aplikacja Vite. Poniższe wersje odpowiadają przeglądarce tej witryny. Sam import nie działa po prostu przez otwarcie pliku JavaScript w przeglądarce.
npm install [email protected] [email protected]
Skopiuj pliki transkodera Basis z zainstalowanego pakietu Three.js do katalogu publicznego. W przypadku konwencjonalnego katalogu publicznego udostępnianego w katalogu głównym witryny poniższe pliki będą dostępne pod nazwą /basis/. Zachowaj je z tej samej wersji Three.js co KTX2Loader.
node -e "require('fs').cpSync('node_modules/three/examples/jsm/libs/basis', 'public/basis', {recursive:true})"
Podłącz dekodery przed załadowaniem
Umieść zoptymalizowany plik pod adresem public/models/optimized.glb i utwórz płótno o identyfikatorze modelu. Użyj poniższego jako modułu wprowadzania aplikacji. Dopasowuje kamerę do załadowanych granic i odtwarza pierwszą animację, jeśli jest obecna.
<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);
}
Sprawdź rozszerzenie i nieudane żądanie
| Objaw | Sprawdzać |
|---|---|
| Błąd dekodera Meshopt | Wywołaj setMeshoptDecoder przed loadAsync i zachowaj pakiet meshoptimizer w pakiecie. |
| Tekstury KTX2 nie ładują się | Ustaw KTX2Loader na GLTFLoader, wywołaj detectSupport z modułem renderującym i sprawdź adres URL transkodera. |
| Zamiast modelu lub pliku WASM zwrócony został kod HTML | Brakujący plik może przedostawać się na stronę aplikacji. Sprawdź stan HTTP, treść odpowiedzi i podstawowe ścieżki wdrożenia. |
W witrynie ze ścisłą Polityką bezpieczeństwa treści sprawdź konsolę pod kątem zablokowanych procesów roboczych lub WebAssembly. Skonfiguruj celowo proces roboczy aplikacji i dostarczanie WASM; nie usuwaj polityki tylko po to, aby ukryć błąd. Sama pomyślna odpowiedź sieci nie potwierdza, że dekodowanie powiodło się.
W przykładzie instalowane są oba dekodery, dzięki czemu można załadować dowolne wyjście. Pliki zachowujące tekstury PNG lub JPEG nie potrzebują KTX2Loader. WebP wymaga obsługi przeglądarki i modułu ładującego, ale nie korzysta z transkodera Basis. W aplikacji, w której występują częste zmiany modelu, usuń starą geometrię, materiały i tekstury; zwolnij moduł ładujący KTX2, gdy nie jest już potrzebny.
Three.js GLTFLoader · Three.js KTX2Loader
Sprawdź inne wymagania dotyczące zgodności wyjściowej →
Odniesienie do silnika: gltfpack
Otwórz optymalizator ↗