Three.js、基本操作、シーン作成からアニメーションまでの基礎

threejs-phaser

Three.jsとは?

Three.jsは、Web上で3Dグラフィックスを作成するためのJavaScriptライブラリです。WebGLをベースにしており、ブラウザ上で複雑な3Dシーンを簡単に描画できます。シンプルなAPIを提供し、3Dグラフィックスの作成を容易にするために設計されています。

主要な機能と利点

簡単なセットアップ
Three.jsは、3Dグラフィックスの描画を簡単に始めるための高レベルの抽象化を提供します。基本的な設定だけで3Dシーンを作成できるため、複雑なWebGLのコードを書く必要がありません。

豊富なオブジェクトとマテリアル
ジオメトリ、メッシュ、ライト、マテリアルなど、多くの3D要素を簡単に追加できます。これにより、リアルなシーンやアニメーションを作成する際の柔軟性が増します。

アニメーションのサポート
Three.jsは、アニメーションのフレームワークを提供しており、オブジェクトの動きを滑らかにするための便利な機能を持っています。

インタラクティブな要素
マウスやキーボードの入力を処理し、ユーザーインタラクションを3Dシーンに組み込むことができます。

広範なドキュメントとコミュニティ
Three.jsには豊富な公式ドキュメントがあり、活発なコミュニティも存在します。これにより、問題解決や新しい技術の習得がスムーズに進みます。

シーン➀、カメラ②、レンダラー③の作成

HTMLファイルを作成する

まず、index.htmlという名前のファイルを作成します。このファイルに、Three.jsを使ったシーンを表示するための基本的な構成を記述します。

Three.jsを使用するためにCDNを読み込ませてください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/three@0.143.0/build/three.min.js"></script>
</head>
<body>
    <script>
        // ここにThree.jsのコードを書きます
    </script>
</body>
</html>
index.html

シーンの作成

Three.jsで3Dシーンを作成するには、THREE.Sceneオブジェクトを作成します。シーンは、3Dオブジェクトや光源、カメラなどを含むコンテナです。

// ➀シーンの作成
    const scene = new THREE.Scene();
JavaScript

カメラの設定

Three.jsでは、カメラはシーンを視覚化するための視点を提供します。最も一般的に使用されるのは THREE.PerspectiveCamera です。4つの引数を受け取ります。PerspectiveCamera

  • 視野角 (FOV): 75度程度がおすすめ。広くすると遠くまで見渡せますが、歪みが増えます。
  • アスペクト比: ウィンドウの幅と高さに基づいて設定。
  • クリッピング:
    • 近いクリップ面: 0.1以上を推奨(精度とパフォーマンスの問題を防ぐため)。
    • 遠いクリップ面: シーンのサイズに合わせて2000~3000などを設定。
// ➁カメラの設定
const camera = new THREE.PerspectiveCamera(
  75, // 視野角 (度)camera.fov
  window.innerWidth / window.innerHeight, // アスペクト比camera.aspect
  0.1, // 近くのクリッピング平面camera.near
  1000 // 遠くのクリッピング平面camera.for
);
camera.position.set(30,30,50);//カメラのポジションcamera.position
camera.lookAt(0, 0, 0); //カメラの視点camera.matrix.elements や camera.matrixWorld自動で計算
JavaScript

カメラの視点設定について: camera.lookAt(0, 0, 0) は、カメラがシーン内のどの方向を向くかを指定するためのメソッドです。この例では (0, 0, 0) を指定しているため、カメラはシーンの中心を向くことになります。

もし camera.lookAt を指定しない場合、カメラ自体は移動できますが、視点(向き)は変わりません。イメージとしては、自分の体をカメラに見立てた場合、前後上下左右に移動はできるものの、体の向きを変えられない状態に似ています。
camera.lookAt(0, 0, 0) を使うことで、カメラの向きを指定し、シーン内で適切な方向を見ることができるようになります。

camera.position.set(30, 30, 50) の概要

  • x: 30 → 水平方向にシーンの中心を基準に配置。
  • y: 30 → カメラを30ユニット上に移動(高い視点)。
  • z: 50 → シーンおおよそ全体を見渡せる距離を確保。

シーンに応じて調整可能。高い視点や遠い視点が必要なら適宜変更します。

レンダラーの設定

レンダラーはシーンを描画するための重要な部分で、一般的に THREE.WebGLRenderer が使用されます。以下の設定を活用して、描画品質を調整できます。

プロパティの説明

  • antialias: true
    • 初期値は false。true にするとオブジェクトのエッジが滑らかになります(アンチエイリアス有効化)。パフォーマンスに影響する場合があります。
  • alpha: false
    • 初期値は false。透明背景が必要な場合に true を設定。
  • precision: ‘highp’
    • 初期値は ‘highp’(高精度)。lowp(低精度)や mediump(中精度)に変更可能。高精度にするとパフォーマンスが低下する場合があります。
// ➂レンダラーの作成
const renderer = new THREE.WebGLRenderer({
  antialias: true,       // アンチエイリアスを有効化、エッジを滑らかに
  alpha: false,          // 背景の透明度を無効化
  precision: 'highp',    // 高精度のシェーダープログラム計算
});

// レンダラーのキャンバスをDOMに追加
document.body.appendChild(renderer.domElement);

// レンダラーのサイズをウィンドウサイズに設定
renderer.setSize(window.innerWidth, window.innerHeight);

// 背景色を設定(灰色: 0x808080)
renderer.setClearColor(0x808080);
JavaScript

ポイント

  1. キャンバスの追加
    • renderer.domElement を document.body に追加して表示します。
  2. サイズ設定
    • renderer.setSize(window.innerWidth, window.innerHeight) でレンダラーの解像度をウィンドウサイズに合わせます。
  3. 背景色
    • renderer.setClearColor(0x808080) で背景色を灰色に設定しています。

コードまとめ③まで

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/three@0.143.0/build/three.min.js"></script>
</head>
<body>
    <script>
// ➀シーンの作成
    const scene = new THREE.Scene();

// ➁カメラの設定
    const camera = new THREE.PerspectiveCamera(
        75, // 視野角 (度)
        window.innerWidth / window.innerHeight, // アスペクト比
        0.1, // 近くのクリッピング平面
        1000 // 遠くのクリッピング平面
    );
    camera.position.set(30,30,50);//カメラのポジション
    camera.lookAt(0, 0, 0);//カメラの視点
// ➂レンダラーの作成
    const renderer = new THREE.WebGLRenderer({
        antialias: true,       // アンチエイリアスを有効化、エッジを滑らかに
        alpha: false,          // 背景の透明度を無効化
        precision: 'highp',    // 高精度のシェーダープログラム計算
    });

    // レンダラーのキャンバスをDOMに追加
    document.body.appendChild(renderer.domElement);

    // レンダラーのサイズをウィンドウサイズに設定
    renderer.setSize(window.innerWidth, window.innerHeight);

    // 背景色を設定(灰色: 0x808080)
    renderer.setClearColor(0x808080);
    </script>
</body>
</html>
HTML

光源④と物体⑤を追加

Three.jsでは、3Dシーンをよりリアルに表現するために光源を使用します。光源を追加することで、オブジェクトが光を反射し、影や質感が現れるようになります。

光源を追加

さまざまな種類の光源が用意されています。それぞれの光源には特徴があり、シーンの演出や目的に応じて選択します。

主な光源の種類

  • AmbientLight(環境光)
    • シーン全体を均一に照らす光。影を作りません。
// ➃光源を作成
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 白い環境光
scene.add(ambientLight);
JavaScript
  • DirectionalLight(方向光)
    • 太陽光のように一定方向から照らす光。影を作ることができます。
// ➃光源を作成
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 白い方向光
directionalLight.position.set(0, 10, 0); // 光源の位置を設定
scene.add(directionalLight);
JavaScript
  • PointLight(点光源)
    • 電球のように全方向に光を放つ光源。影を作ることができます。
// ➃光源を作成
const pointLight = new THREE.PointLight(0xffffff, 1, 500, 1.0); // 白い点光源
pointLight.position.set(5, 0, 20); // 光源の位置を設定
scene.add(pointLight);
JavaScript

mesh(物体)を追加

Three.jsでは、ジオメトリ(形状)とメッシュジオメトリマテリアルを適用したもの)を使用して3Dオブジェクト(物体)を作成します。

//➄mesh(物体)を作成

// サイズ 50x50x50 の立方体を定義
const geometry = new THREE.BoxGeometry(20, 20, 20);
// マテリアル(外観)の作成
// ランバートマテリアル(光の影響を受ける)で赤色を設定
const material = new THREE.MeshLambertMaterial({ color: 0xff0000 });

// ジオメトリとマテリアルを組み合わせてメッシュ(物体)を作成
const mesh = new THREE.Mesh(geometry, material);

// シーンにメッシュを追加
scene.add(mesh);
JavaScript

コードのポイント

  1. ジオメトリ (Geometry)
    • 形状を定義します。この場合、BoxGeometry を使用してサイズ 20x20x20 の立方体を作成しています。3Dオブジェクトの形状を定義します(例: BoxGeometry, SphereGeometry, PlaneGeometry)。
  2. マテリアル (Material)
    • ジオメトリ(形状)に色や質感を与えるためのもので、3Dオブジェクトの見た目を決定します。
    • MeshLambertMaterial は光の影響を受けるマテリアルです。
    • この例では赤色(0xff0000)を設定しています。
  3. メッシュ (Mesh)
    • Mesh はジオメトリとマテリアルを組み合わせた、シーンに描画できるオブジェクトです。
  4. シーンへの追加
    • scene.add(mesh) によって、メッシュがシーンに追加され、レンダリングされる対象になります。

種類

Three.js では、ジオメトリ、マテリアル、メッシュにさまざまな種類があります。

  • ジオメトリ
    3Dオブジェクトの形状を定義する要素です。例として、立方体の形状を作る BoxGeometry や、球体の形状を作る SphereGeometry などがあります。
  • マテリアル
    ジオメトリに色や質感を与える役割を持つ要素です。
    • MeshBasicMaterial: 光の影響を受けず、単純な色やテクスチャを表示するマテリアル。
    • MeshPhongMaterial: 光を反射し、リアルな質感を表現するマテリアル。

光源の影響を受けないマテリアル

  1. MeshBasicMaterial:光源がなくても適切に表示されるため、効率的です。
  2. SpriteMaterial:スプライト(2D平面)に適用されるマテリアル。
  3. PointsMaterial:点群に適用するためのマテリアル。
  4. ShaderMaterial / RawShaderMaterial:カスタムシェーダーで見た目を完全に制御。通常、光源の影響を受けません(ただし、シェーダーコードによる)。

割合と用途の違い

  • 光の影響を受けないマテリアル は、シンプルな描画やパフォーマンスを重視する用途(UI、2D風のオブジェクトなど)でよく使われます。
  • 光の影響を受けるマテリアル は、リアルな3D表現を目指す用途(ゲーム、リアルなシミュレーションなど)で使われます。

最後のステップ:レンダリング⑥

レンダリングは、Three.js でシーンを画面に表示するための最後の重要な作業です。このステップがなければ、作成したシーン、カメラ、光源、メッシュは描画されません。

//➅mesh(物体)を作成
renderer.render(scene, camera);
JavaScript
  • scene: ①描画するシーン。
  • camera: ②描画する視点。

描画の必須作業: このコードがないと、作成した3Dオブジェクトはブラウザに表示されません。
簡潔さ: Three.jsでは、レンダリングはシンプルで効率的です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/three@0.143.0/build/three.min.js"></script>
</head>
<body>
    <script>
// ➀シーンの作成
    const scene = new THREE.Scene();

// ➁カメラの設定
    const camera = new THREE.PerspectiveCamera(
        75, // 視野角 (度)
        window.innerWidth / window.innerHeight, // アスペクト比
        0.1, // 近くのクリッピング平面
        1000 // 遠くのクリッピング平面
    );
    camera.position.set(30, 30, 50);//カメラのポジション
    camera.lookAt(0, 0, 0);//カメラの視点
// ➂レンダラーの作成
    const renderer = new THREE.WebGLRenderer({
        antialias: true,       // アンチエイリアスを有効化、エッジを滑らかに
        alpha: false,          // 背景の透明度を無効化
        precision: 'highp',    // 高精度のシェーダープログラム計算
    });

    // レンダラーのキャンバスをDOMに追加
    document.body.appendChild(renderer.domElement);

    // レンダラーのサイズをウィンドウサイズに設定
    renderer.setSize(window.innerWidth, window.innerHeight);

    // 背景色を設定(灰色: 0x808080)
    renderer.setClearColor(0x808080);
    
// ➃光源を作成
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 白い方向光
    directionalLight.position.set(0, 10, 0); // 光源の位置を設定
    scene.add(directionalLight);
    
    
// ➃光源を作成
    const pointLight = new THREE.PointLight(0xffffff, 1, 500, 1.0); // 白い点光源
    pointLight.position.set(5, 0, 20); // 光源の位置を設定
    scene.add(pointLight);

//➄mesh(物体)を作成

    // サイズ 50x50x50 の立方体を定義
    const geometry = new THREE.BoxGeometry(20, 20, 20);
    // マテリアル(外観)の作成
    // ランバートマテリアル(光の影響を受ける)で赤色を設定
    const material = new THREE.MeshLambertMaterial({ color: 0xff0000 });
    
    // ジオメトリとマテリアルを組み合わせてメッシュ(物体)を作成
    const mesh = new THREE.Mesh(geometry, material);
    
    // シーンにメッシュを追加
    scene.add(mesh);
    
//➅mesh(物体)を作成
    renderer.render(scene, camera);
    </script>
</body>
</html>
HTML

アニメーション

アニメーションを追加して、動きをつけることで視覚的にわかりやすくします。これにより、カメラやオブジェクトの挙動を直感的に確認できるようになります。特に、カメラの移動や回転がどのようにシーンに影響するのかを視覚的に把握する際に役立ちます。

下記のコードに上書きしてください。

//➅mesh(物体)を作成
    renderer.render(scene, camera);
JavaScript

2つのコードをご用意したので試してみて下さい。

const radius = 50; // 光源の回転半径

function animateLight() {
  // 時間を基準に光源の位置を計算
  const t = performance.now() * 0.002; // 時間をスムーズに調整
  pointLight.position.set(
    radius * Math.cos(t),            // x座標
    6 + 5 * Math.sin(t / 3),         // y座標(高さの変化を追加)
    radius * Math.sin(t)             // z座標
  );

  // シーンをレンダリング
  renderer.render(scene, camera);

  requestAnimationFrame(animateLight); // 再帰呼び出し
}

// アニメーションを開始
animateLight();
JavaScript
const radius = 20; // 光源の回転半径

function animateLight() {
  // 時間を基準に光源の位置を計算
  const t = performance.now() * 0.002; // 時間をスムーズに調整

  // pointLight の位置を設定
  pointLight.position.set(
    radius * Math.cos(t),            // x座標
    6 + 5 * Math.sin(t / 3),         // y座標(高さの変化を追加)
    radius * Math.sin(t)             // z座標
  );
  // directionalLight の位置を設定(異なる動きも適用可能)
  directionalLight.position.set(
    radius * Math.sin(t),       // x座標(横方向に動く)
    radius * Math.cos(t),       // y座標(上下に動く)
    0                           // z座標を固定
  );
  // シーンをレンダリング
  renderer.render(scene, camera);

  requestAnimationFrame(animateLight); // 再帰呼び出し
}

// アニメーションを開始
animateLight();
JavaScript

ヘルパー

Three.jsでライトやカメラなどのオブジェクトの視覚的なガイドラインを表示するためのツールです。シーン内でオブジェクトの位置や向きを確認しやすくなるため、開発中にとても便利です。いろんな種類があります。光源を作成した下に追記してください。

// ➃光源を作成
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 白い方向光
directionalLight.position.set(0, 0, 0); // 光源の位置を設定
scene.add(directionalLight);

const lightHelper = new THREE.PointLightHelper(directionalLight, 3);
scene.add(lightHelper);
JavaScript

最後のまとめ

記事の冒頭にもあった図解は、Three.jsを使った3Dシーン描画の基本的な流れを示したものでした。シーンの作成、カメラや光源、物体の配置、そしてブラウザへの描画まで、一連のプロセスを視覚的に理解するためのものです。

この流れを押さえることで、Three.jsの様々な応用機能にも挑戦しやすくなります。Three.jsは、アニメーションやインタラクション、リアルな光源や質感の表現など、幅広い可能性を持つ3D描画ツールです。基本を理解した上で、さらに応用的な機能を活用して、自由な3D空間を作り上げてみましょう。


  1. まず、シーン(①)を作成します。
    シーンは3D空間そのものであり、この中にカメラや光源、物体などを配置します。シーンがなければ何も描画できません。この「箱」の中にすべての要素が収まります。
  2. 次に、カメラ(②)を設置します。
    カメラは人間の目に相当する部分で、シーンをどの視点から見るのかを決定します。この図では、カメラが物体に向かってシーンを撮影している様子が描かれています。カメラが正しい位置にないと、何も見えないこともあります。
  3. その後、レンダラー(③)を用意します。
    レンダラーは、シーンとカメラの情報を基に、画面に3Dシーンを描画する役割を持ちます。この図では、レンダラーがシーンとカメラを接続し、最終的にブラウザの画面に結果を映し出しています。
  4. シーン内に光源(④)を追加します。
    光源は、物体を照らし、影や立体感を与えるために必要不可欠です。この図では電球のアイコンで光源を表しています。光源がない場合、物体は真っ黒で表示されてしまうことがあります。
  5. 物体(⑤)を作成します。
    物体は、形状(ジオメトリ)と質感(マテリアル)を組み合わせることで作られます。この図では、ジオメトリとマテリアルが組み合わさり、球形のメッシュとして完成しています。これがシーン内で描画される対象となります。
  6. 最後に、レンダリング(⑥)を実行します。
    すべての要素が揃ったら、レンダラーを使ってシーンをカメラ越しに描画します。この図では、ブラウザに3Dシーンが表示されている様子が描かれています。

この図解で伝えたいこと

この図は、Three.jsの基本的な構成を1つの流れとして視覚化しています。それぞれのステップが繋がり、最終的にブラウザにシーンが描画されるという全体像を簡単に理解できます。この流れを意識することで、Three.jsの仕組みをしっかりと押さえることができます。

コメント

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