WebGL・Three.js入門①
はじめに
こんにちは。この記事は、学習の備忘録としてまとめていこうと思っています。
解説を目的としているわけではなく、自身の反芻のための意味合いが強いためご容赦ください。
WebGL について
WebGL は主要なモダンブラウザ(Chrome, FireFox, Safari, Edge)に対応しており、Web ページ上で 2D・3D グラフィックスを描画できる技術です。
元々はデスクトップ PC 上でグラフィックスを描画できるOpenGLという API がありました。その後スマホやタブレット等、デスクトップ PC に比べて計算資源(メモリや電力)に制約のある環境向けに、最適化されたOpenGL ESが策定されました。そこからさらに派生したものがWebGLとなります。
OpenGL 同様、WebGL も API の規格です。
なので、Web ページ上で 3D グラフィックスを描画するには WebGL の API を呼び出すことになります。
ただ、WebGL の API は低レベル(ハードウェアに近い意味)で複雑なため、Three.jsといった WebGL を使いやすくしてくれるライブラリ(フレームワーク)を利用して開発しています。
Three.js について
先述の通り WebGL は低レベルで複雑なため、その機能をより簡単に扱えるようにしたライブラリがThree.jsです。
この部分は私も学習中ですが、Three.js が提供する機能だけでは実現が難しい、より細かい描画制御が必要になる場面があります。そういったケースでは、Three.js を使いつつ、部分的に WebGL のコード(シェーダーなど)を直接記述することで、Three.js の手軽さと WebGL の高い自由度を両立させることができそうです。このようなハイブリッドな開発によって、より高度な表現を目指せます。
Three.js を用いた 3D オブジェクトの生成
下記は、シーンに基本的な 3D オブジェクト(キューブ)を生成し、アニメーションさせるためのコードです。
import * as THREE from "three";
// sceneの作成
const scene = new THREE.Scene();
// cameraの作成
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// rendererの作成
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// オブジェクトの作成
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;
// アニメーションループ
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
アニメーションループの仕組み
コードの心臓部はanimate関数です。ここではrequestAnimationFrameを使い、滑らかなアニメーションループを実現しています。
requestAnimationFrame(callback)とは、「ブラウザさん、次の画面を描画する準備ができたら、この callback 関数を実行してください」とお願い(スケジュール)するための命令です。
つまり、animate関数は処理の最後に「次のフレームでまた私を呼んでください」とブラウザに予約している、というイメージがより実態に近いです。これを**「アニメーションループ」や「レンダリングループ」**と呼ぶのが一般的です。
なぜ requestAnimationFrame を使うのか?
setIntervalや単純なwhileループではなくrequestAnimationFrameを使うのには、明確なメリットがあります。
-
スムーズな描画
ブラウザの画面更新のタイミング(通常は 1 秒間に 60 回)と同期して実行されるため、カクカクしにくい滑らかなアニメーションが実現できます。 -
効率的
ページが非アクティブなタブにある時など、不要な場面ではアニメーションが自動的に停止するため、PC の CPU やバッテリーに優しいです。
まとめ
three.js をインポートからアニメーションの実装までを行いました。
基本的な部分ですが、この技術の発端や、言葉の定義(シーンやジオメトリ等)を理解して実際に手を動かしてみると理解がより深まりました。
参考サイト
他教材
Discussion