CrossRoad

AR、MR、VR、Babylon.jsを中心とした技術ブログ。 If you're non-Japanese native guys, check "English" category.

Babylon.jsでVRMモデルを読み込み、Oculus Questで表示させるまでの手順をまとめました

最近、vrmという規格に興味があって調べていたところ、株式会社バーチャルキャストがBabylon.jsに対応したbabylon-vrm-loaderを公開したことを知りました。

VRM は Unity 専用じゃない!ブラウザで VRM 表示出来るものを作りました! | VirtualCast Blog

GitHub - virtual-cast/babylon-vrm-loader: glTF VRM extension Loader for babylon.js

そこで、今回はこれを元にBabylon.jsのVRモードを追加し、発売されたばかりのOculus Questで見るまでの手順を紹介します。

確認した環境
* Babylon.js 4.0.3

1. 今回使う技術分野について

1.1 VRM

ドワンゴが発表した人型3Dモデルに関する共通フォーマットです。詳細はこちらをご覧ください。

「VRM」とは? そのメリットや対応アプリなど情報まとめ | MoguraVR News - VRの「いま」を掘りだすニュースメディア

VRM

1.2 Babylon.js

Web上で3DCGの表現ができるライブラリです。

Babylon.js: Powerful, Beautiful, Simple, Open - Web-Based 3D At Its Best

参考までに、去年から色々と調べていた内容は下記の通りです。

babylonjs カテゴリーの記事一覧 - CrossRoad

2. 環境構築手順

大まかな手順は以下の通りです。

(1) babylon-vrm-loaderをビルド

(2) VRで動かすための機能を追加

(3) サーバ公開の設定

2.0 Node.js/npm/yarnのインストール

(インストール済みの方は飛ばして、2.1に進んでください)

概要、および必要な手順は以下を参照ください。

Node.js / npm をインストール (Mac環境) - Qiita

yarnを使ってみた - Qiita

2.1 babylon-vrm-loaderをビルド

ここからソースコードを取得します。

GitHub - virtual-cast/babylon-vrm-loader: glTF VRM extension Loader for babylon.js

Readmeに沿ってターミナルから、 bash yarn build を実行してビルド、bash yarn debug を実行するだけです。

しかし、なぜか私の環境では大量のエラーが出てそうなりませんでした。本来ならばpackage.jsonの中に書かれたパッケージを取得して加えてくれるはずなのですが。

このあたり、まだ私のnpmに関する理解が浅いので、今回はエラーが出るたびに該当するパッケージを入れるという作業を繰り返しました。最終的にこのようなコマンドを入力することでビルドを通しました。

$ npm install --save-dev ts-loader
$ npm install --save-dev typescript  
$ npm install --save-dev ts-lib
$ npm install --save-dev @babylonjs/core
$ npm install --save-dev @babylonjs/loaders
$ npm install --save-dev @babylonjs/inspector
$ npm install --save-dev babylon-mtoon-material 
$ npm install --save-dev webpack-dev-server
$ npm install --save-dev webpack 
$ npm install --save-dev webpack-cli

最後にtsconfig.jsonの記述を1箇所修正しました。
(これはChanged js version in tsconfig.jsonでmergeいただいたので、以後は不要です )

ここまでやってから、bash yarn debug とすると、webpackが起動します。Chromeなどのブラウザでbash http://localhost:8080 にアクセスするとこのような画面が開きます。

The result of yarn debug of https://github.com/flushpot1125/babylon-vrm-loader-VR

画面左上に「ファイルを開く」というボタンがあるので、ここからvrmファイルを読み込みます。

手っ取り早く確認するには、株式会社ドワンゴが提供している「ニコニ立体ちゃん」がよいと思います (ダウンロードには、無料の会員登録が必要です)

「ニコニ立体ちゃん (VRM)」 / ニコニ立体 さんの作品 - ニコニ立体

これでこのような画面になります。

Loaded alicia vrm model on babylon-vrm-loader

2.2 VRで動かすための機能を追加

babylon.jsのAPIを使います。 src/test/index.tsの一部を変更します。

//L37付近  vrmモデルを近くで見るために、カメラ位置を移動
   // camera.position = new Vector3(0, 1.2, -3);
    camera.position = new Vector3(0, 1.2, -1.1);
//L100付近  VRモード追加とコントローラの有効化
const vrHelper = scene.createDefaultVRExperience();  //基本的にはこの1行だけでVRモードが利用可能
const leftHand = Mesh.CreateBox("",0.1, scene);
leftHand.scaling.z = 2;
leftHand.isVisible =false;

const rightHand = Mesh.CreateBox("",0.1, scene);
rightHand.scaling.z = 2;
rightHand.isVisible =false;
scene.onBeforeRenderObservable.add(()=>{
      if(vrHelper.webVRCamera.leftController){
          leftHand.position = vrHelper.webVRCamera.leftController.devicePosition.clone();
          leftHand.rotationQuaternion = vrHelper.webVRCamera.leftController.deviceRotationQuaternion.clone();
      }
      if(vrHelper.webVRCamera.rightController){
          rightHand.position = vrHelper.webVRCamera.rightController.devicePosition.clone();
          rightHand.rotationQuaternion = vrHelper.webVRCamera.rightController.deviceRotationQuaternion.clone();
      }

});

bash left/rightHand.isVisible =false;を設定しないと、コントローラをCubeが覆ってしまいます。以前は下記のコードで透明化することで対応できました。

var leftHand = BABYLON.Mesh.CreateBox("",{height:0.1,width:0.1,depth:0.1,faceColors:(1,1,1,0)}, scene);

引用:Babylon.jsでWindows Mixed Realityヘッドセットのアプリを作る方法 - CrossRoad

しかし、今回はES6以降のjavascriptで書いたためか、あるいはBabylon.jsのメジャーバージョンが上がったためか、この方法は使えませんでした。

ここまで書くと、VRモードで動かせるようになります。

2.3 サーバ公開の設定

今回、webサーバとして動かすために、webpackというパッケージを使っています。webpackは基本設定のままだとlocalhostしかアクセスできないので、Oculus Questからアクセスするために、サーバ設定を変更します。

//webpack.config.js
//最終行に以下を追加
    devServer: {
        disableHostCheck: true
    }
 "scripts": {
  //省略
        "debug-lan": "webpack-dev-server --host 0.0.0.0 --config webpack.test.config.js",
//省略
    },

こちらを参考にさせていただきました。

webpack-dev-server に localhost 以外からアクセスできるようにする場合は host: 0.0.0.0 を指定する - 約束の地

3. 動作確認結果

2.2と2.3の修正をしたものを下記におきました。2.1のビルドについては、書いたコマンドを実行してください。

GitHub - flushpot1125/babylon-vrm-loader-VR: Base repo is "https://github.com/virtual-cast/babylon-vrm-loader"

また、vrmファイルは、リポジトリの"test/vrm"と書かれたところに入れます。vrmファイル名は下記を修正してください。

// src/test/index.ts
await SceneLoader.AppendAsync('./vrm/', 'vita.vrm', scene);

Oculus Questで確認しました。先ほどのリポジトリでビルドした状態で、bash yarn debug-lanを実行するとwebpackによるサーバが起動し、Oculus Questからアクセスできます。。

動画の13秒付近にコントローラが写っています。この通りコントローラは2つとも認識され、Raycastを飛ばしてオブジェクトを識別したり、ボタン操作を識別することも可能です。ただし、コントローラの3DモデルはOculus Touchです。

4. 補足

4.1 Oculus Goで動かす場合

Oculus Goでも同じソースコードで動きますが、Oculus Goのコントローラには「戻る」というボタンがないので、Sphereを選択したらexitVR()を呼ぶという処理の追加があるとよいです。

Oculus GoでBabylon.jsを使ったときに、没入型と通常VRモードを切り替える方法 - CrossRoad

具体的には、index.tsにこのようなコードを追加します。

//冒頭のimport
import { ActionManager,ExecuteCodeAction} from '@babylonjs/core/Actions';
//vrHelperの宣言をした直後付近
vrHelper.enableInteractions();
vrHelper.gazeTrackerMesh = BABYLON.Mesh.CreateSphere("sphere1", 4, 0.1, scene);
vrHelper.onControllerMeshLoaded.add((webVRController)=>{});


sphere.actionManager = new BABYLON.ActionManager(scene);
sphere.actionManager.registerAction(
new BABYLON.ExecuteCodeAction({
   trigger: BABYLON.ActionManager.OnPickDownTrigger,},
   function () { 
     console.log("clicked the mesh");
     vrHelper.exitVR();
     scene.getEngine().exitFullscreen();
}));

4.2 参考にした関連技術のリンク

私がまだまだWeb系の勉強が足りないので備忘録のために残しておきます。

私はこの記事の「ES2015 for ES5 Programmers」が一番近い感じでした。

5. おわりに

WebGLでvrmを表示する仕組みはいくつかありますが、冒頭のバーチャルキャストブログで言われているように、Babylon.jsはわりとよいと思います。Questも届いたし、新しいjavascript、Typescriptでの書き方も覚えつつあるので、引き続きvrmとBabylon.jsで色々やってみたいと思います。