🐥

JavaScript初心者のためのThree.jsハンズオン

2024/01/19に公開

Three.jsとはその名の通り、3次元の動きをJavaScriptで作り出すライブラリです。
JavaScriptがまだまだわからないピヨピヨのエンジニアであるわたしでも、ある一定のコードを覚えれば無限の動きを作り出すことが出来る神のようなライブラリです。
作例は公式からご覧ください👍
https://threejs.org/

以下はUdemyのShin CodeさんのThree.js入門を進めながらまとめました。
(コードが間違っていたら教えてください🙇)

Three.jsに絶対に必要なものは3つ
1.🎬scene ・・・ステージのようなもの
2.🎥camera ・・・ステージを映すカメラのようなもの
3.🪄renderer ・・・画面に映すための変換器のようなもの

事前準備

💡npmで環境構築(ターミナル)

🟡 three.jsをインストール

//ターミナルからインストール
npm install --save three

🔵 viteをインストール、起動

npm install --save-dev vite
npx vite

(参考記事:Three.js)
https://threejs.org/docs/index.html#manual/en/introduction/Installation

👍 前準備

まずはindex.htmlのbody内にcanvasタグを設置する

// index.html
<canvas id="canvas"></canvas>

jsファイルでthree.jsをimportする

import * as THREE from 'three';

グローバルに適用したい要素を定義しておく

const scene , camera , rederer;

🎬 1.sceneを作ってみよう

🔹sceneを追加してみよう

//sceneを追加
scene = new THREE.Scene();

1️⃣ geometryを追加してみよう

🔹今回はSphereGeometry
※引数はThree.jsのドキュメントを参照

const geometry = new THREE.SphereGeometry( 100, 64, 32 );

2️⃣ materialを追加してみよう

今回はMeshPhysicalMaterial
※引数はThree.jsのドキュメントを参照

const Material = new THREE.MeshPhysicalMaterial({colorプロパティ等});  

🔹テクスチャを追加してみよう
TextureLoader関数で追加したい要素を読み込みます

const texture = new THREE.TextureLoader().load("texture.jpg")

🔹追加したテクスチャをmaterialに追加しよう

mapでテクスチャを追加

const Material = new THREE.MeshPhysicalMaterial({
    map: texture,
   });  

3️⃣ Mesh化してみよう

①と②で作成したgeometryとmaterialを追加する

const sphere = new THREE.Mesh( geometry, material );

🔹sceneにMesh化したものを追加しよう

scene.add( sphere );

🎥 2.cameraを追加しよう

🔹cameraを追加してみよう
PerspectiveCameraで追加する

//cameraを追加
camera = new THREE.PerspectiveCamera(50,innerWidth / innerHeight,0.1,1000);
//camera = new THREE.PerspectiveCamera(視野角,アスペクト比,開始距離,終了距離);

🔸そのままでは見えないため、cameraのポジションをセットしよう

camera.position.set(0 , 0 , 500 );//(x , y , z)

🕋 3.rendererを追加しよう

🔹レンダラーを追加してみよう

・HTMLで記述したcanvasを取得

renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#canvas'),
});

//またはbodyの子要素として「renderer」をDOM要素として挿入でもOK
document.body.appendChild(rederer.domElement);

🔹背景を設定してみよう

・現在の背景は真っ黒なため、CSSで背景を設定
⇒ このままでは背景が見えません。
 ┗alpha: true,とすると背景が透明になる

renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#canvas'),
  alpha: true,
});

🔹rendererサイズを設定しよう

🔸setSizeでrendererのサイズをブラウザ100%に。

renderer.setSize(window.innerWidth, window.innerHeight);//画面のサイズをブラウザ100%にする

🪄 レンダリングしてみよう

renderer関数でレンダリング

renderer.renderer(scene, camera);

🔹光源を追加してみよう

【平行光源】
directionalLight
※引数はThree.jsのドキュメントを参照
🔸光源の位置を変更したい場合はposition.setで設定
🔸scene.add(directionalLight);を忘れずに😇
🔸colorは16進数

const directionalLight = new THREE.DirectionalLight(0xffffff,1.5);//((カラー,強さ))
directionalLight.position.set(1,1,1);//(光源の位置を変更)
scene.add(directionalLight);

【ポイント光源】
💡PointLight
※引数はThree.jsのドキュメントを参照
🔸光源の位置を変更したい場合はposition.setで設定

pointLight = new THREE.PointLight(0xffffff,1);
pointLight.position.set(-200,-200,-200);//マイナスにすると後ろにいく
scene.add(pointLight);

👀
しかしこのままでは光源がどこなのかわかりにくいですよね。
⇒ そこで、光源がどこにあるかをHelperで確認出来るようにしましょう!

【Helperを表示させる】

🔸ポイント光源がどこにあるのかを特定する
PointLightHelper関数を使用する

const pointLightHelper = new THREE.PointLightHelper(pointLight,30);
scene.add(pointLightHelper);

ポイント光源を球の周りを巡回させよう

1.Date.nowで現在までの時刻をm秒単位で取得
2.Mathオブジェクトのsin関数を使用する

pointLight.position.set(
  200 * Math.sin(Date.now / 500), //X軸
  200 * Math.sin(Date.now / 500), //Y軸
  200 * Math.sin(Date.now / 500), //Z軸
);

3.アニメイト関数でフレームをループさせる
requestAnimationFrameを読む

+ requestAnimationFrame(animate);
function animate() {
  pointLight.position.set(
    200 * Math.sin(Date.now / 500), //X軸
    200 * Math.sin(Date.now / 500), //Y軸
    200 * Math.sin(Date.now / 500), //Z軸
 );
    requestAnimationFrame(animate);
}

3.関数内にrendererを入れる

function animate() {
  pointLight.position.set(
   200 * Math.sin(Date.now / 500), //X軸
   200 * Math.sin(Date.now / 500), //Y軸
   200 * Math.sin(Date.now / 500), //Z軸
   renderer.renderer(scene , camera);
 );
   renderer.renderer(scene , camera);
   requestAnimationFrame(animate);
}

これで球の周囲をぐるぐる回るポイント光源が完成⭐️

最後におまけ

🔹マウス操作ができるようにしよう

OrbitControls関数を使用します

controls = new OrbitControls(camera, renderer.domElement);

これでインタラクティブな操作が出来るじょ〜〜〜(山田)

いかがでしたか?
今回は本当に触りだけでしたが、
Three.jsのライブラリは日々進化しています。
少しの知識と好奇心で無限の可能性が広がるThree.jsライブラリに興味がある方は是非一緒に学習しましょう⭐️

Discussion