Three.jsのためのBlender入門

人生初アドベントカレンダーです。よろしくおねがいします。

# 概要
Three.jsユーザーの皆さん、「**Blender**」、使っていますでしょうか？
BlenderはThree.jsと同じくオープンソースで開発されている**統合型3DCGツールです。**モデリングからコンポジットまで、CG作りはこれ一本で事足ります！

 今年の夏頃v2.8の大型アップデートがリリースされ、glTFのインポート/エクスポートがデフォルトでできるようになったりと、Web業界でも非常に熱いツールになってきたのではないかと思います。

 ただ、Blender、統合型ツールということもあり、**機能がいっぱいでこれから始める方には少しとっつきにくい**ところもあると思います。

 というわけで今回は**Three.jsユーザー目線**でBlenderのおおまかな使い方を紹介したいと思います。

- **最低限の操作ができる**、
- **モデルを配置することができる**
- **モデルのインポート/エクスポートができる**

を目標に頑張りましょう！
ちなみに今回はショートカットキーベースで解説したいと思います。

# インストール
インストールはこちらから。
https://www.blender.org/download/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/c554d7a2-dfa5-d110-3b66-7bda1f69d417.png)

# 初期設定

Blenderはデフォルトは英語ですが、今回は日本語で解説したいと思います。
ので、設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/331feef3-2cf4-efce-accd-821a98b7c709.png)
左上の`Edit` > `Preferences`ウィンドウを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/21a8ebfd-594e-de8c-3370-e7c523cc0132.png)
`Interface` > `Translation`をチェック。
`Translation` > `Language`を`Japanese`に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/9c77391f-a7e5-64d4-ca8b-af18af7729fd.png)
この３つのチェックですが、これは言語の変更をどこまでするか設定できます。

|項目||
|:--|--:|
|Tooltips|UIをホバーしたときに出る解説を翻訳|
|Interface|UI自体を翻訳|
|NewData|作成されるオブジェクト名を翻訳|

**NewDataのチェックは外しておいたほうがいいですね**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/80785303-fdc8-7073-ff6d-dfb33e25b7af.png" width="70%">

# 基本操作

|項目|キー|備考|
|:--|--:|:-------------------------------------------|
|移動|	G|移動中にX,Y,Zキーを押すと、その軸の移動ができます。二回軸を押すとローカル座標においての移動ができます。また、移動中に数字をキー入力するとその量移動されます|
|回転|	R|	上と同じ|
|拡大縮小|	S| 上と同じ|
|オブジェクトの追加| Shift+A|　Blenderで物を追加したいときは大体これです。|
|オブジェクトの複製| Shift+D| これで大体のものは複製できます。|
|削除| XまたはDel| オブジェクトを消します。|
|モード変更| tab|オブジェクトモード、編集モードの切り替えができます。|

## 操作モードについて
Blenderには`オブジェクトモード`と`編集モード`の２つのモードがあります。
これらは`Tabキー`で切り替えることができるので覚えておきましょう。

- オブジェクトモード
    - オブジェクト自体の位置や回転を編集する。
- 編集モード
    - モデルの頂点などを編集したりする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/6911b201-06c8-ec33-7c89-56ade2404966.png)

# オブジェクトの作成
例えばThree.jsで、こんなシーンがあったとします。

```typescript

let group = new THREE.Group();
group.name = 'Root'

//create box
let boxGeo = new THREE.BoxBufferGeometry( 2, 2, 2 );
let boxMat = new THREE.MeshStandardMaterial({
	color: new THREE.Color( 1, 0, 0 ),
	metalness: 0	
});

let box = new THREE.Mesh( boxGeo, boxMat );
box.name = "RedBox";
box.position.set( -2, 0, 0 );
group.add( box );

//create sphere
let sphereGeo = new THREE.SphereGeometry( 1, 10, 10 );
let sphereMat = new THREE.MeshStandardMaterial({
	color: new THREE.Color( 0, 0, 1 )
})

let sphere = new THREE.Mesh( sphereGeo, sphereMat );
sphere.name = "BlueSphere";
sphere.position.set( 2, 0, 0 );
group.add( sphere )

```

こんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/637298d4-7636-67e9-fccb-f06368ab594c.png)


今度はこれをBlenderで再現してみたいと思います。

### 立方体を作成

### メッシュを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/c65843db-c7b9-90df-c1e6-16cdcb798c79.png)

`Ctrl + A`キーでオブジェクトの追加ができます。`Mesh` > `立方体`で立方体を追加します。

### 位置を調整

立方体の位置を調整します。3Dビュアー上で移動しても良いですが、正確に移動したい場合は画面右にあるプロパティエディタの`トランスフォーム`から数値を入力すると良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/2860351a-ff60-b525-9826-3af0605f647d.png)

##### 座標系について
Three.js(WebGL)は**Y-upの右手座標**ですが、Blenderは ~~**左手座標のうえ、YとZが逆**というちょっと特殊な座標系~~ **Z-upの右手座標系**です。けど、そのへんは**glTFエクスポーターがよしなにやってくれる**ので、とりあえずBlender上では**右が+Xで上が+Z**でシーンを作っておけばOKです！

2019/12/03 - 座標系について@cx20さんより[コメント](https://qiita.com/ukonpower/items/7545337b3d2963d44ce2#comment-6804fc6d968ec8b0c7ab)をいただき修正いたしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/b5bde3b1-7b64-695e-1894-6e887144d8d5.png" width="70%">

### マテリアルを編集
マテリアルを編集するには画面右の`プロパティエディタ` > `マテリアルタブ`を開きます。
`新規`ボタンを押すと`プリンシプルBSDF`マテリアルが作成されます。`プリンシプルBSDF`は2.79から追加されたPBRマテリアルでglTFともとても相性が良く、これ一択です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/56fd95e8-602f-727f-f1a3-4e82acde9ca6.png)

ベースカラーの色を設定し、立方体の設置は完了です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/9a9c8621-fcc1-f52c-03ec-7a0576a9a4c4.png)

ちなみに3Dビュー上で`Zキー`を押すと3Dビュアーのオブジェクト表示方法を選択でき、`ルック開発`を選択するとオブジェクトのマテリアルを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/1726b6bf-f99b-e915-71db-744c884adc21.png)

### 球体を追加

球体は`Shift + A` > `メッシュ` > `UV球`で追加することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/27e0289e-e4a7-b4c1-c8dd-9902a46c18f2.png)

立方体と同じく位置を調整してマテリアルを作成しましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/6b33f8dd-7383-6bea-1cce-e72aaed2adb6.png)

## Blender上での親子関係

Three.jsのシーンを作る際にこんな部分があります。

```typescript
let group = new THREE.Group();

...略...

group.add( box );

...略...

group.add( sphere )

this.scene.add( group );
```

Three.jsのデベロッパーツールで見てみるとこんなツリーになっていますね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/48a97e58-afbb-1a31-46d0-6ca7d635c5ca.png)


`THREE.Group`は`THREE.Object3D`とほぼ同じで、空っぽのオブジェクトです。これと同等のBlender上でのオブジェクトは`Empty`です。

### Emptyの追加

3Dビュー上で`Shift + Aキー` > `エンプティ`を選択します。`十字`や`矢印`などありますが、これはBlender上での表示方法なので好きなもので大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/1012f49b-1e5f-531d-5086-ed3c7066db60.png)

追加しまして、画面右側のアウトライナーを見てみると、まだThree.jsのシーンとは違います。
`Cube`と`Sphere`が`Empty`と同じ階層にいるからです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/ffde277e-99ab-6177-4489-3c8c8489f056.png)

### 親子関係の設定

Three.jsでいう`THREE.Object3D.add()`はBlenderでは**親子関係の設定で実現**できます。

親子関係を設定するには、まず**子要素にしたいものをすべて選択**した上で**最後に親オブジェクトを選択**した状態にします。
（子要素を選択状態に、親要素をアクティブ状態にする）

その状態で`Cltr + P`キーを押します。
`ペアレント対象`の`オブジェクト`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/b2adcacf-fefe-bbe1-dcc4-c536b740e2f8.png)

すると3Dビュアー上ではEmptyに向かって子オブジェクトから点線が表示され、画面右のアウトライナーではEmptyの下階層にオブジェクトが移動したかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/161dc489-a39a-1fcb-e550-ac197d921ace.png)

### 親子関係の解消

親子関係を解消したい場合は`Alt + P`キーを押し、親子関係をクリアします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/2714e6d4-a6ff-d8b1-e4b4-76a9f87560bc.png)

なお、Blenderのショートカットキーにおいて、`Ctrl`キーは基本的に**ポジティブなアクション**(追加、設定など）に使用されます。逆に`Alt`キーは**ネガティブなアクション**（消去、解消など)に使用されます。 
これを覚えておくとショートカットキーを覚えるのが若干楽になります。

## 名前の設定
`THREE.Object3D.getObjectByName`で検索ができるように**オブジェクトの名前もしっかり設定しておきましょう**。
画面右のアウトライナーでオブジェクトをダブルクリックすると変更することができます。プロパティエディタのオブジェクトタブなどからでも変更できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/9414fd07-df09-c1dc-feea-e79fe68775f2.png)

## モデルデータの書き出し

さて、モデルデータを作成することができ、最後に作ったデータをglTFでエクスポートします。

エクスポートするには、まず**エクスポートしたいオブジェクトを選択**し、画面左上の`ファイル` > `エクスポート`>`glTF2.0`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/0fb54e08-3520-d831-83f9-b5f913b517ab.png)

エクスポート画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/bfe5b289-0fe5-f99e-05d9-1b8cf507f021.png)

画面左下のエクスポート設定はいつもだいたいこんな感じです。
普段はマテリアルはほぼThree.jsで作成するのであんまり書き出さないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/aaa65c6d-9389-e03f-dce4-69a02df7aec8.png)

ちなみに、Blnederでマテリアルの**カラーなどにテクスチャを割り当てておくと**、マテリアルを書き出す際、なんと**画像も一緒に書き出してくれます**。Three.jsのglTFローダーもしっかり画像を読み込んでくれ、デモづくりなどにとても便利です。

## 完成...??

ようやっと3Dモデルデータの作成ができました。Three.jsで読み込んでみるとこんな感じになりました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/ece610e1-cc08-adce-3ec4-3ed5dbc057bd.png)

あれ....なんか違う...(汗

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/82c88e3a-b1d7-2662-03b3-c136d56f4009.png)

なんかBlender側はなんか明るい...そしてゴツゴツしてますよね...

### なんで色違うの？？
色の明るさが違うのはマテリアルのパラメータを比較したところ、ただ`THREE.MeshStandardMaterial`は`Metalness'が**デフォルトで0.5に**設定されているせいでした。

### なんでゴツゴツしてるの？？
Sphereオブジェクトをスムースシェーディングに設定していないからです（完全に忘れてた）

Three.jsではメッシュは**初期状態ではスムースシェーディングになっています**。`THREE.Material.flatShading`を`true`にするとフラットシェーディングになりますが、Blenderで作成したメッシュは**初期状態でフラットシェーディングになっています**。

Blenderでシェーディングを変える場合はまず、`Tab`キーを押して編集モードに入ります。
そしてシェーディングを変更したい面を選択します。全選択する場合は`A`キーを押しましょう。
3Dビュー上にある`面`>`スムーズシェード` or `フラットシェード`を選択することでシェーディングを変えることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/4e34eeb7-761c-2513-6579-2697506a76e1.png)

## 完成

メタルネスを0.5に設定、球体をスムースシェーディングにして再度書き出し直し、Three.jsで読み込んだものが以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/78fe35d3-2aee-2884-e3cc-6fe88d07d0f5.png)

無事、Three.jsのシーンづくりをBlender上で行うことができました。
Three.jsデベロッパーツールでシーンを確認してみても、同じオブジェクト構成になっていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/a500d525-e533-be40-28ac-20c69a95bcfb.png)

# 3Dモデルのインポート
インポートは超カンタンで画面左上`ファイル` > `インポート` > `好きな形式`を選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/665d36be-f567-8a5c-4310-f4e75e6796c7.png)

インポート設定はよしなに...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/19b573c2-70e7-6bac-fe58-c6d867d484c0.png)

さっき作成したモデルを選択してみると、無事読み込まれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280075/a7a5ecff-680a-6cd6-a350-0c00dbc73343.png)

# おわり
Three.jsではそれなりに複雑なシーンの作成にはやはり3DCGソフト上での編集は欠かせないと思います。
自分的にはBlenderはThree.jsと相性抜群だと思うので皆さんも是非使ってみてください！