Three.jsはHTMLの3D技術「WebGL」を扱いやすくしたフレームワークです。Three.jsを使えばGPUによる本格的な3D表現をプラグイン無しで作成できます。
ライブラリのセットアップから3D画面への表示および直方体の回転までを紹介します。手順通りに進めば、20分くらいで作業が完了できると思います。
まずはHTMLファイルを用意して、次のコードを貼り付けて試してください。
<html>
<head>
<meta charset="utf-8" />
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.module.js"
}
}
</script>
<script type="module">
import * as THREE from "three";
// サイズを指定
const width = 960;
const height = 540;
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("#myCanvas"),
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, width / height);
camera.position.set(0, 0, +1000);
// 箱を作成
const geometry = new THREE.BoxGeometry(400, 400, 400);
const material = new THREE.MeshNormalMaterial();
const box = new THREE.Mesh(geometry, material);
scene.add(box);
tick();
// 毎フレーム時に実行されるループイベントです
function tick() {
box.rotation.y += 0.01;
renderer.render(scene, camera); // レンダリング
requestAnimationFrame(tick);
}
</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
ブラウザの画面上に単色の直方体が回転します。
ちなみに前提としてThree.jsはWebGL対応のブラウザが必須となりますので、動作確認はFirefoxやChrome、Safari、Edgeなどを使うといいでしょう。
また、WebGLはローカルファイルのセキュリティーの制限があるため、ローカルサーバー上で実行することをオススメします。ローカルサーバーの構築方法がわからなければ、記事『VS Codeを使いこなせ! フロントエンジニア必須の拡張機能7選』で紹介している「Live Server」を利用しましょう。マウス操作で簡単にローカルサーバーを起動できるので簡単です。
ここからは、上記のコードを解説していくので、少しずつ理解していきましょう。
canvas要素を用意する
Three.jsはHTML5のcanvas
要素を利用します。canvas
要素はコンテンツを表示する描画エリアとなります。canvas
要素には属性としてid
(ID値)を最低限設定しておきましょう。
<body>
<canvas id="myCanvas"></canvas>
</body>
canvas
要素の大きさはJavaScriptを使って設定します。
JSライブラリを読み込む
Three.jsはJavaScriptのライブラリですが、このファイルを読み込むことによってはじめてThree.jsが利用できるようになります。
CDN(コンテンツ・デリバリー・ネットワーク)で提供されているURLを使うのが導入にお手軽です。ECMAScript Modulesの仕組みを使って、import
文でThree.jsを読み込みます。
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.module.js"
}
}
</script>
WebGLの処理はJavaScriptで記述します。Three.jsはES Modulesに対応しているため、import
文で読み込むことができます。import
文は<script>
要素のtype
属性にmodule
を指定することで利用できます。
<script type="module">
import * as THREE from "three";
// 処理
</script>
3D表示用のJavaScriptを用意
WebGLのレンダリングをするためのレンダラーを作成します。THREE.WebGLRenderer
クラスのコンストラクターには引数として、HTMLに配置したcanvas
要素を指定し、連携させます。
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
デフォルトではレンダラーのサイズが小さいため、setSize()
メソッドでサイズを設定します。今回のデモでは幅960px、高さ540pxを設定しています。
renderer.setSize(960, 540);
シーンを作成する
シーンを作成します。シーンとは3D空間のことで、3Dオブジェクトや光源などの置き場となります。
const scene = new THREE.Scene();
カメラを作る
3Dではどの視点から空間を撮影するか、という実装をします。この機能は「視点」や「カメラ」と呼ばれます。
Three.jsではTHREE.PerspectiveCamera
クラスのコンストラクターで画角、アスペクト比、描画開始距離、描画終了距離の4つの情報を引数として渡しカメラを作成します。
// new THREE.PerspectiveCamera(画角, アスペクト比
const camera = new THREE.PerspectiveCamera(45, 960 / 540);
立方体を作る
立方体はメッシュという表示オブジェクトを使用して作成します。メッシュを作るには、ジオメトリ(形状)とマテリアル(素材)の二種類を用意する必要があります。
ジオメトリとは頂点情報や面情報を持っています。Three.jsにはさまざまなジオメトリが用意されていますが、今回は立方体や直方体のような箱状の形状を生成するためのBoxGeometry
を使用します。
// new THREE.BoxGeometry(幅, 高さ, 奥行き)
const geometry = new THREE.BoxGeometry(500, 500, 500);
マテリアルは色や質感の情報を持っています。今回はとりあえず箱を表示させたいので、THREE.MeshNormalMaterial
という適当なカラーを割り振るマテリアルを生成します。
const material = new THREE.MeshNormalMaterial();
作成したジオメトリとマテリアルを使って、メッシュを作ります。作成したメッシュをシーンに追加しましょう。
// new THREE.Mesh(ジオメトリ,マテリアル)
const box = new THREE.Mesh(geometry, material);
// シーンに追加
scene.add(box);
アニメーション
JavaScriptでアニメーションをさせるには、時間経過で関数を呼び続ける必要があります。そのためには、requestAnimationFrame()
というグローバルメソッドを使用します。requestAnimationFrame()
は引数として渡された関数を、毎フレーム実行します。
// 初回実行
tick();
function tick() {
requestAnimationFrame(tick);
// アニメーション処理をここに書く
}
次に、Three.jsの表示結果を更新する命令を書きます。Three.jsでは自動的に画面が最新に切り替わらないので、明示的に画面が更新されるように命令を書く必要があります。renderer.render()
という命令で更新を指示できます。
// 初回実行
tick();
function tick() {
requestAnimationFrame(tick);
// アニメーション処理をここに書く
renderer.render(scene, camera); // レンダリング
}
アニメーションの処理として、立方体が回転するようにしてみましょう。時間経過で回転するようにrotation.y
プロパティの数値を加算しています。
// 初回実行
tick();
function tick() {
requestAnimationFrame(tick);
// アニメーション処理をここに書く
box.rotation.y += 0.01;
renderer.render(scene, camera); // レンダリング
}
以上がサンプルの解説となります。
Three.jsの基本構造
上記のコードで出現したThree.jsの基本機能について紹介します。
図:Three.jsを構成する基本的なオブジェクトと表示の仕組み
ビュー(HTMLのcanvas
タグ)が実際に表示される画面となります。
THREE.Sceneクラス
3Dの空間を表すクラス。3Dのオブジェクトはシーンにadd()
メソッドを利用して追加することで表示できます。
THREE.PerspectiveCameraクラス
3D空間を撮影するカメラ。視点を制御するために使用します。3D空間のどの視点で撮影しているのかの情報が必要となります。
THREE.WebGLRendererクラス
3D空間のレンダリングを行います。レンダリングとは、Three.jsで計算した3Dのオブジェクトを画面に表示することです。内部的にはThree.jsがWebGLのAPIを使って、GPUで座標を計算させ画面に表示させています。Three.jsではrequestAnimationFrame
のタイミングにあわせて、レンダリングを行うように設定しましょう。
まとめ
3Dと聞くと難しそうと思われがちですが、あっけなく動作したので驚かれた方も多いのではないでしょうか?
次回の記事では、マテリアルやライティングの設定方法を説明します。