この投稿は、WebXR ( WebVR/WebAR ) Advent Calendar 2021 の 20 日目の記事です。
本記事では、Babylon.js を使って WebXR の VR 空間上に 3D ピアノを構築し、ハンド トラッキングを有効にして手で簡単な操作をできるようにする方法を紹介します。
Babylon.js とは
Babylon.js は、3D コンテンツとイマーシブ アプリケーションを簡単に開発できるようにする JavaScript 3D エンジンのフレームワークです。Visual Studio Code などの開発環境で実装することはもちろん、Playground と呼ばれるオンラインのエディターや、Babylon.js Editor という専用のリッチな開発環境を利用してすぐに開発を始めることができます。Babylon.js Editor については、Limes さんが 紹介記事 を書かれているので、興味がある方はぜひご参考ください。
ちなみに、Babylon.js は VR だけでなく AR にも対応しています。WebXR Plane Detection API など新しい機能を使う実装も簡単に行えます。
Babylon.js の AR サポートでキズナアイちゃんを投影 😊
— ユスキィ (Yusuke Hara) (@ms_yuhara) July 3, 2020
<model-viewer> ほどお手軽感はないものの、割と簡単なコーディングでカスタマイズ性は高そう。いまのところ iPhone には対応していないが今後に期待デス。https://t.co/gZZVqZM5bK
©︎ #KizunaAI pic.twitter.com/AIyz3BmFtv
Babylon.js is encroaching the real world...!! 🎉
— ユスキィ (Yusuke Hara) (@ms_yuhara) July 5, 2020
Thanks for really nice features and samples. Here is my demo using WebXR Hit Test and Plain Detection in Babylon.js. pic.twitter.com/zfmDCREoVl
3D ピアノ モデルを構築する
さて、VR 空間でピアノを弾けるようにするためには、ピアノの 3D モデルを構築し、それぞれの鍵盤に対応したピアノの音を出力できるようにする仕組みが必要です。一見複雑に思えますが、マイクロソフトが提供している Babylon.js のチュートリアルにしたがって、スクラッチから簡単にピアノの 3D モデルを準備することができます。
チュートリアル: Babylon.js を使用して WebXR でピアノを構築する
このチュートリアルでは、以下のような 3D ピアノを構築し、WebXR の VR 空間で実際に演奏できるところまでの実装を紹介しています。そのため、本記事で実現したいことの 9 割はこのチュートリアルで完了です 😂
Babylon.js で作成した 3D シーンを WebXR に対応させるにあたり、重要なポイントだけ紹介しておきます。
はじめに、単に WebXR に対応させるだけであれば、以下の 1 行を追加するだけです!非常に簡単です。
const xrHelper = await scene.createDefaultXRExperienceAsync();
VR 空間でコントローラーを扱えるようにするためには、以下のコードを追加します。あとはコントローラーの操作に応じて発生するポインターのイベントを実装して、ピアノの鍵盤を押下するといったアクションを実現します。
const featuresManager = xrHelper.baseExperience.featuresManager;
const pointerSelection = featuresManager.enableFeature(BABYLON.WebXRFeatureName.POINTER_SELECTION, "stable", {
xrInput: xrHelper.input,
enablePointerSelectionOnAllControllers: true
});
VR 空間内を移動できるテレポートを実現したい場合は、床を表現するメッシュを作成し、以下のコードを追加します。これだけでテレポートできるようになります。
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 400, height: 400 });
const teleportation = featuresManager.enableFeature(BABYLON.WebXRFeatureName.TELEPORTATION, "stable", {
xrInput: xrHelper.input,
floorMeshes: [ground],
snapPositions: [new BABYLON.Vector3(2.4 * 3.5 * scale, 0, -10 * scale)],
});
続いてハンド トラッキングを有効にしていきますが、ハンド トラッキングのような新しい機能を試す場合は、チュートリアルでインクルードしている安定板ではなく、最新のプレビュー版を使用する方が正しく動作することが多いです。以下のようにプレビュー版の JS ファイルに置き換えておきます。
<script src="https://preview.babylonjs.com/babylon.js"></script>
ハンド トラッキングを有効にする
WebXR におけるハンド トラッキングとは、正確には WebXR Hand Input Module - Level 1 という仕様で、2021 年 8 月 24 日に W3C Working Draft として公開されています。具体的には、ベースとなる WebXR Device API を拡張し、多関節ハンド ポーズをトラッキングする機能を定義しています。
この仕様では、以下の図のような Skeleton Joints を定義しており、Joint のインデックスやボーンの部分にメッシュを作成することで、WebXR の空間上に手を模したオブジェクトを表示できるようにしています。
WebXR Hand Input 対応ブラウザーには、Oculus Quest/Quest2 の Oculus Browser や Firefox Reality for HoloLens 2 があります。Oculus Browser では、以前は chrome://flags
から以下のように #webxr-hands
を有効に変更する必要がありましたが、最新の Oculus Browser では明示的に有効にしなくても、既定でハンド トラッキングできるようになっているようです。
では、Babylon.js で作成した 3D ピアノを手で操作できるようにしてみましょう。これも非常に簡単で、以下のコードを追加します。これだけでハンド トラッキングが動作し、既定の手のメッシュが表示されるようになります。
const handTracking = featuresManager.enableFeature(BABYLON.WebXRFeatureName.HAND_TRACKING, "latest", {
xrInput: xrHelper.input
});
なお、Babylon.js の既定の実装では、人差し指と親指でつまむようなピンチ操作を行うことで、POINTERDOWN
や POINTERUP
のイベントが発生します。そのため、鍵盤をつまむように操作することで、3D ピアノの音を出すことができます。残念ながらこれは現実のピアノの操作性とは大きく異なるものですが、手のメッシュに物理演算のエンジンを組み込むことも可能なため、鍵盤との衝突判定を実装するなどして、よりリアルなピアノを作り込むことも可能と思います。手のメッシュのカスタマイズも可能なため、興味がある方は、Babylon.js のドキュメントを参考にしてみてください。
Babylon.js - WebXR Selected Features
ライブ デモ
本記事で紹介したコードを実装したデモを https://tinyurl.com/webxrpiano (リダイレクト先は https://edgewatcher.azurewebsites.net/babylonjs-piano-tutorial/index.html) に用意しました。WebXR でなくても通常のブラウザーで開いてピアノに触れることができますが、Oculus Quest 2 など対応デバイスをお持ちの方は、ぜひハンド トラッキングによる操作を試してみてください 😊
ブラウザーで #WebXR の VR 空間上に 3D ピアノを構築し、ハンド トラッキングにより手で弾いてみる 👍
— ユスキィ (Yusuke Hara) (@ms_yuhara) December 18, 2021
つたない演奏だけどね 🥺 pic.twitter.com/NzFE4O85h7
次回は ft-lab (Yutaka Yoshisaka) さんの "Web からのお手軽 AR の手段 (model-viewer)、glTF/usd による表現力の違いについて" です。