見出し画像

three.js 入門 (1) - 事始め

以下の記事が面白かったので、ざっくり翻訳しました。

Creating a scene – three.js docs

1. three.js

three.js」は、Webブラウザ上で3Dグラフィックスを描画するためのJavaScriptのAPIです。

2. HTMLとthree.jsの準備

「HTML」と「three.js」を準備します。

(1) 「index.html」を作成し、以下のように編集。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <style>
      body { margin: 0; }
    </style>
  </head>
  <body>
    <script src="three.js"></script>
    <script>
      // JavaScriptをここに追加
    </script>
  </body>
</html>

(2) ここから「three.js」をダウンロード。

3. シーンとカメラとレンダラーの準備

「three.js」で何かを表示するには、「シーン」「カメラ」「レンダラー」の3つが必要です。

// シーンの準備
const scene = new THREE.Scene()

// カメラの準備
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)

// レンダラーの準備
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

◎ カメラ
「three.js」には何種類かのカメラが提供されています。今回は「PerspectiveCamera」を使います。引数は、次のとおりです。

・fov : 視錐台の垂直視野(度)。
・aspect : 視錐台のアスペクト比。
・near : 視錐台の近くのクリップ平面。
・far : 視錐台の遠くのクリップ平面。

画像3

カメラの種類は、次のとおりです。

・PerspectiveCamera : 透視投影のカメラ
・OrthographicCamera : 平行投影のカメラ

◎ レンダラー
レンダラーを作成し、レンダリングサイズも指定します。
解像度を低くしたい場合は、以下のように指定します。

renderer.setSize(window.innerWidth/2, window.innerHeight/2, false);

4. 立方体の準備

立方体を準備するコードは、次のとおりです。

// 立方体の準備
const geometry = new THREE.BoxGeometry() // ジオメトリ
const material = new THREE.MeshBasicMaterial({color: 0x00ff00}) // マテリアル
const cube = new THREE.Mesh(geometry, material) // キューブ
scene.add(cube)
camera.position.z = 5

形状を表す「BoxGeometry」と色を表す「MeshBasicMaterial」を準備し、それらを使って立方体の「Mesh」を作成します。最後にscene.add()で立方体をシーンに追加しています。立方体は(0, 0, 0)に配置されるので、カメラのZ座標を少しずらして、立方体がカメラに映るよう調整します。

ジオメトリの種類は、次のとおりです。

・PlaneGeometry : 平面
・SphereGeometry : 球体
・BoxGeometry : 直方体
・ConeGeometry : 三角錐
・CylinderGeometry : 円柱
・TorusGeometry : ドーナツ形状

マテリアルの種類は、次のとおりです。

・MeshBasicMaterial : 光源を考慮しないベタ塗りのマテリアル
・MeshNormalMaterial : 光源を考慮しないRGB指定のマテリアル
・MeshLambertMaterial : 光沢感のないマテリアル
・MeshPhongMaterial : 光沢感のあるマテリアル
・MeshToonMaterial : トゥーンシェーディングのマテリアル
・MeshStandardMaterial : 物理ベースレンダリングのマテリアル

5. アニメーションループの開始

上記のコードだけでは、まだ何も表示されません。立方体を表示するには、「アニメーションループ」が必要になります。

// アニメーションループの開始
function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}
animate();

アニメーションループは画面更新毎(通常は1秒間に60回)に呼ばれます。setInterval()ではなく、requestAnimationFrame()を使うことで、ユーザーの別タブ移動時に、アニメーションループが一時停止するようになります。

アニメーションループ内でrenderer.render(scene, camera)を呼ぶことでレンダリングされます。

画像3

6. 立方体の回転

animate()のrenderer.render()を呼び出す前に、次のコードを追加することで、立方体を回転させることができます。

cube.rotation.x += 0.01
cube.rotation.y += 0.01

画像3

7. ライトの準備

ライトを追加して陰影を表示するようにします。

// ライトの準備
const directionalLight = new THREE.DirectionalLight('#aaaaff', 1)
directionalLight.position.set(0, 10, 10)
scene.add(directionalLight)

ライトの種類は、次のとおりです。

・AmbientLight : 環境光源
・DirectionalLight : 平行光源
・PointLight : 点光源
・SpotLight : スポットライト光源
・RectAreaLight : 矩形光源

立方体の「MeshBasicMaterial」を「MeshPhongMaterial」に変更する必要があります。

const material = new THREE.MeshPhongMaterial({color: 0x00ff00}) // マテリアル

画像4

8. カメラのマウス操作

「OrbitControls.js」を使うことで、カメラのマウス操作を追加することができます。

・周回軌道 : 左ボタンでドラッグ
・ズーム : マウスホイール
・パン : 右ボタンでドラッグ

(1)「OrbitControls.js」を取得して配置。

(2) scriptタグで「OrbitControls.js」を読み込み。

    <script src="OrbitControls.js"></script>

(3) コントローラの準備。

// コントローラーの準備
const controls = new THREE.OrbitControls(camera, document.body)

(4) アニメーションループ内でcontrols.update()を呼ぶ。

// アニメーションループの開始
function animate() {
  requestAnimationFrame(animate)
  cube.rotation.x += 0.01
  cube.rotation.y += 0.01
  controls.update() // ← 追加
  renderer.render(scene, camera)
}

9. 全ソースコード

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <style>
      body { margin: 0; }
    </style>
  </head>
  <body>
    <script src="three.js"></script>
    <script src="OrbitControls.js"></script>
    <script>
// シーンの準備
const scene = new THREE.Scene()

// カメラの準備
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)

// レンダラーの準備
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

// ライトの準備
const directionalLight = new THREE.DirectionalLight('#aaaaff', 1)
directionalLight.position.set(0, 10, 10)
scene.add(directionalLight)

// 立方体の準備
const geometry = new THREE.BoxGeometry() // ジオメトリ
const material = new THREE.MeshPhongMaterial({color: 0x00ff00}) // マテリアル
const cube = new THREE.Mesh(geometry, material) // メッシュ
scene.add(cube)
camera.position.z = 5

// コントローラーの準備
const controls = new THREE.OrbitControls(camera, document.body)

// アニメーションループの開始
function animate() {
  requestAnimationFrame(animate)
  cube.rotation.x += 0.01
  cube.rotation.y += 0.01
  controls.update()
  renderer.render(scene, camera)
}
animate()
    </script>
  </body>
</html>

10. 参考

次回


いいなと思ったら応援しよう!