three.jsで3Dを作りたい！

#はじめに
WebGLのコンテンツを作りたくて、
なんとなく取っ付きやすそうな感じがしたthree.jsに挑戦してみました。
three.jsはjsさえ読めればなんとか書けるくらいの難易度っぽい。
とりあえず、立方体の表示とマウス操作を目標にいざトライ！

これが目標！!
![サンプル.png](https://qiita-image-store.s3.amazonaws.com/0/65924/2f270914-3725-f86f-5f4d-a282f5120000.png)


#まずは下準備
##three.jsを用意
下記ページからthree.js一式をダウンロードします。
[http://threejs.org/](http://threejs.org/)
※画面左のナビゲーションの「download」からまとめてダウンロードできます。

##HTMLとか
ここは本題ではないのでサクッといきます。

```sample.html
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Threejsの練習</title>
	<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
	<style type="text/css">
		html, body {
			margin: 0;
			padding: 0;
		}
	</style>
	<script src="js/jquery-2.1.3.min.js"></script>
	<script src="js/three.min.js"></script>
	<script src="js/OrbitControls.js"></script>
	<script>
		{ここに3Dを表現する記述を書いていくよ〜！}
	</script>
</body>
</html>
```

#three.jsの書き方
three.jsは下記の３ステップの記述で画面を表示できる模様。
・シーン（箱庭）
・オブジェクト（カメラとかライトとか立方体とか！）
・レンダラー（描画）

ソースを見ながらの方がわかりやすいと思うので、
まずはソースを書いてしまいます。

```sample.js
// シーン
var scene = new THREE.Scene();

// レンダラー
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

// カメラ
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(0, 0, 100);

// マウスコントロール
var controls = new THREE.OrbitControls(camera);

// ライト
var directionalLight = new THREE.DirectionalLight('#aaaaff', 1);
directionalLight.position.set(0, 10, 10);
scene.add(directionalLight);

// キューブ
var geometry = new THREE.BoxGeometry(12,12,12);
var material = new THREE.MeshPhongMaterial( { color: '#ffffff' } );
var cube = new THREE.Mesh( geometry, material );
cube.position.set(0, 0, 0);
scene.add( cube );

// レンダリング
function render() {
	requestAnimationFrame(render);
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	controls.update();
	renderer.render(scene, camera);
}
render();
```
以上！
これを実行すれば画面が見れるはずです。

では、上記のソースの説明をしていきます。


##シーンとレンダラー
```
// シーン
var scene = new THREE.Scene();
// レンダラー
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
```
`var scene =〜`
この行だけでシーン（箱庭）ができます。
そして、その下からの記述でレンダラーを作成しています。
レンダラーはいわば、絵を書くためのキャンバスみたいなものですね。
これがないと3Dの画像を表示できないのでとっても大事

##カメラ

```
//カメラオブジェクトを新規作成
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );

//カメラのポジションを設定
camera.position.set(0, 0, 100);
```
読んだまんまカメラです。
カメラを通した部分が3D画像として表示されます。
もちろんカメラの角度も変更可能（今回はやってませんが・・・

##キューブ（立方体）

```
// キューブのオブジェクトを作成
var geometry = new THREE.BoxGeometry(12,12,12);
// キューブの表面設定
var material = new THREE.MeshPhongMaterial( { color: '#ffffff' } );
// 上記２つを合体
var cube = new THREE.Mesh( geometry, material );
// 作ったキューブの表示位置を設定
cube.position.set(0, 0, 0);
// シーンにキューブを追加
scene.add( cube );
```
とりあえず、被写体がないことには始まらない。
`var geometry =〜`の行で立方体を作成し、
`var material =〜`の行で表面の色を設定しています。
いわば骨と皮みたいな感じ。
`var cube =〜`で上記２つを合体しています。

##ライト

```
// ライトのオブジェクトを作成（色も指定）
var directionalLight = new THREE.DirectionalLight('#aaaaff', 1);
// ライトの表示位置を設定
directionalLight.position.set(0, 10, 10);
// ライトをシーンに追加
scene.add(directionalLight);
```
ライトです。
光がないと何も見えません。まっくら。
もちろんキューブも見えません。
作り方のルールはキューブとほぼ同じですね。


##レンダリング（画面描画）

```
// レンダリング処理
function render() {
	requestAnimationFrame(render);
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	controls.update();
	renderer.render(scene, camera);
}
render();
```
シーンに設定してきたものを画像として書き出す処理です。
`renderer.render(scene, camera);`
この部分で画面に画像を描画する命令を出してます。

ちなみに他の部分はちょっとしたアニメーション用の記述になってます。
ポイントは`requestAnimationFrame`を呼び出しているところですかね。
この関数に作ったばかりのrender関数を渡すことによって、
アニメーションを表現しています。

※アニメーションするなんていってなかったけど、
なんか出来そうなので急遽追加です！

要するに、上記の記述では、
アニメーションの1フレームごとに、
キューブをちょっとずつ回転するような感じの記述になっています。

##マウスでの視点変更
さて、最初に書いたコードで、
ここまでで触れてない記述がちょこっとだけあります。
その部分がマウス操作を受け付けるための記述になってます。

```
// マウスコントロール
var controls = new THREE.OrbitControls(camera);　←ここ

~~

function render() {
	requestAnimationFrame(render);
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	controls.update();　←ここ
	renderer.render(scene, camera);
}
render();
```
←で指してる部分ですね。

上記の他に`OrbitControls.js`というプラグインを読み込みましょう。
このプラグインは始めにダウンロードしたthree.jsのパッケージの中に入ってます。
`three.js-master/example/js/controls/OrbitControls.js`

上記の追加をするだけでマウスでの視点変更ができるようになります！


#まとめ
ざっと一気に走り抜けましたが、
これで簡単な3Dのデモが作成できたと思います。

とりあえずの表示であれば簡単に出来たのですが、
突き詰めるとかなり細かいことまで出来るようなので、使いこなしていきたいですね！

下記に今回のデモにちょっと手を入れたものをアップしています。
今回初めてCodePen使ってみたけど、結構いいかも！

[http://codepen.io/kurokuma/pen/emggzm/](http://codepen.io/kurokuma/pen/emggzm/)