やりたいこと
ThreejsやMicrosoftが推奨されているglTF(.glb)ファイルをThreejsを簡単に読み込みたい。
環境
Threejs: r150
Chrome: 111.0.5563.65
準備
モジュールを読み込めるようにする
TypeがモジュールのJavaScriptを使用します。ローカルで使用する場合はChromeを特別な起動方法で起動する必要があります。通常のChromeはTypeがモジュールのJavaScriptを読み込むことができません。
Chromeを起動時に以下の引数を追加します。
--allow-file-access-from-files
Chromeのショートカットを作成してのリンク先の最後に上記の引数を追加するか、batを作成すると便利です。
上記方法でChromeを起動する際、すべてのChromeのWindowを閉じている必要があります。
glTFファイルの作成方法
GLTFLoaderを用いた読み込み
フォルダ構成
フォルダ構成は以下の通りです。
dice.glbが読み込み対象のファイルです。
GLTFLoader.js、three.module.js、BufferGeometryUtils.jsはThreejsに含まれるファイルです。
ROOT | dice.glb | index.html | \---js +---libs | 3d.js | GLTFLoader.js //元ファイル (three.js\examples\jsm\loaders¥GLTFLoader.js) | three.module.js //元ファイル (three.js\build\three.module.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>
以下行ごとの説明です。
<canvas id="canvas1" width=600 height=600></canvas>
3Dを表示するCanvasです。JavaScriptから使用するのでIDを設定します。
<script type="importmap">{"imports": {"three": "./js/libs/three.module.js"}}</script>
three.module.jsの場所を指定します。
これを設定せずにだいぶ悩みました。
<script type="module" src="./js/libs/3d.js"></script>
読み込み処理を含むJavaScriptを読み込みます。
今の最新版ではglbファイルを読み込むGLTFLoaderはmodule版しか含まれていないようです。ほかのサイトでは非モジュール版の情報が掲載されていることがあり正しく動作しないことがあります。
JavaScript
import * as THREE from 'three';
import { GLTFLoader } from './GLTFLoader.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.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();
loader.load(path, function(gltf) {
let box = gltf.scene;
scene.add(box);
requestAnimationFrame(render);
}, undefined, function(e) {
console.error(e);
});
}
.glbファイルを読み込むための処理は以下の通りです。ほかの処理は一般的なThreejsの画像表示処理です。
import { GLTFLoader } from './GLTFLoader.js';
.glbファイルを読み込むためのLoaderをインポートします。
function loadObjects(scene, path) {
const loader = new GLTFLoader();
loader.load(path, function(gltf) {
let box = gltf.scene;
scene.add(box);
requestAnimationFrame(render);
}, undefined, function(e) {
console.error(e);
});
}
pathには読み込む.glbファイルのパスを設定します。相対パスを設定する場合、htmlからの相対パスを設定します。
loader.loadの第二引数の関数は読み込み完了時に呼ばれます。ここでは読み込み結果のgltfのgltf.sceneをsceneにadd()で追加しています。追加後にrequestAnimationFrame()でレンダリングを要求し画面に表示を行います。
gltf.sceneはThreejsのsceneではなくgroupです。直接レンダリングできません。
結果
dice.glbを読み込んで表示することができました。
コメント