Open1

Meta Quest3のパススルーAPI触ってみた

イワケンイワケン

こんにちは、XRエンジニアのイワケンです。

Meta Questのパススルー映像をアプリ内で活用できるPassthrough Camera APIが登場しました!
これにより、WebCamTextureAndroid Camera2 API を使ってQuestのカメラ映像を取得できます。

本記事では、Meta公式サンプルを用いて、UnityでのパススルーAPIの基本的な使い方を紹介します!

Quest Passthrough
WebCamTextureを使ったパススルー


環境構築

私が検証した環境は以下の通りです。

ツール バージョン
Unity 2022.3.58f1 / 6000.0.38f1
Meta MR Utility Kit v72.0.0
Unity Sentis (ML用) v2.1.1
Horizon OS v74以上
対応デバイス Quest 3 / Quest 3S

ドキュメント:Meta Developers Documentation

必要なパーミッション

Questのパススルーカメラにアクセスするためには、以下のAndroidパーミッションが必要です。

AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="horizonos.permission.HEADSET_CAMERA"/>

パーミッションリクエストは PassthroughCameraPermissions クラスが処理します。


Unityでパススルーカメラを利用する方法

プロジェクトのセットアップ

  1. 公式リポジトリをクローン
    git lfs install
    git clone https://github.com/oculus-samples/Unity-PassthroughCameraApiSamples
    
  2. Unity 2022.3.58f1 以上で開く
  3. Meta > Tools > Project Setup Tool で設定エラーを修正
  4. Meta > Tools > Building Blocks から Camera Rig をシーンに追加
  5. WebCamTextureManagerPrefab をシーンにドラッグ&ドロップ

WebCamTextureを使ってパススルーカメラ映像を取得する

Unityの WebCamTexture を使用すると、Questのパススルーカメラ映像を取得できます。
WebCamTextureManager を使うことで、簡単にカメラデータを表示できます。

基本コード

using UnityEngine;
using UnityEngine.UI;

public class CameraViewer : MonoBehaviour
{
    public RawImage displayImage;
    private WebCamTexture webCamTexture;

    void Start()
    {
        WebCamDevice[] devices = WebCamTexture.devices;
        if (devices.Length > 0)
        {
            webCamTexture = new WebCamTexture(devices[0].name, 1280, 960);
            displayImage.texture = webCamTexture;
            webCamTexture.Play();
        }
    }

    void OnDestroy()
    {
        webCamTexture?.Stop();
    }
}

2D座標から3D空間への変換

パススルーカメラを使うと、2D画面上のオブジェクトを3D空間に投影することができます。

スクリーン座標をワールド座標に変換する

PassthroughCameraUtils.ScreenPointToRayInWorld() を使うと、スクリーン上の座標を3Dのレイに変換できます。

var cameraScreenPoint = new Vector2Int(x, y);
var ray = PassthroughCameraUtils.ScreenPointToRayInWorld(PassthroughCameraEye.Left, cameraScreenPoint);

物理オブジェクトと交差する座標を取得

Questの EnvironmentRaycastManager.Raycast() を利用すると、カメラ映像と実空間のオブジェクトを対応付けることができます。

if (environmentRaycastManager.Raycast(ray, out EnvironmentRaycastHit hitInfo))
{
    anchorGo.transform.SetPositionAndRotation(
        hitInfo.point,
        Quaternion.LookRotation(hitInfo.normal, Vector3.up));
}


Meta Quest向けMLモデルの活用

Unity Sentis を使用すると、Questデバイス上でリアルタイム物体認識を行うことができます。

YOLOを使用したオブジェクト検出

MultiObjectDetection サンプルでは、YOLOモデルを使用してリアルタイムにオブジェクトを認識します。

// 画面上の物体を検出し、位置を取得
var detectedObjects = sentisModel.DetectObjects(cameraFrame);
foreach (var obj in detectedObjects)
{
    Debug.Log($"Detected: {obj.Label} at {obj.Position}");
}

既知の問題と制約

問題 対応策
WebCamTexture にはタイムスタンプがない 40~60msの遅延あり
片方のカメラのみ使用可能 両目カメラの同時利用は不可
解像度の変更時にフレーム落ちが発生 1280x960を推奨
PassthroughCameraUtils1つのパーミッション要求のみ対応 他のパーミッション管理と競合する可能性あり

まとめ

  • QuestのパススルーカメラWebCamTexture で活用可能
  • PassthroughCameraUtils を使うと 2D画像座標を3D座標に変換 できる
  • Unity Sentisオンデバイスの物体認識 が可能
  • 現状では シングルカメラのみ対応(両目カメラは不可)

今後の展望

今後、QuestのパススルーAPIがさらに進化することで、より多くのXR体験が可能になると期待されます。
特に 両目パススルーの対応物体認識の精度向上 などが待たれます!

次回は「パススルーカメラを活用したARエフェクトの実装」について解説予定です!
フォローしてお待ちください 🎮


参考資料