📷

Babylon.js 6.31.0でWebXR Raw Camera Access Featureが追加された

2023/12/08に公開

はじめに

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 にて公開しております。
もしよければ、合わせてご覧ください。

https://github.com/drumath2237/babylon-webxr-raw-camera-access-sandbox

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 に機能としてなかったため、自分で初期化やデータ変換をする必要がありましたが、この度それがなくなったので嬉しいです。

https://zenn.dev/drumath2237/articles/52d62638c7d06f

Featureによって何ができるのか

さてこの Feature ですが、日本語に直訳すると「生のカメラへのアクセス」ということになります。つまり WebXR 機能としてカメラの情報を直接取得できるということです。API ドキュメントページを貼ります。

https://doc.babylonjs.com/typedoc/classes/BABYLON.WebXRRawCameraAccess

この Feature 独自の API は多くないです。ざっくりこの API を通して得られるカメラ情報というのは次の 2 つです。順番に見ていきましょう。

  • カメラ画像
  • カメラ内部パラメータ

カメラ画像

カメラ画像に関係する API は次の 2 つです。

  • texturesData
  • onTexturesUpdatedObservable

textureDataはカメラ画像のテクスチャ(BaseTexture型)の配列です。なぜ配列かというと、VRHMD のような 2 眼のデバイスがあった場合にテクスチャを複数取れる可能性があるからですね。
onTexturesUpdatedObservableはカメラ画像テクスチャが更新されたときに呼び出される Observable オブジェクトです。ここにコールバックを登録してカメラ画像の取得処理を入れることになりそうです。

カメラ内部パラメータ

カメラ内部パラメータとは、カメラのレンズ特性を示す数値です。ここでは詳しい解説はしませんが、いわゆる視野角などに関わってくる値です。

https://mem-archive.com/2018/02/21/post-157/

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 で普通のシーンを作っていきます。

Cubeだけの簡単なシーン
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 機能の初期化と取得をします。

WebXR Featureの初期化と取得
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 にカメラ画像が映るようになりました。

Alt text

また、コンソールにもちゃんとカメラ内部パラメータが出力されていますね。

Alt text

おわりに

まとめ

本記事では概要の説明と簡単なコード例によって Babylon.js の Raw Camera Access Feature をご紹介しました。筆者としては、ついに実装されたかという感じで結構嬉しいので、ここでご紹介出来て良かったです。
最後まで読んでいただきありがとうございました。

参考

https://doc.babylonjs.com/typedoc/classes/BABYLON.WebXRRawCameraAccess

https://zenn.dev/drumath2237/articles/52d62638c7d06f

https://immersive-web.github.io/raw-camera-access/

GitHubで編集を提案

Discussion