🧐

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 オブジェクト(キューブ)を生成し、アニメーションさせるためのコードです。

app.ts
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 をインポートからアニメーションの実装までを行いました。
基本的な部分ですが、この技術の発端や、言葉の定義(シーンやジオメトリ等)を理解して実際に手を動かしてみると理解がより深まりました。


参考サイト

https://balance.bz/magazine/category/system/webgl/
https://freelance.shiftinc.jp/column/opengl/
https://ics.media/tutorial-three/quickstart/
他教材


GitHubで編集を提案

Discussion