WebVR - 雪を降らせてみた

この記事は [J2complexed Advent Calendar 2016](http://qiita.com/advent-calendar/2016/j2complexed) の8日目です。
（いつもどおり遅れていますすみません）

クリスマスに雪が降ると雰囲気がありますよね。
でも、寒いのイヤじゃないですか。なので、WebVRで雪を振らせてみようと思います。
WebVRなら雪が降っているのも共有できるし、なによりJavaScriptなら怖くないですね！

# Web Boilerplateを準備
最近は開発をするときにはボイラープレートを検索するようにしてます。楽がしたいので！
やっぱり、ありましたよ。
[WebVR Boilerplate](https://github.com/borismus/webvr-boilerplate)
さくっと準備しましょう。

```bash
$ git clone https://github.com/borismus/webvr-boilerplate.git
$ cd webvr-boilerplate/
$ npm init
$ npm i lite-server
```

## Web Boilerplateが動くか確認
まず、動くか確認するためにlite-serverを入れます。静的ページを動かせれば、なんでもいいですよ。最近はlite-serverを使ってるので、これで説明しますね。

```bash
$ npm init
$ npm i lite-server
```
package.jsonに以下を書き込んでください。

```js
  "scripts": {
    "start": "lite-server"
  },
```
それから、設定のファイルを用意します。

```json:bs-config.json
{
  "port": 8000,
  "files": ["./webvr-boilerplate/**/*.{html,htm,css,js}"],
  "server": { "baseDir": "./webvr-boilerplate" }
}
```

あとは、以下のコマンドを打てば、ブラウザが起動します。

```bash
$ npm run start
```
こんな感じで箱がぐるぐるしてます。でましたか？
![スクリーンショット 2016-12-08 21.16.48.png](https://qiita-image-store.s3.amazonaws.com/0/109382/527f3c01-f48c-0709-ca96-cdcc221d6227.png)

## ソースを確認
index.htmlを見てみましょう。なんてことはありません。three.jsで書いてるんですね。
WebVRとか、難しそうとか思ってたけど、three.jsなら怖くないですね。

scriptタグの中身を順に見ていくと、こんな記述を見つけると思います。

```js
var controls = new THREE.VRControls(camera);
controls.standing = true;
controls.standing = true;

// Apply VR stereo rendering to renderer.
var effect = new THREE.VREffect(renderer);
effect.setSize(window.innerWidth, window.innerHeight);
```

VRとか変数についていたりするのは、触らずにそっとしておきましょう。
まとめたり、整理整頓したりすると、こんな感じでしょうか。

```js
// レンダラをつくる
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

// Sceneをつくる
var scene = new THREE.Scene();
// Cameraをつくる
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 10, 30000);

// VR用のコントローラをつくる
var controls = new THREE.VRControls(camera);
controls.standing = true;
controls.standing = true;
// VR用のエフェクトをつくる
var effect = new THREE.VREffect(renderer);
effect.setSize(window.innerWidth, window.innerHeight);

var vrDisplay;

// VRマネージャをつくる
var params = {
  hideButton: false,
  isUndistorted: false
};
var manager = new WebVRManager(renderer, effect, params);

// このなかでマテリアルをつくったりする
setupStage();

window.addEventListener('resize', onResize, true);
window.addEventListener('vrdisplaypresentchange', onResize, true);

// このなかでアニメーションさせる
function animate(timestamp) {
  controls.update();
  manager.render(scene, camera, timestamp);
  effect.render(scene, camera);

  vrDisplay.requestAnimationFrame(animate);
}

function onResize(e) {
  effect.setSize(window.innerWidth, window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
}

function setupStage() {
  navigator.getVRDisplays().then(function(displays) {
    if (displays.length > 0) {
      vrDisplay = displays[0];
      vrDisplay.requestAnimationFrame(animate);
    }
  });
}
```
あとは雪が降るアニメーションをつくるだけなので、省略します。

# 公開作業
Herokuにアップして公開をしたいと思います。Herokuに静的ページをアップする方法はそこらで説明されていると思うので、簡単な説明のみにしておきます。
まず、以下をダウンロードします。

```bash
$ git clone https://github.com/nulltask/heroku-static-provider.git webvr-snow
```
その次に、Herokuのappを作っておきます。そしたら、Herokuにログインしてください。

```bash
$ heroku login
```

あとは、Herokuに載っているとおりにコマンドを入力します。

```bash
$ cd my-project/
$ git init
$ heroku git:remote -a webvr-snow
$ git add .
$ git commit -am "make it better"
$ git push heroku master
```

できました！
![snow.gif](https://qiita-image-store.s3.amazonaws.com/0/109382/202165ca-d009-1c00-e5d8-48655d7a503a.gif)

[WebVR Snow](https://webvr-snow.herokuapp.com/)
※ スマホで見てほしいです

雪の結晶はこちらから頂きました。ありがとうございます！
[雪の結晶素材 ｜  シルエットデザイン](http://kage-design.com/wp/?p=113)

# まとめ
いかがでしょうか、これでロマンチックなクリスマスを迎えられるのではないでしょうか。（VRだけどね）