
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 : 視錐台の遠くのクリップ平面。
カメラの種類は、次のとおりです。
・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)を呼ぶことでレンダリングされます。
6. 立方体の回転
animate()のrenderer.render()を呼び出す前に、次のコードを追加することで、立方体を回転させることができます。
cube.rotation.x += 0.01
cube.rotation.y += 0.01
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}) // マテリアル
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>