カブクで主にThree.jsを担当していたあんどうです。
なぜ「担当していた」なのか?それは最近Go言語でふにゃふにゃするばかりで全然Three.jsを触れていないからです。Three.jsを触りたい、Three.jsで遊びたい、そんな気持ちが抑えきれないので、今日はThree.jsでVRする話をします。
Three.jsでVR
3Dに関係するものならだいたいなんでもそろうThree.js、当然VRも簡単です。そうThree.jsならね。
<script src="/examples/js/vr/WebVR.js"></script>
まずexamplesディレクトリの中にあるWebVR.jsを読み込みます。WebVR APIとWebXR Device APIに関係するコードの大部分はこのWebVR.js内に収められています。WebVR APIはDeprecatedになっている古い仕様ですが、現時点ではWebXR Device APIが実装されているのはGoogle Chromeだけで、市販のVR HMDも含めそれ以外のブラウザではまだWebVR APIしか利用できません。
document.body.appendChild(WEBVR.createButton(renderer));
次にWEBVR.createButton
を使用して「Enter VR」ボタンを作成します。
renderer.vr.enabled = true;
また、合わせてレンダラのVR機能を有効にしておきます。後ほど確認しますが、render.vr
はWebVRManager
もしくはWebXRManager
のインスタンスです。
renderer.setAnimationLoop(function() {
renderer.render(scene, camera);
});
最後に通常であればwindow.requestAnimationFrame()
を使用しているであろう描画ループをrenderer.setAnimationLoop
を使用するように書き換えます。
これで3DシーンのVR化は完了です。では表示を確認してみましょう。
上がVR開始前のスクリーンショット、下がVR開始後のスクリーンショットです。下のスクリーンショットでは視差を持った画像に二分割され、それぞれ樽型に変形されていることが見て取れるでしょう。また上の状態では端末の角度を変更しても表示内容に変更はありませんが、下の状態では端末の角度を変えるとそれに合わせてシーン内のカメラの角度も変わります。
さすがThree.jsというしかない簡単さです。
実装の確認
せっかくなので簡単に実装も確認してみましょう。WebVR.jsはAPIの対応状況によってWebVR APIとWebXR Device APIを切り替えて使用しますが、このエントリでは後者のWebXR Device APIを使用しているパスだけを確認することにします。
WebGLRenderer
var vr = null;
if (typeof navigator !== 'undefined') {
vr = ('xr' in navigator) ? new WebXRManager(_this) : new WebVRManager(_this);
}
this.vr = vr;
WebXR Device APIが利用できる環境ではnavigator
にxr
プロパティが存在するので、それによってWebGLRenderer
でWebXRManager
とWebVRManager
のどちらを使用するかを決定しています。
WebXRManager
function WebXRManager(renderer) {
var gl = renderer.context;
var device = null;
var session = null;
var frameOfReference = null;
var frameOfReferenceType = 'stage';
var pose = null;
// ...
}
WebXRManager
はWebXR Device APIのXRDevice
(外部HMDやXR対応スマートフォンなどのXRデバイス)、XRSession
(XRデバイスとの接続情報)、XRFrameOfReference
(XRデバイスの使用する基準系)、XRDevicePose
(XRデバイスの姿勢、位置と角度)などを管理しています。
WebVR
ここでのWebVR
は仕様名ではなくWebVR.jsで定義されているオブジェクトです。ここでWebXR Device APIに関係するすべての処理を行います。例えば、XRデバイスを取得して、機能を確認し、セッションを開始するまでの処理として以下のようなコードが含まれています。
navigator.xr.requestDevice().then(function(device) {
device.supportsSession({immersive: true})
.then(function() { showEnterXR(device); })
.catch(showVRNotFound);
}).catch(showVRNotFound);
device.requestSession({immersive: true}).then(onSessionStarted);
見かけないオブジェクトやメソッドが並んでいるかと思いますが、興味のある方は技術書典5の「か71」 にくればいいことがあるかもしれません。
最後に
カブクではThree.jsを使ったビューアーの開発や、Go言語で機械図面をふにゃふにゃしたい開発者を募集しています。