2018年5月、Oculus Go(オキュラス・ゴー)が発売されました。Oculus GoはPCやスマートフォンを必要とせず、単体でVR(バーチャルリアリティ、仮想現実)が楽しめるスタンドアロン型VR HMD(ヘッドマウントディスプレイ)です。価格も¥23,800からと比較的安価なため、日本でも購入者が増えこれまでと比べ一気にVR環境が広がりました

VR環境の普及に伴い、ウェブコンテンツにおいてもVR対応へのニーズが増えています。ウェブブラウザにはWebVR APIが策定されており、これを使用することでブラウザでもVR体験が可能です。

※ WebVR APIの策定はv1.1で停止しており、今後VR以外にもAR(拡張現実)やMR(複合現実)といったXR(◯◯現実)を総合的に扱うWebXR Device APIに統合されるようです

最新のThree.jsであれば、既存のThree.jsコンテンツをWebVRに対応するのは驚くほど簡単です。スクリプトを4行変更するだけですべてのWebVR処理をThree.js内で完結してくれます。デモを作成したのでご覧ください。

※ この記事のソースコードは 2018年8月時点で最新のThree.js(r95)によって書かれています

Three.jsでのWebVRの対応方法

まずは通常通りThree.jsコンテンツを作成しましょう。本記事ではThree.js自体の説明は割愛しますが、基本的な使い方はICS MEDIAのThree.js入門サイトで学べます。作成したThree.jsコンテンツに対し、以下の変更を加えてWebVRに対応します。

1.WebVRを有効にする

最初に、Three.jsのレンダラー(THREE.WebGLRenderer)に対してWebVRが有効になるようフラグを設定します。

// レンダラーのWebVR設定を有効にする
renderer.vr.enabled = true;

2.アニメーションのループを設定する

次に、レンダラーに対して毎フレーム実行されるループ関数を登録します。

// レンダラーにループ関数を登録
renderer.setAnimationLoop(tick);

通常は毎フレーム実行するループ関数をWindowオブジェクトのrequestAnimationFrame()メソッドに設定します。一方、WebVRではHMDデバイスに対応したVRDisplayオブジェクトのrequestAnimationFrame()メソッドに対して設定する必要があります。ループ関数をThree.jsのレンダラーのsetAnimationLoop()メソッドに登録することで、表示状態に応じてThree.jsがこの2つを適切にスイッチしてくれます。Windowオブジェクトに設定したrequestAnimationFrame()メソッドは削除してください。

以上でThree.jsのWebVR対応は完了です。追加で下記の対応を行います。

3.WebVRの判定、開始ボタンを表示する

WebVRの表示は、クリックやタップなどのユーザー操作を起点としてのみ開始できます。WebVRコンテンツにはこのためのUIが必要となります。また、WebVR APIに対応した環境かどうかの判定も必要です。

この2つの機能を実現できるWebVR.jsというヘルパーがThree.jsのサンプルとして提供されています。WebVR.jsファイルが提供するWEBVR.createButton()メソッドでボタン要素を作成し、DOMに追加します。

// WebVRの開始ボタンをDOMに追加
container.appendChild(WEBVR.createButton(renderer));

WebVRを表示できる環境の場合は「ENTER VR」ボタンが表示され、クリックするとWebVRの表示を開始できるようになります。

4.ポリフィルを追加する

WebVR RocksにてWebVR APIに対応しているブラウザを確認できます。2018年8月現在、対応環境は少なく、とくにiOSでは対応ブラウザが存在しない状況です。より多くのユーザーに体験してもらうためにWebVR APIのポリフィルを使用しましょう。

webvr-polyfill.jsを読み込み、スクリプト冒頭でnew WebVRPolyfill()と記述すればポリフィルを適用できます。

// ポリフィルを使用
const polyfill = new WebVRPolyfill();

以上の4ステップでThree.jsのコンテンツをWebVR対応できました。3D空間内を見回すだけのコンテンツであれば簡単に対応できることがわかります。

開発TIPS

Three.jsの既存コンテンツをWebVR対応する上で注意するポイントを紹介します。

指定したcanvas以外の要素は表示されない

WebVR APIはcanvas要素をHMDに表示する機能です。そのため、指定したcanvas以外のcanvas要素や他のDOM要素は画面に表示されません。VRに2次元のUIなどを表示したい場合はThree.jsと同じcanvasレイヤーに描画する必要があります。たとえば、dat.GUI for VRを使えばThree.js空間上にUIを表示できます。

カメラのFOVに注意

Three.jsのカメラ(THREE.PerspectiveCamera)に設定したFOV(画角)値はVR表示時には無視され、HMDデバイスのFOV値が使用されます。極端なFOV値でコンテンツを作成すると、PCで表示したときとVR HMDで表示した時の差が大きくなり、意図しない見た目になることがあります。最初からカメラのFOV値を90°くらいで作っておきましょう。

カメラ座標を変更したい場合

Three.jsでカメラを動かすときはcamerapositionプロパティを使いますが、WebVRではcamerapositionプロパティは無視されます。この方法では座標の変更ができません。

// WebVRではカメラの座標を変更できない
// camera.position.x = 100;

代わりに、カメラ用の空コンテナを作り、カメラではなくコンテナに対して座標を設定します。カメラ用コンテナをsceneに追加することも忘れないでください。

// カメラ用のコンテナを作成
const cameraContainer = new THREE.Object3D();

// カメラをコンテナに追加
cameraContainer.add(camera);

// カメラ用コンテナをsceneに追加
scene.add(cameraContainer);

// コンテナに対して座標を設定することでカメラの座標を変更可能
cameraContainer.position.x = 100;

※ カメラを動かす場合は、ユーザーがVR酔いしないよう充分に注意してください

終わりに

Oculus Goの登場でVR環境の普及が加速し、その波はウェブ業界にも押し寄せてきています。Three.jsを使えば簡単にVR対応できるので、みなさんのウェブコンテンツもぜひVRで表示してみませんか? HMDをかぶって自分で作成した3Dコンテンツ内に入り込んだときの感動はひとしおです。

ICS MEDIAではThree.jsの入門サイトを公開しています。まだThree.jsをさわったことがない方もこの機会にチャレンジしてみましょう。