はじめに

Three.jsであらかじめ用意されてるマテリアルと、ブロック崩しゲーム開発で作成した魔法陣画像を使い、魔法陣を回転させ光のパーティクルを浮かび上がらせるアニメーションを作ってみました。

実装のメモを備忘録も兼ねて残しておきます。

[JavaScript] 魔法陣と月のエフェクトをThree.jsを使って実装

空に月も作成したので、その実装方法も紹介。

テクスチャ画像は、Nasaの公式サイトで公開されているものを利用しています。

やればやる程、上達しますし、色々なエフェクトやアニメーションが出来るようになって面白いです。

[JavaScript] 魔法陣と月のエフェクトをThree.jsを使って実装

1. Three.jsとそのエフェクトの概要

Three.jsは、Webブラウザ上で3Dグラフィックスを描画するための強力なJavaScriptライブラリです。WebGLを抽象化し、3Dグラフィックスの作成をより簡単にしてくれます。特に、エフェクトやアニメーションを加えることで、魅力的なビジュアルコンテンツを作成することができます。

このセクションでは、Three.jsの基本的な概念や機能について紹介し、どのようにして魔法陣や月のエフェクトを実装できるのかを理解するための基礎を学びます。

主なトピック

  • シーンとカメラ: 3D空間を定義し、カメラの視点を設定する方法。
  • ジオメトリとマテリアル: 3Dオブジェクトの形状や質感を作成する方法。
  • ライトとシャドウ: 光源の設定方法と、物体に影を落とす技術について。
  • アニメーション: 時間に応じてオブジェクトを動かし、リアルな動きを作り出す技術。

Three.jsは、これらの基本要素を組み合わせて、リアルタイムで動的な3DコンテンツをWeb上で表現することを可能にします。次に、魔法陣や月のエフェクトを実際に作成しながら、これらの基本技術を学んでいきます。

2. 魔法陣の作成

このセクションでは、Three.jsを使って魔法陣を作成する方法を紹介します。

魔法陣は、回転するトーラス(ドーナツ型のジオメトリ)をベースに、光の粒子エフェクトやアニメーションを加えることで、幻想的なビジュアルを作り出します。

トーラスジオメトリとテクスチャの設定

まず、魔法陣の形状を作成するために、Three.jsのTorusGeometry(トーラスジオメトリ)を使用します。このジオメトリはドーナツ型で、魔法陣の円形の特徴にピッタリです。次に、トーラスにテクスチャを適用して、魔法陣らしい質感を出します。

const geometry = new THREE.TorusGeometry(5, 3, 2, 100); // トーラスの半径、太さ、分割数
const texture = config.imgageList.find((item) => item.name === 'vortex')?.texture;
const material = new THREE.MeshBasicMaterial({
  color: 0x7000ff,  // 紫色
  map: texture,  // テクスチャを設定
  transparent: true,
  blending: THREE.AdditiveBlending,  // 加算ブレンドで光を強調
  side: THREE.FrontSide,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = (90 * Math.PI) / 180;  // 回転角度を調整
config.scene.add(mesh);

光の粒子エフェクトの追加

魔法陣の周りに光の粒子を追加することで、より幻想的で動的なエフェクトを作り出します。Three.jsのSpriteMaterialを使い、光の粒子をSpriteとしてシーンに配置します。この粒子は、回転や位置の変化、透明度の変化を加えることで、よりリアルに見せることができます。

const texture3 = config.imgageList.find((item) => item.name === 'sprite')?.texture;
const material3 = new THREE.SpriteMaterial({
  color: 0x007eff,  // 青い色
  map: texture3,
  blending: THREE.AdditiveBlending,
  depthWrite: false,
});
const sprite = new THREE.Sprite(material3);
config.scene.add(sprite);

アニメーションの作成(回転、透明度の変化)

魔法陣を動かすためには、回転させるアニメーションを加えます。また、粒子の透明度をsin関数を使って滑らかに変化させることで、幻想的なエフェクトを演出します。

let time = 0;
function animate() {
  mesh.rotation.z += 0.015;  // 回転させる速度
  material.opacity = 0.1 + 0.1 * (Math.sin(time) + 1);  // 透明度をsin関数で滑らかに変化

  time += 0.05;  // 時間を進めてsin波の動きを変化

  // 粒子の位置と透明度
  sprite.position.y += 0.01;  // 上昇
  material3.opacity -= 0.01;  // 薄くする

  config.renderer.render(config.scene, config.camera);
  requestAnimationFrame(animate);  // 次のフレームで再度呼び出し
}
animate();  // アニメーション開始

このセクションでは、トーラスジオメトリの作成から光の粒子エフェクトの追加、そしてアニメーションまで、魔法陣のビジュアルエフェクトを実装する方法を学びました。これにより、幻想的で動的な魔法陣のエフェクトが完成し、シーンに華やかさを加えることができます。

3. 月の作成と照明

このセクションでは、Three.jsを使って月のオブジェクトを作成し、照明を加えて月をリアルに見せる方法を紹介します。月の回転アニメーションを加え、スポットライトを使って月を照らすことで、幻想的なシーンを作り上げます。

月のテクスチャの読み込み

月の見た目をリアルにするために、月の表面にテクスチャを適用します。Three.jsでは、TextureLoaderを使って外部の画像を読み込み、月の表面にマッピングします。

const textureLoader = new THREE.TextureLoader();
const moonTexture = textureLoader.load('path/to/your/moon-texture.jpg');  // 月のテクスチャ画像を指定

const moonGeometry = new THREE.SphereGeometry(2, 32, 32);  // 月のジオメトリ
const moonMaterial = new THREE.MeshStandardMaterial({
  map: moonTexture,  // 月のテクスチャを適用
  emissive: new THREE.Color(0x888888),  // 薄く発光させる
  emissiveIntensity: 0.1,  // 発光の強さ
});
const moon = new THREE.Mesh(moonGeometry, moonMaterial);
moon.position.set(10, 10, -10);  // 月の位置を設定
config.scene.add(moon);

光源の設定(スポットライト、月の照らし方)

月をよりリアルに見せるためには、適切な光源が必要です。THREE.SpotLightを使って月を照らすことができます。スポットライトは特定の方向に強く光を当てるので、月の照明にピッタリです。

// スポットライトの作成
const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 4, 0.5);
spotLight.position.set(10, 20, 10);  // スポットライトの位置を設定
spotLight.target = moon;  // 月をスポットライトで照らす
config.scene.add(spotLight);
config.scene.add(spotLight.target);  // 月のターゲットを追加

スポットライトのpositionでライトの位置を設定し、targetを月に設定することで、月がその光源に照らされるようになります。Math.PI / 4は光の広がり角度で、0.5は光の減衰の強さを設定しています。

月の回転アニメーション

月が自転しているように見せるためには、rotationを使って月を回転させます。月の回転速度を設定することで、よりリアルな月の動きを作ることができます。

function animateMoon() {
  moon.rotation.y += 0.005;  // 月をゆっくり回転させる
  requestAnimationFrame(animateMoon);  // 次のフレームで再度呼び出し
}

animateMoon();  // アニメーション開始

月の自転をmoon.rotation.yに加え、回転速度を調整しています。これにより、月が一定のスピードで自転しているように見えます。

おわりに

公式サイトや、解説サイトを参考に作ってみましたが、既存のエフェクトだけでもアイデア次第でクオリティの高い物を作れるようです。

あとは、2Dの時と同じように、複数のオブジェクトとアニメーションパターンを組み合わせる事で、複雑で臨場感のあり演出が作れます。

また、別のオブジェクトを作ったり、エフェクトを変更して実験してみる予定です。