Babylon.js Introduction To WebXR
現在の状況
WebXRのW3Cプロポーザルは、現在ドラフト段階です。しかし、Chrome にはすでに実装されています(他のブラウザについては caniuse.com を参照してください)。バージョン 79 からは、WebVR は非推奨となり、WebXR がデフォルトで有効になりました。それ以前のバージョンのブラウザでは、WebXR は設定フラグの後ろにありました。その目的の一つは、WebVRや他のAR実装を非推奨とし、単一のVRおよびAR APIを提供することです。
APIは継続的に変更されるため、機能変更に対応するのは困難です。最新のchrome canaryは、最もXR機能が充実したブラウザであり、Googleは継続的に新機能をアップデートしています。これが、後方互換性を壊すことなく、公式機能の最新版を内部バージョン管理で実装できるFeatures Managerを導入した主な理由です。
なお、WebXRと言った場合、実際にはVRイマーシブモードのWebXRを意味することがほとんどです。これは現在、WebXRの最も使用されているモードです。
Device and browser support
PC
WindowsのChrome 79は、すべてのMicrosoft Mixed RealityデバイスでWebXRを公式にサポートしています。非公式ですが、WebXRはoculus SDK (Rift, Rift S, Quest with Link)でうまく動作しています。この記事を書いている時点では、Oculusのサポートはまだフラグの後ろにあります。
Mobile and Quest
AndroidのChromeブラウザ(StableとCanary)上のWebXR AR機能は、平面検出、ヒットテスト、アンカーなどのAR機能を含む、chrome://flagsでフラグの後ろに有効にすることができます。AR機能のアーキテクチャは常に変化しているため、バージョンによって異なる結果が予想されることに注意してください。
Oculus Questは、最新のoculusブラウザでWebXR(VRモード)をサポートしています。Babylonのスペック実装はクエストとうまく連動しています。
iOS/iPhoneの公式サポートは今のところ予定されていません。MozillaはWebXR iOS Viewerを構築しており、これは(非常に)限定的なAR向けブラウザです。
Polyfill
WebVR をサポートしているが WebXR をサポートしていない古いブラウザでは、WebVR の機能を使用して WebXR API を実装した WebXR Polyfill を使用することができます。一部の機能は動作しませんが(または、変更せずにそのまま返します)、基本的な機能は正常に動作します。
Babylonでは、フレームワーク自体やプレイグラウンドにポリフィルを統合することは考えていません。WebXR をサポートするブラウザを使用していないユーザーに対して、ポリフィルを提供することを開発者に推奨します。
プレイグラウンドでポリフィルを使用するには、以下をプレイグラウンドに追加してください('createScene'の前)。
Getting started
最も簡単な方法は、WebXR 対応のブラウザを使用して、シーンに 1 行のコードを追加することです。
const xr = scene.createDefaultXRExperienceAsync();
これにより、セッション開始、入力ソース、カメラ、テレポート、シーンインタラクションなど、 VRイマーシブモード でWebXRを使用できるようになります。すべて WebXR Default Experience Helper を使用しています。
xr
変数は Promise であることに注意してください。非同期/awaitパターンを使用することで、よりシンプルで直感的な操作が可能になります。また、床のメッシュを定義することで、地面を定義し、その上を移動できるようになります。ここにXRの球体があります。
var createScene = async function () {
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);
sphere.position.y = 1;
const env = scene.createDefaultEnvironment();
// here we add XR support
const xr = await scene.createDefaultXRExperienceAsync({
floorMeshes: [env.ground],
});
return scene;
};
Migrating from WebVR
WebVR は非推奨であり、すべてのブラウザではないにせよ、ほとんどのブラウザでまもなくその寿命を終えるでしょう。すべての WebVR 実装を WebXR に移植することが強く推奨されます。
Migrating controller support
WebXR コントローラはもはやゲームパッドとはみなされないため、アーキテクチャは少し異なっています。
追加された最も重要な機能は、コントローラでポインタイベントを完全にサポートすることです。コントローラは全てのポインタイベントをサポートしているので、シーン内でマウスを操作するのと同じようにポインタインタインタラクションを使用することができます。
また、コントローラがどのような機能を持っているかを問い合わせ、それに応じて動作させることができるようになったことも重要な点です。
ここでは、VRコントローラーのよく使う機能と、XRで動作させる方法を紹介します。
WebXR (VR) Selected Features
AR-Exclusiveでない全ての機能のドキュメントが含まれています。AR機能については、BabylonJS WebXR AR Featuresのページを参照してください。
- Teleportation Module
- Hand tracking
- Movement Module
- Walking Locomotion
Teleportation Module
多くの(ネイティブ)VRゲームでは、シーン内での移動を可能にするためにテレポート機能があります。これは、ユーザーがめまいや方向感覚を失うことなく、シーン内を移動する最も便利な方法です。
BabylonはWebVRでテレポートをサポートしてきましたが、今回、その機能をアップグレードし、様々な能力を持つようになりました。
テレポート機能では、カメラの位置を操作するために、以下の方法が可能になりました。
- 直接/間接光線を使用して前進する
- 後退する
- その場で回転する
WebXRエミュレータに関する簡単なメモ
まだサポートされていないとはいえ、WebXRエミュレータはエミュレートしたコントローラにサムスティックを追加するので、テレポートをシミュレートすることが不可能になります。テレポートを動作させるには、useMainComponentOnly(後述)を有効にして、サムスティックのテレポートを無効にする必要があります。この動作が必須でない限り、開発時のみ有効にすることをお勧めします。
Enabling teleportation
WebXR Default Experience Helper を使用する場合、テレポートモジュールはデフォルトでオンになります。この機能を有効にしたり、再度有効にしたりするには、次のコードを使用します。
const featuresManager = xr.baseExperience.featuresManager; // or any other way to get a features manager
featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable" /* or latest */, {
xrInput: xr.input,
// add options here
floorMeshes: [ground, secondFloor, thirdFloor],
});
最新のオプションは、WebXRのテレポート機能のソースコードに記載されています。
一部のテレポートパラメータは構築時に必要となるため、コンストラクタのオプションパラメータでのみ設定可能です。パブリック ゲッター/セッターを持たないパラメータを再設定するには、この機能を再度有効にしてください。
var xrHelper = await scene.createDefaultXRExperienceAsync({
xrInput: xrHelper.input,
floorMeshes: [ground] /* Array of meshes to be used as landing points */,
});
// ...
// needs a reconfigure - re-enable the feature (will discard the old one and create a new one!)
xrHelper.teleportation = featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable" /* or latest */, {
xrInput: xrHelper.input,
floorMeshes: [ground],
renderingGroupId: 1,
});
テレポート機能で唯一必要なオプションはxrInputで、これはユーザーをテレポートさせるために使用するコントローラーです。
Setting floor meshes
Floor meshesはテレポートに最も重要で、モジュールはユーザーがどこに着陸できて、どこに着陸できないかを知る必要があります。
WebXR Default Experience Helper を使用する場合、初期化時に floorMeshes を設定することができます。
var xrHelper = await scene.createDefaultXRExperienceAsync({
xrInput: xr.input,
floorMeshes: [ground] /* Array of meshes to be used as landing points */,
});
const teleportation = xrHelper.teleportation;
自分で機能を有効にする場合、オプションオブジェクトで提供することができます。
const teleportation = featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable", {
xrInput: xr.input,
floorMeshes: [ground],
});
テレポート機能が有効になった後にメッシュを追加したい場合は、addFloorMesh関数を使用します。
teleportation.addFloorMesh(ground2);
And to remove simply use the removeFloorMesh function:
teleportation.removeFloorMesh(ground2);
Direct and indirect landing zones
テレポートの着地点は、コントローラーを持つ人が定義します。テレポートには、直接テレポートと間接(放物線)テレポートの2つの方法があります。
直接テレポートとは、ユーザーが着地したい位置(直線)を目指してテレポートする方法です。地面と着地点が見えている場合に使用し、最も便利で直進性の高い移動方法です。
間接ラインとは、高い位置から放物線を描くように移動することです。障害物を横切ったり、ある階から別の階へテレポートしたりするときに使います。
直接テレポーテーションは常に有効です。間接テレポートはデフォルトで有効ですが、フラグを使用して無効にすることが可能です。
// disable the parabolic (indirect) teleportation ray
teleportation.parabolicRayEnabled = false;
放物線をより遠くに飛ばすには、光線を90度上に向けたときに検査光線を作成するのに使用する半径を設定します(デフォルトは5)。
teleportation.parabolicCheckRadius = 10;
なお、放物線の半径が大きいほど、コントローラの回転角度は小さくなります。補正計算はこの式で行われます。
const compensation = 1 + (Math.PI / 2 - Math.abs(rotationOnTheXAxis));
補正は、定義された半径に乗算され、現在のレイ交差半径を変更します。
Different input sources
デフォルトの入力ソースは、XRヘッドセットと2つのハンドヘルドコントローラーです。WebXR のこの入力ソースは、TrackedPointer と呼ばれます。
入力ソースにサムスティックまたはタッチパッドがある場合、指を前に動かすとレイキャスティングモードがトリガーされます。投射された光線を見た後に指を回転させると、ユーザーが着地する方向が回転します。着地点が見えたら指を離すと、そこにユーザーが移動します。
サムスティックやタッチパッドが使用できない場合は、メインコンポーネント(通常はトリガー)が使用されます。メインコンポーネントの詳細については、WebXR input sourceを参照してください。メインコンポーネント(通常はボタン)を使用する場合、トリガーを押したままであれば、ユーザーがテレポートするまでの時間をミリ秒単位で定義することができます。デフォルトは3秒です。
この設定値はコンストラクタのオプションで見つけることができ、timeToTeleport と呼ばれています。
const teleportation = featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable", {
xrInput: xr.input,
floorMeshes: [ground],
timeToTeleport: 5000,
});
ボタンを使用する場合、回転を許可することは不可能であるため、ユーザーの方向はテレポートする前と同じままであることに注意してください。
メインコンポーネントのみを使用するように強制するには(サムスティックが使用可能な場合でも)、構築時にuseMainComponentOnlyフラグを使用します。
const teleportation = featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable", {
xrInput: xr.input,
floorMeshes: [ground],
timeToTeleport: 5000,
useMainComponentOnly: true,
});
The teleportation landing zone
テレポートランディングゾーンは、ユーザーがどこに、どの方向に着陸するのかを示すためのメッシュのグループです。デフォルトでは以下のような形になっています。
テレポートの着地点の各パーツは設定可能です。
ランディングゾーンのマテリアル
ランディングゾーン(床の暗円)の素材は、機能を構築する際にcssの色を使用して設定することができます。
const teleportation = featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable", {
xrInput: xr.input,
floorMeshes: [ground],
defaultTargetMeshOptions: {
teleportationFillColor: "#55FF99",
teleportationBorderColor: "blue",
},
});