【WebGL】three.jsの基本

初心者が勉強しながら書いている覚え書きです。

# WebGLとは

3DCGをブラウザで表示させるためのJavaScript API。
WebGLを使うと、以下のようなことができる。

- 3Dモデルの表示
- ゲームコンテンツ
- データビジュアライゼーション
- プログラミングアート
- 魅力的で華やかな画面演出

参考：[WebGL入門　サンプルで理解する3D表現の迫力](https://ics.media/entry/2328/)


# three.jsとは

WebGLを比較的簡単に扱えるようにした、JavaScriptのライブラリ。


# three.jsを使う準備

#### three.jsファイルのダウンロード

1. [three.js公式サイト](https://threejs.org/)からライブラリをダウンロードし、three.jsファイルを自分の作業フォルダーにコピーする。

#### JavaScriptファイルを作成

```js
window.addEventListener("DOMContentLoaded", init);

function init() {
  // ここに記述していく
}
```

#### HTMLファイルを作成

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
</head>
<body>
  <canvas id="stage"></canvas>
  <script src="three.js"></script>
  <script src="index.js"></script>
</body>
</html>
```

# three.jsの基本的な書き方

#### レンダラーを作成

```js
const width = 500; // 描画領域を指定
const height = 500;

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#stage') //引数にはHTMLコード上に記載したcanvas要素の参照を渡す
  });
renderer.setPixelRatio(window.devicePixelRatio); // スマホで見てもぼやけないようにする
renderer.setSize(width, height);
renderer.setClearColor(0xefefef); // 背景色を設定
```

#### ステージ（scene）を作成
オブジェクトや光源などの置き場。

```js
const scene = new THREE.Scene();
```

#### カメラを作成

```js
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
camera.position.set(0, 0, 1000); //カメラの位置を指定
```

#### 物体（mesh）を作成

立方体はメッシュという表示オブジェクトを使用して作成する。
箱の形状を生成するにはBoxGeometryを使用する。

```js
const geometry = new THREE.BoxGeometry(100, 100, 100); // 形状（geometry）
const material = new THREE.MeshStandardMaterial({color: 0x7998FF});// 材質（material）を作成
const box = new THREE.Mesh(geometry, material); // 箱を作成
box.position.set(0, 0, 0); //物体の位置を指定
scene.add(box);
```

※カラーコードの前に'0x'をつける決まりがある。


#### 光源（light）を作成

平行光源（DirectionalLight）は太陽光のように一定方向から差し込む光。

```js
const light = new THREE.DirectionalLight(0xFFFFFF); // 平行光源
light.intensity = 2; // 光の強さを倍に
light.position.set(1, 1, 1); // 光源の位置を指定
scene.add(light); // シーンに追加
```
その他についてはこちらを参照。
[Three.js ライト機能まとめ](https://ics.media/tutorial-three/light_variation/)

#### レンダリング
`renderer.render()`メソッドに作成したシーンとカメラを引数に渡すと、canvas上に描かれる。

```js
renderer.render(scene, camera);
```
参考：[ドットインストール/Three.js入門](https://dotinstall.com/lessons/basic_threejs_v2)



# アニメーションをつける

`requestAnimationFrame()`というグローバルメソッドを使用。
引数として渡された関数を、毎フレーム実行する。
前章の「レンダリング」の部分を以下に書き換えて、箱を回転させる。

```js
// 初回実行
tick();

function tick() {
  requestAnimationFrame(tick);

  // 箱を回転させる
  box.rotation.x += 0.01;
  box.rotation.y += 0.01;

  // レンダリング
  renderer.render(scene, camera);
}
```

参考：[最新版で学ぶThree.js入門　手軽にWebGLを扱える3Dライブラリ](https://ics.media/entry/14771/)




# ヘルパー表示で作業を効率化

シーンの見えない部分を視覚化するヘルパーオブジェクトがたくさんあり、表示することで作業をしやすくすることができる。

```js
//平面にグリッドを設置
const gridHelper = new THREE.GridHelper(200, 50);
scene.add(gridHelper);
//xyz軸を表示
const axisHelper = new THREE.AxisHelper(1000, 50)
scene.add(axisHelper)
//ライトを表示
const lightHelper = new THREE.SpotLightHelper(light);
scene.add(lightHelper);
```

# Blenderの3DモデルをThree.jsでブラウザに表示することもできる

Blenderでモデリングした3Dモデルを、Three.jsでブラウザに表示することもできる。

1. Blenderでモデルを作成する
2. 作成したモデルをglTF形式のファイルにエクスポートする
3. Three.jsにて、エクスポートしたglTFファイルをロードする

参考：[Blenderで作成した3Dモデルを、Three.jsでブラウザに表示する](https://qiita.com/nannany_hey/items/c92d9f05588c751077b1)




# 最後に
Blenderを使って3DCGモデリングをしていたところから、もっと楽に大量のオブジェクトを発生させたり数値によって細かいズレを表現したりしてみたいと思うようになり、three.jsに手を出してみました。

JSも勉強したてのレベルでどこまで出来るかわかりませんが、まずはいろいろやってみようと思います。
（学んだことから追記していく予定）