Load and display a compressed glTF (.glb) file (using Threejs).

この記事は約10分で読めます。

スポンサーリンク

Things I want to do

Load the compressed glTF (.glb) file into Threejs.

The compression method is below ↓

保存するglTF(.glb)ファイルのファイルサイズを小さくする(Blender)
やりたいこと下の記事で紹介した通り、BlenderでglTF(.glb)ファイルを保存することができますが、形状が複雑になればファイルサイズは大きくなりWEBで読み込む際などにロード時間が遅くなります。ここでは保存されるg...
スポンサーリンク

Environment

Threejs: r150

Chrome: 111.0.5563.65

スポンサーリンク

Prepare

For instructions on preparing the uncompressed source and environment, please refer to the article below.

スポンサーリンク

Loading using DRACOLoader

Folder structure

The folder structure is as follows:

dice-c.glb is the compressed glTF file to be read.

The DRACOLoader.js file and the draco folder have been added. Both are files included with ThreeJS.

ROOT
| dice-c.glb
| index.html
|
\---js
+---libs
| | 3d.js
| | DRACOLoader.js /// Added to the original file (three.js\examples\jsm\loaders\DRACOLoader.js)
| | GLTFLoader.js //Original file (three.js\examples\jsm\loaders\GLTFLoader.js)
| | scan.module.js //Original file (three.js\build\three.module.js)
| |
| \---draco ///Added Original file (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 // Original file (three.js\examples\jsm\utils\BufferGeometryUtils.js)

HTML

The index.html file for the folder structure should be written as follows:

There are no changes from last time.

<!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

The contents of 3d.js are as follows:

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();
///Add start
	const dracoLoader = new DRACOLoader();
	dracoLoader.setDecoderPath('./js/libs/draco/');
	loader.setDRACOLoader(dracoLoader);

///add end

	loader.load(path, function (gltf) {
		let box = gltf.scene;
		scene.add(box);
		requestAnimationFrame(render);
	}, undefined, function (e) {
		console.error(e);
	});
}

The process for reading a compressed .glb file is as follows. Other parts are the same as before.

import { DRACOLoader } from './DRACOLoader.js';

Import a Loader to read compressed .glb files.

	const dracoLoader = new DRACOLoader();
	dracoLoader.setDecoderPath('./js/libs/draco/');
	loader.setDRACOLoader(dracoLoader);

Create a DRACOLoader and set it to GLTFLoader.

The path specified in setDecoderPath is the path from the HTML file to the draco folder.

Result

I was able to load and display the compressed dice-c.glb file.

Error message

If you load a glTF file that has been compressed without proper handling, the following error will be logged:

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

If the argument for dracoLoader.setDecoderPath( ./js/libs/draco/ ); is incorrect, the following error will be logged.

xxxxxxxxxxxxxxxxxx will vary depending on the environment.

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 ()
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
スポンサーリンク

Websites I used as references

Three.js – JavaScript 3D Library
スポンサーリンク

Related pages

A summary of how to load and display 3D objects created in Blender using Threejs.

コメント

タイトルとURLをコピーしました