こちらの記事で、Blenderで作ったglbファイルを読み込んで表示しました。
読み込んだモデルを一度しか使わないのであれば、これで問題ないのですが、同じモデルを何個も配置するときはどうしたものかと考えた結果、cloneをつかって複製することにしてみました。
DEMO
こちらのDEMOのカラフルなキューブは、わざわざBlenderで作っているのですが、
・loaderで1回読み込む
・cloneで複製
という形を取って4つに増やしています。
JavaScript
import * as THREE from './build/three.module.js'; import { OrbitControls } from './lib/jsm/controls/OrbitControls.js'; import { GLTFLoader } from './lib/jsm/loaders/GLTFLoader.js'; init(); async function init() { const canvas = document.createElement('canvas'); document.body.appendChild(canvas); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true }); const scene = new THREE.Scene(); const width = window.innerWidth; const height = window.innerHeight; renderer.setPixelRatio(1); renderer.setSize(width, height); const camera = new THREE.PerspectiveCamera(45, width / height, 1, 100); camera.position.set(0, 1, 10); const controls = new OrbitControls(camera, renderer.domElement); const light = new THREE.AmbientLight(0xFFFFFF, 1.0); scene.add(light); const loader = new GLTFLoader(); const url = './cube.glb'; const colors = [{ r: 1, g: 1, b: 1 },{ r: 1, g: 0, b: 0 },{ r: 0, g: 1, b: 0 },{ r: 0, g: 0, b: 1 },]; const models = []; const model = await (() => { return new Promise((resolve) => { loader.load( url, (gltf) => { resolve(gltf.scene); }, (err) => { console.error(err); } ); }); })(); for (let i = 0; i < colors.length; ++i) { models.push(model.clone()); // モデルを複製 models[i].traverse((object) => { if (object.isMesh) { object.material = object.material.clone(); // 同一のマテリアルを参照しているようなので複製したものを代入 object.material.color.r = colors[i].r; object.material.color.g = colors[i].g; object.material.color.b = colors[i].b; } }); models[i].position.set( i * 2 % colors.length, 0, (0 | i / colors.length * 2) * 2 ); scene.add(models[i]); } renderer.setAnimationLoop(tick); function tick() { controls.update(); if (model) { scene.rotation.y += .01; } renderer.render(scene, camera); } }