やりたいこと
圧縮されたglTF(.glb)ファイルをThreejsを読み込む。
圧縮方法は↓
保存するglTF(.glb)ファイルのファイルサイズを小さくする(Blender)
やりたいこと下の記事で紹介した通り、BlenderでglTF(.glb)ファイルを保存することができますが、形状が複雑になればファイルサイズは大きくなりWEBで読み込む際などにロード時間が遅くなります。ここでは保存されるg...
環境
Threejs: r150
Chrome: 111.0.5563.65
準備
圧縮なしのソースおよび環境の準備は↓の記事を参考にしてください。
DRACOLoaderを用いた読み込み
フォルダ構成
フォルダ構成は以下の通りです。
dice‐c.glbが読み込み対象の圧縮されたglTFファイルです。
DRACOLoader.jsファイル、dracoフォルダを追加しています。ともにThreejsに含まれるファイルです。
ROOT | dice-c.glb | index.html | \---js +---libs | | 3d.js | | DRACOLoader.js ///追加 元ファイル (three.js\examples\jsm\loaders¥DRACOLoader.js) | | GLTFLoader.js //元ファイル (three.js\examples\jsm\loaders¥GLTFLoader.js) | | three.module.js //元ファイル (three.js\build\three.module.js) | | | \---draco ///追加 元ファイル (threejs\three.js\examples\jsm\libs\draco) | | draco_decoder.js | | draco_decoder.wasm | | draco_encoder.js | | draco_wasm_wrapper.js | | README.md | | | \---gltf | draco_decoder.js | draco_decoder.wasm | draco_encoder.js | draco_wasm_wrapper.js | \---utils BufferGeometryUtils.js //元ファイル (three.js\examples\jsm\utils¥BufferGeometryUtils.js)
HTML
フォルダ構成のindex.htmlは以下のように記述します。
前回から変更はありません。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas1" width=600 height=600></canvas>
<script type="importmap">{"imports": {"three": "./js/libs/three.module.js"}}</script>
<script type="module" src="./js/libs/3d.js"></script>
</body>
</html>
JavaScript
3d.jsの中身は以下の通りです。
import * as THREE from 'three';
import { GLTFLoader } from './GLTFLoader.js';
import { DRACOLoader } from './DRACOLoader.js'; ///追加
let renderer;
let scene;
let camera;
scene = new THREE.Scene();
const canvas = document.querySelector("#canvas1");
renderer = new THREE.WebGLRenderer({ canvas: canvas });
const width = canvas.width;
const height = canvas.height;
renderer.setSize(width, height);
setupCamera();
loadObjects(scene, "./dice-c.glb");
setupLights(scene);
function setupCamera() {
const canvas = document.querySelector("#canvas1");
const width = canvas.width;
const height = canvas.height;
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 3000);
camera.position.set(4, 4, 4);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
function render() {
renderer.render(scene, camera);
}
function setupLights(scene) {
let ambientLight = new THREE.AmbientLight(0xffffff);
ambientLight.intensity = 1;
scene.add(ambientLight);
}
function loadObjects(scene, path) {
const loader = new GLTFLoader();
///ここから追加
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('./js/libs/draco/');
loader.setDRACOLoader(dracoLoader);
///ここまで追加
loader.load(path, function (gltf) {
let box = gltf.scene;
scene.add(box);
requestAnimationFrame(render);
}, undefined, function (e) {
console.error(e);
});
}
圧縮された.glbファイルを読み込むための処理は以下の通りです。ほかの個所は前回と同様です。
import { DRACOLoader } from './DRACOLoader.js';
圧縮された.glbファイルを読み込むためのLoaderをインポートします。
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('./js/libs/draco/');
loader.setDRACOLoader(dracoLoader);
DRACOLoaderを作成してGLTFLoaderにセットします。
setDecoderPathで指定するパスはdracoフォルダへのhtmlからのパスです。
結果
圧縮されたdice-c.glbを読み込んで表示することができました。
エラーメッセージ
対応せずに圧縮されたglTFファイルをロードすると以下のエラーがログされます。
3d.js:47 Error: THREE.GLTFLoader: No DRACOLoader instance provided. at new GLTFDracoMeshCompressionExtension (GLTFLoader.js:1730:10) at GLTFLoader.parse (GLTFLoader.js:380:37) at Object.onLoad (GLTFLoader.js:218:11) at three.module.js:40715:38
dracoLoader.setDecoderPath(‘./js/libs/draco/’);の引数が間違えていると以下のエラーがログされます。
xxxxxxxxxxxxxxは環境により異なります。
three.module.js:40577 GET file:///xxxxxxxxxxxxxx/js/libs/draco/draco_wasm_wrapper.js net::ERR_FILE_NOT_FOUND three.module.js:40577 GET file:///xxxxxxxxxxxxxx/js/libs/draco/draco_decoder.wasm net::ERR_FILE_NOT_FOUND 3three.module.js:40577 Uncaught (in promise) TypeError: Failed to fetch at FileLoader.load (three.module.js:40577:3) at DRACOLoader.js:251:11 at new Promise (<anonymous>) at DRACOLoader._loadLibrary (DRACOLoader.js:249:10) at DRACOLoader._initDecoder (DRACOLoader.js:278:32) at DRACOLoader.preload (DRACOLoader.js:259:8) at new GLTFDracoMeshCompressionExtension (GLTFLoader.js:1737:20) at GLTFLoader.parse (GLTFLoader.js:380:37) at Object.onLoad (GLTFLoader.js:218:11) at three.module.js:40715:38
参考にさせていただいたサイト
Three.js – JavaScript 3D Library
コメント