Babylon.js 6.31.0でWebXR Raw Camera Access Featureが追加された
はじめに
TL;DR
Raw Camera Access Feature を使えば Babylon.js の WebXR 機能から端末のカメラ情報へアクセスできるようになります。
概要と対象読者
タイトルどおりではありますが、Babylon.js に最近追加された WebXR 機能である Raw Camera Access についてご紹介します。分量としては軽い内容ですが、少々内容のコンテキストが高めに思われる可能性がありますのでご了承ください。具体的には下記のトピックについて取り扱いますので、これらについて基礎知識があると読みやすいでしょう。
- Babylon.js
- WebXR Device API
- WebXR Raw Camera Access Module
検証環境
本記事の執筆において利用した環境を次に示します。
- Windows 10 Home
- Node.js 20
- pnpm 8
- Babylon.js 6.33.0
サンプル
本記事で紹介した内容を実装したサンプルを GitHub にて公開しております。
もしよければ、合わせてご覧ください。
RawCameraAccessについてご紹介
WebXR Featureについて
今回ご紹介する WebXR Raw Camera Access Feature というものは、Babylon.js における WebXR Feature の一種です。Babylon.js では WebXR Device API によって提供される Module を、Feature という形でラップして提供します。Feature(Module)の他の例としては Light Estimation(光源推定)や Plane Detection(平面検出)、Hit Test などがあります。
実は WebXR Raw Camera Access Module については以前に記事を書いていますので、詳しくはそちらをご覧ください。当時は Babylon.js に機能としてなかったため、自分で初期化やデータ変換をする必要がありましたが、この度それがなくなったので嬉しいです。
Featureによって何ができるのか
さてこの Feature ですが、日本語に直訳すると「生のカメラへのアクセス」ということになります。つまり WebXR 機能としてカメラの情報を直接取得できるということです。API ドキュメントページを貼ります。
この Feature 独自の API は多くないです。ざっくりこの API を通して得られるカメラ情報というのは次の 2 つです。順番に見ていきましょう。
- カメラ画像
- カメラ内部パラメータ
カメラ画像
カメラ画像に関係する API は次の 2 つです。
- texturesData
- onTexturesUpdatedObservable
textureData
はカメラ画像のテクスチャ(BaseTexture
型)の配列です。なぜ配列かというと、VRHMD のような 2 眼のデバイスがあった場合にテクスチャを複数取れる可能性があるからですね。
onTexturesUpdatedObservable
はカメラ画像テクスチャが更新されたときに呼び出される Observable オブジェクトです。ここにコールバックを登録してカメラ画像の取得処理を入れることになりそうです。
カメラ内部パラメータ
カメラ内部パラメータとは、カメラのレンズ特性を示す数値です。ここでは詳しい解説はしませんが、いわゆる視野角などに関わってくる値です。
Raw Camera Access Feature ではcameraIntrinsics
というプロパティから「内部パラメータの配列」を取得出来ます。配列な理由はすでに説明済みですね。このプロパティの型は次のようになっており、各フィールドが主要なパラメータと対応しています(筆者がうまく説明できない部分はコメントをしていません)。
{
ax: number; // 水平焦点距離
ay: number; // 垂直焦点距離
gamma: number;
height: number; // 画像の高さ
u0: number; // 水平光学中心
v0: number; // 垂直光学中心
viewportX: number;
viewportY: number;
width: number; // 画像の横幅
}
実装と動作確認
コード例を見ながら Feature の使い方をご紹介します。今回は Cube のテクスチャにカメラ画像を貼り付けてみましょう。まずはいつも通り Babylon.js で普通のシーンを作っていきます。
const engine = new Engine(renderCanvas, true);
const scene = new Scene(engine);
scene.createDefaultCameraOrLight(true, true, true);
const box = MeshBuilder.CreateBox("box", { size: 0.15 });
box.position = new Vector3(0, 0, 0.3);
const material = new StandardMaterial("material", scene);
box.material = material;
このコードに続けて WebXR 機能の初期化と取得をします。
const xr = await scene.createDefaultXRExperienceAsync({
uiOptions: {
sessionMode: "immersive-ar",
referenceSpaceType: "unbounded",
},
});
const sessionManager = xr.baseExperience.sessionManager;
const featureManager = xr.baseExperience.featuresManager;
// WebXRRawCameraAccess Featureを初期化・取得
const rawCameraAccess = featureManager.enableFeature(
WebXRFeatureName.RAW_CAMERA_ACCESS,
"latest",
{} as IWebXRRawCameraAccessOptions
) as WebXRRawCameraAccess;
// カメラ画像関連
rawCameraAccess.onTexturesUpdatedObservable.add(() => {
console.log("texture update!");
if (rawCameraAccess.texturesData.length !== 0) {
material.diffuseTexture = rawCameraAccess.texturesData[0];
}
});
// 内部パラメータの取得
sessionManager.onXRFrameObservable.add(() => {
const intrinsics = rawCameraAccess.cameraIntrinsics;
if (intrinsics.length !== 0) {
console.log(rawCameraAccess.cameraIntrinsics);
}
});
ざっくりと説明すると、カメラ画像の更新時にその画像データをテクスチャとして取得しそれを Cube のマテリアルに適用している処理と、XR のイベントループ中で内部パラメータを取得して表示している部分があります。
この処理をスマホで見てみると次のように浮かんでいる Cube にカメラ画像が映るようになりました。
また、コンソールにもちゃんとカメラ内部パラメータが出力されていますね。
おわりに
まとめ
本記事では概要の説明と簡単なコード例によって Babylon.js の Raw Camera Access Feature をご紹介しました。筆者としては、ついに実装されたかという感じで結構嬉しいので、ここでご紹介出来て良かったです。
最後まで読んでいただきありがとうございました。
参考
Discussion