😎

Unity 用 Meta Quest 位置合わせライブラリ (QR / Immersal) の仕組み

に公開

本記事では、Meta Quest 3 / Meta Quest 3S で利用可能な Unity 用の位置合わせライブラリである QuestCameraTools-Unity の仕組みについて紹介します。このライブラリでは、位置合わせ手法として QR コードと Immersal の 2 種類をサポートしています。

QuestCameraTools-Unity は以下のリポジトリで公開しています。使い方についてはリポジトリの README をご覧ください。

https://github.com/HoloLabInc/QuestCameraTools-Unity

カメラ映像の取得

Horizon OS v74 より Passthrough Camera API という API が公開され、Quest 3 / Quest 3S のカメラ映像を取得できるようになりました。Unity では WebCamTexture を利用してカメラ映像を利用することができます。また、Android の API を利用することで、カメラの内部パラメータ(焦点距離など)や外部パラメータ(アプリ座標におけるカメラの位置や向き)についても取得できます。

さらに、公式のサンプルプロジェクトである Unity-PassthroughCameraApiSamples では、カメラ取得やカメラパラメータ取得のためのマネージャークラス、ユーティリティクラスが提供されており、これらを使うことでより簡単にカメラを利用することができます。

ただし、Unity-PassthroughCameraApiSamples のコードは UPM インポートできるように作られていなかったため、QuestCameraTools-Unity にコードを取り込んでいます。

https://github.com/oculus-samples/Unity-PassthroughCameraApiSamples

QR コードによる位置合わせ

https://www.youtube.com/watch?v=yewc1cSJ5Gc

処理の流れ

QR コードによる位置合わせは以下のような流れで行っています。

  1. カメラ画像とカメラパラメータを取得
  2. カメラ画像から QR コードを検出
  3. 画像内の QR コードファインダパターンの位置とカメラパラメータから、カメラからファインダパターンへのレイを計算
  4. レイと Quest の Depth API を利用して、ファインダパターンの 3 次元位置を取得
  5. ファインダパターンの位置から、QR コードの位置・姿勢・サイズを計算
  6. GameObject の位置・姿勢を QR コードの位置・姿勢に合わせる

1. カメラ画像とカメラパラメータの取得

カメラ映像の取得で記載した通り、WebCamTexture を利用してカメラ映像を取得できます。WebCamTexture に対し GetPixels32() を呼ぶことで、その時点でのカメラ画像を取得します。

また、カメラの外部パラメータについても取得しておきます。

2. カメラ画像から QR コードを検出

ZXing.Net というライブラリを利用して QR コードを検出します。このライブラリでは、ファインダパターンと呼ばれる QR コードの左上・右上・左下にあるパターンのピクセル座標を取得することができます。

3. 画像内の QR コードファインダパターンの位置とカメラパラメータから、カメラからファインダパターンへのレイを計算

ファインダパターンのピクセル座標とカメラの外部パラメータ・内部パラメータを利用することで、Unity の World 座標におけるカメラからファインダパターンへのレイを計算することができます。ただし、この時点ではまだパターンとカメラとの距離がわからないため、3 次元位置を取得することはできません。

4. レイと Quest の Depth API を利用して、ファインダパターンの 3 次元位置を取得

ファインダパターンの 3 次元位置を取得するために、Quest の Depth API を利用します。Depth API は Quest で認識しているリアルタイムの環境のデプス情報を取得できます。

Mixed Reality Utility Kit では、Depth API を利用してレイが環境にぶつかる位置を取得するためのメソッドが提供されています。このメソッドを利用して、QR コードのファインダパターンの 3 次元位置を取得しています。

5. ファインダパターンの位置から、QR コードの位置・姿勢・サイズを計算

3 点のファインダパターンの 3 次元位置から、QR コードの位置・姿勢・サイズを計算します。具体的には、以下のように計算を行っています。

位置は右上パターンと左下パターン位置の平均値として求めます。
姿勢は左下パターンから左上パターンへの方向が前方向、左上パターンから右上パターンへの方向が右方向であるとして求めます。

サイズは少し複雑で、まず左上パターンと左下パターンの距離と左上パターンと右上パターンの距離をそれぞれ求めます。ここで求めた距離はマーカー全体のサイズではなく、ファインダパターンの中心間のサイズとなっています。そのため、この距離に セルサイズ / (セルサイズ-7) をかけることで、マーカー全体の縦横サイズを求めています。最後に、縦横の平均値を求めて、マーカーのサイズとしています。

6. GameObject の位置・姿勢を QR コードの位置・姿勢に合わせる

位置合わせをして表示したい GameObject の位置・姿勢を認識した QR コードの位置・姿勢に合わせます。

ただし、認識結果そのままでは位置や姿勢のブレが大きく表示が安定しなかったため、複数回の結果から外れ値を除去したうえで平均値を求めるような処理も行っています。

Immersal による位置合わせ

https://www.youtube.com/watch?v=tv8CBWOci_s

実装概要

Immersal SDK ではコンポーネントアーキテクチャを採用しており、一部分を差し替えることでさまざまなデバイスに対応することができます。

具体的には、IPlatformSupport インタフェースを実装したクラスを作成します。そのクラスの ConfigurePlatform メソッド内でカメラ画像やカメラパラメータの取得を行い、求められている形式 (IPlatformUpdateResult) にしたがってデータを返します。

https://developers.immersal.com/docs/unitysdk/immersalcomponents/platformsupport/

ConfigurePlatform メソッドを定期的に呼び出す処理、位置の認識を行う処理、認識結果に合わせて GameObject の位置を更新する処理などはすべて Immersal SDK で行ってくれます。

そのため、QuestCameraTools-Unity で実装しているスクリプトは QuestSupport.cs という IPlatformSupport インタフェースを実装したクラスのみとなっています。

おわりに

本記事では、Meta Quest 3 / Meta Quest 3S で利用可能な Unity 用の位置合わせライブラリである QuestCameraTools-Unity の仕組みについて紹介しました。ぜひ、このライブラリを利用して Quest 用の MR アプリケーションを開発してみてください。

なお、ホロラボではMeta Questシリーズのハードウェア本体の販売や運用を目指した導入支援も行っております。ぜひお気軽にご相談ください。

■ホロラボ の Meta Questに関する取組み
https://hololab.co.jp/showcases/meta/

ホロラボのテックブログ

Discussion