Three.js図解1: マテリアルの比較

# はじめに
現在、[Three.jsの勉強中](https://qiita.com/skm_bnn/items/fe4c17ac65ce5c4a89db)です。その際に、詳細を調べていると、色々な描画スタイルが見つかります。この記事では、各スタイルを実際に比較して違いを理解していきたいと思います。

# マテリアルの比較
今回の記事ではマテリアルの比較をしていきます。[この記事](https://qiita.com/skm_bnn/items/9bd86ab51a829efc43ef)にて、単純な立方体のアニメーションを描画しました。この立方体のマテリアル(材質)を比較していきます。

## ソースコードのひな形
次のソースコードを使用します。

### index.html
```html: index.html
<!DOCTYPE html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>Three.jsの図解1</title>
    <style>
      body {
        margin: 0;
      }
    </style>

    <!-- CDNからThree.jsのインポート -->
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@v0.159.0/build/three.module.js",
          "three/addons/": "https://unpkg.com/three@v0.159.0/examples/jsm/"
        }
      }
    </script>
  </head>

  <body>
    <!-- three.jsを使ったシーンのインポート -->
    <script type="module" src="./main.js"></script>
  </body>

</html>
```

### main.js
```描画オブジェクトの実装``` に注目してください。実際のコードでは、```new THREE.マテリアル({ color: 0x00ff00 });``` の ```マテリアル``` という箇所を変更します。```ライトの実装``` については後日に改めてしっかりとまとめたいと思います。

```js: main.js (ひな形)
import * as THREE from 'three';

/* シーンの実装 */
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);           // HTMLへの追加

/* ライトの実装 */
const color = 0xFFFFFF;                                     // 光の色
const intensity = 3;                                        // 光の強度
const light = new THREE.DirectionalLight(color, intensity); // ライトの生成
light.position.set(0, 0, 5);                                // ライトの配置
scene.add(light);                                           // シーンへの追加

/* 描画オブジェクトの実装 */
const geometry = new THREE.BoxGeometry(1, 1, 1);                    // ジオメトリの生成
const material = new THREE.マテリアル({ 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;  // x軸方向
  cube.rotation.y += 0.01;  // y軸方向

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

animate(); // アニメーション関数の実行
```

## ```MeshBasicMaterial```
単純なシェーディングの方法でジオメトリを描画するためのマテリアルです。光の影響を受けないことが特徴です。

![動作結果.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/f1aed0af-19c1-2cbf-a0ed-3e6b4858d662.gif)


## ```MeshToonMaterial```
トゥーンシェーディングを実現するマテリアルです。光に反射している箇所と影がついている箇所に二分された表現が特徴です。

![MeshToonMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/ac194526-0a7a-e5b7-956a-f70f8a0d9a8b.gif)

## ```MeshLambertMaterial```
表面が鏡面ハイライトや光沢ではないもの専用のマテリアルです。従って、木材にニスを塗ったような光沢は表現できません。```MeshPhongmaterial```や```MeshStandardmaterial```、```MeshPhysicalmaterial```と比べると精度が低いですが、それらより処理が軽いことが特徴です。

![MeshLambertMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/871557be-5944-687a-2df0-ffb6fdc06199.gif)


## ```MeshPhongMaterial```
鏡面ハイライトや光沢を表現できるマテリアルです。```MeshStandardmaterial```、```MeshPhysicalmaterial```と比べると精度が低いですが、それらより処理が軽いことが特徴です。

![MeshPhongMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/f25ef10d-9f85-0b45-2020-813d91711992.gif)


## ```MeshPhysicalMaterial```
```MeshStandardmaterial``` の拡張機能であり、より高度な物理ベースのレンダリングプロパティを提供します。グラフィックの表現が富んでいるため、処理が重くなりやすいことが特徴です。

![MeshPhysicalMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/589d3a72-8f13-b8ed-4312-55f9bbe288e9.gif)


## ```MeshStandardMaterial```
粗めの金属を表現できることがマテリアルです。```MeshLambertmaterial``` や ```MeshPhongmaterial``` よりも正確で現実的な外観の結果が得られることが特徴です。

![MeshStandardMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/4464085f-05a8-bc08-de02-d453b5cb244a.gif)


# 参考
- シーンの作成

https://threejs.org/docs/#manual/en/introduction/Creating-a-scene

- MeshBasicMaterial

https://threejs.org/docs/#api/en/materials/MeshBasicMaterial

- MeshToonMaterial

https://threejs.org/docs/#api/en/materials/MeshToonMaterial

- MeshLambertMaterial

https://threejs.org/docs/#api/en/materials/MeshLambertMaterial

- MeshPhongMaterial

https://threejs.org/docs/#api/en/materials/MeshPhongMaterial

- MeshPhysicalMaterial

https://threejs.org/docs/index.html#api/en/materials/MeshPhysicalMaterial

- MeshStandardMaterial

https://threejs.org/docs/#api/en/materials/MeshStandardMaterial