gltfpack モデルを Three.js にロードします
最適化された GLB には、GLTFLoader だけではなく多くのものが必要になる場合があります。このガイドでは、このツールの Meshopt および KTX2 出力のローダー設定について説明します。圧縮設定は選択しません。結果パネルを使用して、エクスポートされたファイルに必要な拡張子を確認します。
一致する依存関係をインストールする
この例は、既存の Vite アプリケーションなどの ES モジュール バンドラーを含む npm プロジェクトで使用します。以下のバージョンは、このサイトのビューアと一致します。単純なインポートは、ブラウザで 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 テクスチャがロードされない | KTX2Loader を GLTFLoader に設定し、レンダラで detectSupport を呼び出し、トランスコーダ URL を確認します。 |
| モデルまたは WASM ファイルの代わりに HTML が返されました | 不足しているファイルがアプリケーション ページに表示される可能性があります。 HTTP ステータス、応答内容、展開ベース パスを確認します。 |
厳格なコンテンツ セキュリティ ポリシーが適用されているサイトでは、コンソールでブロックされた Web ワーカーまたは WebAssembly を確認してください。アプリケーションのワーカーと WASM 配信を意図的に構成します。エラーを隠すためだけにポリシーを削除しないでください。ネットワーク応答が成功しただけでは、デコードが成功したことは確認されません。
この例では、どちらの出力も読み込めるように両方のデコーダーをインストールします。 PNG または JPEG テクスチャを保持するファイルには KTX2Loader は必要ありません。 WebP はブラウザとローダーのサポートを必要としますが、Basis トランスコーダーは使用しません。モデル変更を繰り返すアプリケーションでは、古いジオメトリ、マテリアル、テクスチャを破棄します。 KTX2 ローダーが必要なくなったら解放してください。
Three.js GLTFLoader · Three.js KTX2Loader
エンジンリファレンス: gltfpack
オプティマイザを開きます ↗