Three.jsでオブジェクトにテクスチャ(画像)を張り付ける方法を試してみます。
サンプルコード
まずは平面のオブジェクトを追加してみます。
import * as THREE from 'three'; // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // オブジェクトの作成 const geometry = new THREE.PlaneGeometry(16, 9); const material = new THREE.MeshBasicMaterial({ color: "orange" }); const object = new THREE.Mesh(geometry, material); scene.add(object); function animate() { renderer.render(scene, camera); } renderer.setAnimationLoop(animate);
この時点ではオレンジ色の平面が映っているのみです。
設定前のデモページ
次にテクスチャの設定を追加してみます。
srcディレクトリ内にtexturesフォルダを作成して、img.jpgを格納します。
コードを以下のように変更します。
import * as THREE from 'three'; import imgUrl from './textures/img.jpg' // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // オブジェクトの作成 const geometry = new THREE.PlaneGeometry(16, 9); const texture = new THREE.TextureLoader().load(imgUrl); const material = new THREE.MeshBasicMaterial({ map: texture }); const object = new THREE.Mesh(geometry, material); scene.add(object); function animate() { renderer.render(scene, camera); } renderer.setAnimationLoop(animate);
テクスチャはTextureLoader()でファイルを読み込んで、マテリアルで設定しています。
テクスチャを設定するデモページ
注意点として、以下のような記述だとテクスチャは表示されないようでした。
import * as THREE from 'three'; import imgUrl from './textures/img.jpg' // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // オブジェクトの作成 const geometry = new THREE.PlaneGeometry(16, 9); const texture = new THREE.TextureLoader().load(imgUrl); const material = new THREE.MeshBasicMaterial({ map: texture }); const object = new THREE.Mesh(geometry, material); scene.add(object); renderer.render(scene, camera);
テクスチャが反映されないデモページ
ひとつ前の例ではsetAnimationLoop()で繰り返しレンダリングの更新を行っているのに対して、この例では末尾に一回だけレンダリングの処理を行っているのですが、テクスチャの読み込みが非同期のため、読み込み完了前にレンダリングを行っていて表示されないようでした。
対応方法として、テクスチャロード後のコールバック関数を設定できるようなので、試してみます。
import * as THREE from 'three'; import imgUrl from './textures/img.jpg' // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // オブジェクトの作成 const geometry = new THREE.PlaneGeometry(16, 9); const loader = new THREE.TextureLoader() // テクスチャの読み込み完了後 loader.load(imgUrl, (texture) => { const material = new THREE.MeshBasicMaterial({ map: texture }); const object = new THREE.Mesh(geometry, material); scene.add(object); renderer.render(scene, camera); });
テクスチャのロード後にレンダリングすることで、表示されるようになりました。
テクスチャのコールバック関数設定のデモページ
コメントが承認されるまで時間がかかります。