Three.js에 gltfpack 모델 로드
최적화된 GLB에는 GLTFLoader보다 더 많은 것이 필요할 수 있습니다. 이 가이드에서는 이 도구의 Meshopt 및 KTX2 출력에 대한 로더 설정을 다룹니다. 압축 설정은 선택하지 않습니다. 결과 패널을 사용하여 내보낸 파일에 필요한 확장자를 확인하세요.
일치하는 종속성 설치
기존 Vite 애플리케이션과 같은 ES 모듈 번들러가 있는 npm 프로젝트에서 이 예제를 사용하세요. 아래 버전은 이 사이트의 뷰어와 일치합니다. Bare Import는 단순히 브라우저에서 JavaScript 파일을 여는 것만으로는 작동하지 않습니다.
npm install [email protected] [email protected]
설치된 Three.js 패키지의 Basis 트랜스코더 파일을 공용 디렉터리에 복사합니다. 사이트 루트에서 제공되는 기존 공용 디렉토리를 사용하면 아래 파일을 /basis/에서 사용할 수 있습니다. KTX2Loader와 동일한 Three.js 버전에서 유지하세요.
node -e "require('fs').cpSync('node_modules/three/examples/jsm/libs/basis', 'public/basis', {recursive:true})"
로딩하기 전에 디코더를 연결하세요
public/models/optimized.glb에 최적화된 파일을 넣고 id 모델로 캔버스를 생성합니다. 다음을 애플리케이션 입력 모듈로 사용하세요. 로드된 경계에 카메라를 맞추고 존재하는 경우 첫 번째 애니메이션을 재생합니다.
<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);
}
확장 프로그램 및 실패한 요청을 확인하세요.
| 징후 | 확인하다 |
|---|---|
| Meshopt 디코더 오류 | loadAsync 이전에 setMeshoptDecoder를 호출하고 meshoptimizer 패키지를 번들에 유지합니다. |
| KTX2 텍스처가 로드되지 않습니다. | GLTFLoader에 KTX2Loader를 설정하고 렌더러로 detectSupport를 호출한 후 트랜스코더 URL을 확인합니다. |
| 모델 또는 WASM 파일 대신 HTML이 반환됨 | 누락된 파일이 지원서 페이지로 전달될 수 있습니다. HTTP 상태, 응답 내용, 배포 기본 경로를 확인하세요. |
콘텐츠 보안 정책이 엄격한 사이트에서는 차단된 웹 워커나 WebAssembly를 콘솔에서 확인해보세요. 애플리케이션의 작업자와 WASM 전달을 의도적으로 구성하십시오. 단지 오류를 숨기기 위해 정책을 제거하지 마십시오. 성공적인 네트워크 응답만으로는 디코딩이 성공했음을 확인할 수 없습니다.
이 예제에서는 두 디코더를 모두 설치하여 두 출력 중 하나를 로드할 수 있습니다. PNG 또는 JPEG 텍스처를 유지하는 파일에는 KTX2Loader가 필요하지 않습니다. WebP는 브라우저 및 로더 지원이 필요하지만 Basis 트랜스코더를 사용하지 않습니다. 모델 변경이 반복되는 애플리케이션에서는 오래된 형상, 재료 및 텍스처를 폐기합니다. 더 이상 필요하지 않으면 KTX2 로더를 해제하십시오.
Three.js GLTFLoader · Three.js KTX2Loader
엔진 참조: gltfpack
옵티마이저 열기 ↗