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

オプティマイザを開きます ↗