【Three.js】基本的なセットアップ:ライトやモデルの読み込み等

Three.js

プロジェクトを開いてThree.jsで簡単なオブジェクトを入れたり、ライトやモデル読み込みをするコードのメモ。(※環境構築はやっていません)

Three.jsはSceneの準備のコーディングが結構大変なので、すっ飛ばしたい人向けです。解説もたまについてます。

簡単なセットアップ

まずはnpm install threeでライブラリをインストールする必要があります。

以下はThree.js を使ったシーンの簡単なセットアップコードです。OrbitControlsaxisHelper, gridHelperなども使えるように書いています。

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

const renderer = new THREE.WebGLRenderer();

renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

const orbit = new OrbitControls(camera, renderer.domElement);

const axesHelper = new THREE.AxesHelper(3);
scene.add(axesHelper);

camera.position.set(-10, 30, 30);
orbit.update();

const gridHelper = new THREE.GridHelper(30);
scene.add(gridHelper);

function animate() {
  renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate);

window.addEventListener("resize", function () {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

1. Three.js と OrbitControls のインポート

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
  • THREE は Three.js のライブラリ全体をインポートしています。
  • OrbitControls は、カメラをマウスで操作できるようにするためのモジュールです。

2. レンダラーの設定

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
  • THREE.WebGLRenderer を使ってレンダラーを作成します。これにより、WebGLを利用して3D描画を行います。
  • renderer.setSize() でレンダラーのサイズをウィンドウのサイズに合わせて設定。
  • renderer.domElement を document.body.appendChild() でHTMLに追加し、表示します。

3. シーンとカメラの設定

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  • THREE.Scene は、シーンオブジェクトを作成します。このシーン内に3Dオブジェクトやライトを配置します。
  • THREE.PerspectiveCamera は、視野角が 45 度のカメラを作成します。ウィンドウのアスペクト比に基づいてカメラの描画領域を設定します。

4. OrbitControls の設定

const orbit = new OrbitControls(camera, renderer.domElement);

OrbitControls を使って、マウスでカメラを回転・ズームできるように設定します。

5. 軸のヘルパー(AxesHelper)の追加

const axesHelper = new THREE.AxesHelper(3);
scene.add(axesHelper);

AxesHelper は、シーン内で3D座標軸を表示するためのヘルパーです。これにより、X、Y、Z軸がそれぞれ赤、緑、青で表示されます。

6. カメラ位置の設定

camera.position.set(-10, 30, 30);
orbit.update();
  • camera.position.set() でカメラの位置を設定します。ここでは、x = -10y = 30z = 30 の位置に設定されています。
  • orbit.update() は、カメラが初期位置で適切に動作するように更新します。

7. グリッドのヘルパー(GridHelper)の追加

const gridHelper = new THREE.GridHelper(30);
scene.add(gridHelper);

GridHelper は、グリッド線を表示するためのヘルパーです。グリッドの大きさを 30 に設定しています。

8. アニメーション関数の設定

function animate() {
  renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate);
  • animate() 関数内で renderer.render() を使ってシーンを描画します。この関数は、ブラウザの描画ループで呼ばれ、シーンが描画され続けます。
  • renderer.setAnimationLoop() を使って、animate() 関数がアニメーションループとして呼ばれるようにします。

9. ウィンドウリサイズ時の処理

window.addEventListener("resize", function () {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

resize イベントリスナーを使って、ウィンドウのサイズが変わった際にカメラのアスペクト比を更新し、レンダラーのサイズを調整します。

ライトのセット

three.jsのライトに関して代表的なものを追加します。

  • ambientLight環境光
    これはシーン全体に均等に照らす光で、どの方向にも影響を与えません。全体的な明るさを調整するのに使います。
  • directionalLight平行光源または方向光
    太陽光のように、特定の方向からまっすぐに光を放つ光源です。平行光線でシーンを照らすイメージです。
  • spotLightスポットライト
    特定の地点に集中して照らす光源で、光の範囲や角度を調整できるライトです。舞台の照明など、ピンポイントでの照明に使います。

以下、()内にライトの色や強さが入っていますので調整の必要があります。


const ambientLight = new THREE.AmbientLight(0x333333);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 3);
scene.add(directionalLight);

const spotLight = new THREE.SpotLight(0xffffff, 10000);
scene.add(spotLight);

オブジェクトのセット(box)

このコードは、立方体(ボックス)を作成してシーンに追加するものです。

const boxGeometry = new THREE.BoxGeometry();
const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const box = new THREE.Mesh(boxGeometry, boxMaterial);
scene.add(box);

1. const boxGeometry = new THREE.BoxGeometry();

  • THREE.BoxGeometry は、立方体(ボックス)のジオメトリ(形状)を作成するためのクラスです。このコードでは、引数なしで new THREE.BoxGeometry() として立方体を生成しています。
  • デフォルトでは、立方体のサイズは (width = 1, height = 1, depth = 1) となっています。
    • 幅、 高さ、 奥行きがそれぞれ1の立方体が作成されます。

2. const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

  • THREE.MeshBasicMaterial は、シンプルなマテリアル(材質)を作成するためのクラスです。このマテリアルは、影響を受けずに直接的な色を表示します。ライティングの影響を受けないため、常に同じ明るさで表示されます。
  • { color: 0x00ff00 } は、マテリアルの色を指定しています。このコードでは、色を 緑色 (0x00ff00 は16進数で緑色) に設定しています。

3. const box = new THREE.Mesh(boxGeometry, boxMaterial);

  • THREE.Mesh は、ジオメトリ(形状)とマテリアル(材質)を組み合わせて実際に3Dオブジェクトを作成するためのクラスです。
  • このコードでは、先ほど作成した boxGeometry(立方体の形状)と boxMaterial(緑色のマテリアル)を使って、立方体のメッシュオブジェクトを作成しています。

4. scene.add(box);

  • scene.add() は、作成したオブジェクト(ここでは box)をシーンに追加するためのメソッドです。
  • これにより、box がシーン内で表示されるようになります。

結果

このコードは、緑色の立方体を作成し、それをシーンに追加します。シーンに追加された立方体は、カメラやレンダラーが描画する対象となります。

つまり、これを実行すると、シーン内に緑色の立方体が表示されることになります。

背景の色を変更する

以下は画面の背景色を 明るい黄色 に設定するコードです。

renderer.setClearColor(0xffea00);

setClearColor…レンダラーが描画を行う前に 画面をクリア(背景色を設定) するためのメソッドです。このメソッドで背景色を設定できます。

モデルを読み込む

GLTFLoaderを使って、外部の GLB ファイル(monkey.glb)を読み込み、シーンにモデルとして追加する処理です。

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
const monkeyUrl = new URL("../assets/monkey.glb", import.meta.url);

const assetLoader = new GLTFLoader();
assetLoader.load(
  monkeyUrl.href,
  function (gltf) {
    const model = gltf.scene;
    scene.add(model);
    model.position.set(-12, 4, 10);
  },
  undefined,
  function (error) {
    console.error(error);
  }
);

1. import { GLTFLoader } from “three/examples/jsm/loaders/GLTFLoader.js”;

  • GLTFLoaderは、GLTF(またはGLB)形式の3Dモデルを読み込むためのthree.jsのローダーです。
  • import 文を使って、GLTFLoaderをインポートしています。これにより、GLTFファイル(.glb)を読み込んで、three.jsのシーンに追加することができます。

2. const monkeyUrl = new URL(“../assets/monkey.glb”, import.meta.url);

  • monkeyUrl は、monkey.glb というGLBファイルへのURLを作成する変数です。
  • new URL を使うことで、相対パス (../assets/monkey.glb) を基に、現在のファイルのURL(import.meta.url)と合わせて絶対パスを生成します。
  • これにより、monkey.glb ファイルが正しいパスで指定され、読み込み可能になります。

import.meta.url・・・JavaScriptモジュール内で現在のモジュールのURL(ファイルの場所)を指す特別なオブジェクトです。これを使うことで、モジュールの相対パスから正しい絶対パスを生成できます。

3. const assetLoader = new GLTFLoader();

  • assetLoader は、GLTFLoaderのインスタンスを作成します。これを使って、GLTF(またはGLB)形式のモデルを読み込みます。

4. assetLoader.load(…)

  • load メソッドは、GLTF(またはGLB)ファイルを非同期で読み込むために使います。
  • 引数 は以下の通りです:
    1. monkeyUrl.href: 読み込むファイルのURL(先ほど作成した monkeyUrl から .href を使ってURL文字列を取得)。
    2. function(gltf): 読み込みが成功したときに呼ばれるコールバック関数。gltf オブジェクトには、GLTFファイルのデータ(シーンやアニメーションなど)が含まれています。この場合、gltf.scene がモデルのシーン部分です。
    3. undefined: この引数は読み込み進行状況のコールバック用ですが、今回は指定していないため undefined になっています。
    4. function(error): 読み込み中にエラーが発生した場合に呼ばれるコールバック関数。error オブジェクトにエラーメッセージが含まれます。

5. コールバック内での処理

  • const model = gltf.scene;
    • 読み込まれたGLTFファイルから、scene オブジェクト(3Dモデル)を取得します。この scene は、3Dオブジェクトやシーン内の内容を持っています。
  • scene.add(model);
    • scene.add() メソッドを使って、3Dモデル(model)を現在のthree.jsシーンに追加します。この段階で、モデルがシーンに表示されるようになります。
  • model.position.set(-12, 4, 10);
    • 読み込まれたモデルの位置を設定します。set() メソッドで、xyz 軸の座標を指定しています。この例では、x = -12y = 4z = 10 という位置にモデルが配置されます。

6. エラーハンドリング

  • function(error) コールバックでは、もし読み込み中にエラーが発生した場合、そのエラーをコンソールに出力します。