開発
開発
プラットフォームを選択

パススルーを実装する


健康と安全に関するおすすめ: パススルーAPIを使って複合現実エクスペリエンスを構築する際、ユーザーにとって快適かつ安全なエクスペリエンスをサポートしているかどうか、開発者が自分のコンテンツを評価することを強くおすすめします。詳しくは、インサイトSDKについてのヒントとコツのガイドをご覧ください。

パススルー機能は、物理世界の3Dビジュアリゼーションを、リアルタイムで快適に知覚できるようにMeta Questヘッドセットに提供します。パススルーAPIにより、バーチャルエクスペリエンスにパススルー表示を統合することができます。その機能は、OpenXRの拡張機能であるXR_FB_passthroughXR_FB_triangle_meshによって提供されます。
OpenXR仕様の完全なAPIリファレンスについては、XR_FB_passthroughXR_FB_triangle_meshをご覧ください。

仕組み

パススルーは、専用サービスにより別個のレイヤーにレンダリングされ、XRコンポジターに直接送られます。ユーザーの物理環境の画像や動画に、アプリからアクセスすることはできません。その代わりに、アプリから特殊なプレースホルダーレイヤーが送信されます。このレイヤーが、XRコンポジターにより実際のパススルー表示に置き換わります。パススルーをカスタマイズする手段は、複合レイヤーやスタイリングなどいくつかあります。
  • 複合レイヤーでは、パススルーレイヤーの配置をXRコンポジタースタック内での仮想コンテンツとの相対関係(オーバーレイやアンダーレイ)で指定し、仮想コンテンツとどうブレンドするかを指定できます。パススルーを画面上のどこに表示するかは、アルファマスキングを使って指定できます。現在のところ、パススルーの奥行きに基づいてブレンドを指定する手段はありません。
  • スタイリングでは、パススルーフィードに色を付け、エッジレンダリングなどの視覚的効果を適用できます。
  • サーフェス投影パススルーでは、パススルー画像の投影先ジオメトリを定義します。このアプローチでは、アプリでユーザーの環境のさまざまな部分を認識している場合に、パススルーの表示の安定性が高くなります。

構成要素

XRセッションは、OpenXR仕様で定義されている、OpenXRセッションオブジェクト(ハンドルで表現される)です。パススルーオブジェクトはXrSessionインスタンスをスコープとしているため、ほとんどの作成(create)呼び出しにはセッションの指定が必要になります。詳しくは、インスタンスとセッションの作成をご覧ください。
パススルー機能は、パススルー機能を有効にして、その機能の動作に必要なデータを提供します。
パススルーレイヤーは、コンテンツのレンダリング機能を提供します。それらはシステムによって生成され、アプリに代わってシステムコンポジターに送信されます。アプリでは、コンテンツをどこにどうレンダリングするかを指定できます。どこにというのは、合成スタックの中の位置に対応します(アプリの投影レイヤーの上か下かなど)。どうというのは、タイプ(投影か再構成か)とスタイル(色、輪郭)に対応します。
メッシュとジオメトリインスタンスを利用すると、(自動環境深度再構成ではなく)パススルー画像の投影先のジオメトリをアプリで指定することができます。パススルーがアクティブになると、パススルーはサーフェス投影パススルーの対象として選ばれているジオメトリ上にのみ表示されます。パススルーは、それらのジオメトリのテクスチャーのように動作します。このアプローチでは、アプリでユーザーの環境のさまざまな部分を認識している場合に、パススルーの表示の安定性が高くなります。

前提条件

パススルーを開始する前に、最新バージョンのMeta QuestオペレーティングシステムとMeta XR Core SDKを使っていることを確認してください。これは個別に、またはMeta XRオールインワンSDKの一部として入手できます。以下のように確認します。
  • ヘッドセットがインターネットに接続されていること、最新バージョンがインストールされていることを確認します。ヘッドセットの[Settings (設定)] > [System (システム)] > [Software Update (ソフトウェアの更新)]で、最新バージョンであるかどうかを確認し、必要に応じて更新します。
  • アプリでは64ビットのビルドを使う必要があります。32ビットのアプリはサポートされていません。
Linkを介して接続されているデバイスを使ってUnityエディターからプロジェクトを直接実行する場合は、Oculus Linkによるパススルーに関する追加の前提条件を考慮してください。

プロジェクトの設定

: マニフェストファイルの中でこの機能フラグがセットされていないと、パススルーOpenXR拡張機能は有効になりません。

インスタンスとセッションを作成する

パススルーAPIを実装するには、OpenXRインスタンス作成時に、XR_FB_passthroughXR_FB_triangle_mesh(サーフェス投影パススルー専用)拡張機能が必須拡張機能として宣言されていることが必要です。
std::vector<const char*> requiredExtensionNames{
  XR_FB_PASSTHROUGH_EXTENSION_NAME,
  XR_FB_TRIANGLE_MESH_EXTENSION_NAME // optional
};

XrInstanceCreateInfo instanceCreateInfo = {XR_TYPE_INSTANCE_CREATE_INFO};
instanceCreateInfo.createFlags = 0;
instanceCreateInfo.applicationInfo = appInfo;
instanceCreateInfo.enabledApiLayerCount = 0;
instanceCreateInfo.enabledApiLayerNames = NULL;
instanceCreateInfo.enabledExtensionCount = requiredExtensionNames.size();
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames.data();

XrInstance instance;
XrResult result = xrCreateInstance(&instanceCreateInfo, &instance);
if (XR_FAILED(result)) {
  LOG("Failed to create XR instance: %d.\n", initResult);
  exit(1);
}
次に、通常の手順どおりXrSessionの作成に移ります。OpenXRのインスタンスとセッションの設定と管理のあらゆる面を網羅したサンプルについては、ネイティブ版のサンプルをご覧ください。
上記の前提条件のいずれかが満たされていない場合、インスタンスの作成は失敗します。XrInstanceを作成する前に、拡張機能が利用可能かどうかを確認することができます。そのためには、xrEnumerateInstanceExtensionPropertiesを呼び出して、返される拡張機能のリストの中にXR_FB_passthroughXR_FB_triangle_meshが存在していることを確認します。

システムがパススルーをサポートしていることを確認する

ネイティブアプリでパススルーを使用する前に、システムでパススルーがサポートされていることを確認する必要があります。そのためには、次のように、xrGetSystemPropertiesを呼び出して、XrSystemPassthroughProperties2FB構造体のsupportsPassthroughフラグをチェックします。
static bool SystemSupportsPassthrough(XrInstance instance, XRFormFactor formFactor)
{
    XrSystemPassthroughProperties2FB passthroughSystemProperties{XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB};
    XrSystemProperties systemProperties{XR_TYPE_SYSTEM_PROPERTIES, &passthroughSystemProperties};

    XrSystemGetInfo systemGetInfo{XR_TYPE_SYSTEM_GET_INFO};
    systemGetInfo.formFactor = formFactor;

    XrSystemId systemId = XR_NULL_SYSTEM_ID;
    xrGetSystem(instance, &systemGetInfo, &systemId);
    xrGetSystemProperties(instance, systemId, &systemProperties);

    return (passthroughSystemProperties.capabilities & XR_PASSTHROUGH_CAPABILITY_BIT_FB) == XR_PASSTHROUGH_CAPABILITY_BIT_FB;
}
同様に、現在のデバイスでカラーパススルーがサポートされているかどうかについて、XR_PASSTHROUGH_CAPABILITY_COLOR_BIT_FB機能フラグがtrueかどうかを調べます。

関数ポインターを取得する

パススルー拡張機能で定義されている関数を使うには、関数ポインターを宣言して取得する必要があります。
PFN_xrCreatePassthroughFB pfnXrCreatePassthroughFBX = nullptr;
XrResult result = xrGetInstanceProcAddr(_instance, "xrCreatePassthroughFB", (PFN_xrVoidFunction*)(&pfnXrCreatePassthroughFBX));

if (XR_FAILED(result)) {
  LOG("Failed to obtain the function pointer for xrCreatePassthroughFB.\n");
}
関数ポインターすべてのリストについては、OpenXRパススルーのサンプルをご覧ください。

パススルー機能を作成して開始する

パススルーレイヤーをアプリに追加するには、その前にアプリでパススルー機能を作成する必要があります。パススルー表示に必要になる基本的なシステムリソースや処理は、パススルー機能により管理されます。アプリで行うべきことは、すべてのセッションで1つのパススルー機能を作成することだけです。
// Create the feature
XrPassthroughFB passthroughFeature = XR_NULL_HANDLE;

XrPassthroughCreateInfoFB passthroughCreateInfo = {XR_TYPE_PASSTHROUGH_CREATE_INFO_FB};
passthroughCreateInfo.flags = XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB;

XrResult result = pfnXrCreatePassthroughFBX(GetSession(), &passthroughCreateInfo, &passthroughFeature);
if (XR_FAILED(result)) {
  LOG("Failed to create the passthrough feature.\n");
}
XrPassthroughCreateInfoFBの中でXR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FBフラグを指定することにより、パススルー機能が作成後すぐに開始されます。つまり、パススルー表示に必要な環境再構成やその他のバックグラウンドタスクを、システムがただちに実行開始する場合があるということです。アプリ実行時にパススルーをすぐには表示しないなどの理由で、作成と開始を分離するのであれば、flagsをセットしないままにし、後で手動で機能を開始してください。それには次のようなコードを使います。
// Start the feature manually
XrResult result = pfnXrPassthroughStartFB(passthroughFeature);
if (XR_FAILED(result)) {
  LOG("Failed to start a passthrough feature.\n");
}

パススルーレイヤーを作成して開始する

システムでパススルー画像を生成するための準備はパススルー機能によって行いますが、アプリの中でパススルーが表示されるようにするには、アプリで1つ以上のパススルーレイヤーを作成し、開始する必要があります。パススルーレイヤーには次の2つの目的があります。
  • パススルーをアプリの他のレイヤーとどう合成するかを指定する。例えば、メイン投影レイヤーなどです。
  • パススルーの外観と動作を別個にカスタマイズする。
アプリでは、複数のパススルーレイヤーを作成して開始することができます。しかし、同時に作成できるパススルーレイヤーは3つまでです。
// Create and run passthrough layer
XrPassthroughLayerFB passthroughLayer = XR_NULL_HANDLE;

XrPassthroughLayerCreateInfoFB layerCreateInfo = {XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB};
layerCreateInfo.passthrough = passthroughFeature;
layerCreateInfo.purpose = XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB;
layerCreateInfo.flags = XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB;

XrResult result = pfnXrCreatePassthroughLayerFBX(Session, &layerCreateInfo, &passthroughLayer);
if (XR_FAILED(result)) {
  LOG("Failed to create and start a passthrough layer");
}
パススルー機能と同じようにパススルーレイヤーについても、XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FBフラグを省くことにより停止状態で作成しておいて、後でxrPassthroughLayerResumeFBを使って開始することができます。
purposeフィールドは、パススルーレイヤーのタイプを指定します。ほとんどの場合は、XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FBが適切な選択となります。その他の選択肢の説明については、サーフェス投影パススルー を参照してください。

パススルーレイヤーをコンポジターに送信する

アプリから送信する他のレイヤーとパススルーレイヤーをどういう順序でブレンドするかをXRコンポジターに対して指示するには、各パススルーレイヤーのxrEndFrame呼び出しに、タイプXrCompositionLayerPassthroughFBのコンポジターレイヤーを含める必要があります。
アプリに1つの投影レイヤーと1つのパススルーレイヤーするという単純なシナリオでは、これにより、パススルーレイヤーをアプリケーションの投影レイヤーの上または下のどちらに表示するかをアプリで選択できるようになります。レイヤー数が3つ以上になる複雑なシナリオの場合、任意の順序で合成することが可能です。
プロキシレイヤーが送信されていないパススルーレイヤーは、コンポジターによって破棄される場合があります。ただし、プロキシレイヤーを送信しないことでパススルーレイヤーを非表示にすることはできません。アプリでは、xrPassthroughLayerPauseFBでシステムリソースを保存し、パススルーが非アクティブであることをシステムに通知する必要があります。プロキシレイヤーは、常に実行中のパススルーレイヤーに対して送信を行い、一時停止中のパススルーレイヤーに対しては送信を行いません。
以下のスニペットは、パススルーレイヤーがアプリの投影レイヤーのオーバーレイとして合成される単純なシナリオを示しています。
XrCompositionLayerPassthroughFB passthroughCompLayer = {XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB};
passthroughCompLayer.layerHandle = passthroughLayer;
passthroughCompLayer.flags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
passthroughCompLayer.space = XR_NULL_HANDLE;

const kLayerCount = 2;
const XrCompositionLayerBaseHeader* layers[kLayerCount] = {
  (const XrCompositionLayerBaseHeader*) applicationCompLayer,
  (const XrCompositionLayerBaseHeader*) passthroughCompLayer
};

XrFrameEndInfo endFrameInfo = {XR_TYPE_FRAME_END_INFO};
endFrameInfo.displayTime = predictedDisplayTime;
endFrameInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
endFrameInfo.layerCount = kLayerCount;
endFrameInfo.layers = layers;

xrEndFrame(session, &endFrameInfo);
構造コンテンツの次の点に注意してください。
  • パススルー合成レイヤーに画像データが含まれないためXrCompositionLayerPassthroughFB::spaceは無関係なので、XR_NULL_HANDLEに設定する必要があります。
  • パススルー合成レイヤーに関係するレイヤーフラグは、XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BITだけです。それ以外のレイヤーフラグは無視されます。
    • スタイルまたはサーフェス投影パススルーが使われている場合、システム生成のパススルーレイヤーに不透明でないアルファ値が含まれる可能性があります。XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BITがセットされていない場合、それらのアルファ値は無視されます。アプリでアルファ値を無視することが特に必要でない限り、このフラグをセットすることをおすすめします。
  • Meta Quest OpenXRの実装では、パススルーを使う場合であっても、XrFrameEndInfo::environmentBlendModeXR_ENVIRONMENT_BLEND_MODE_OPAQUEに設定されている必要があります。パススルーを背景として表示するには、アプリの投影レイヤーより前にパススルーレイヤーを送信します。つまり、XrCompositionLayerBaseHeader配列の中でapplicationCompLayerpassthroughCompLayerの挿入順序を変更します。
  • 次の2つの拡張機能は、XrCompositionLayerPassthroughFBインスタンスの次のチェーンの中でサポートされます。合成時にパススルーレイヤーによって、それらの拡張機能のプロパティが考慮されます。
    • XR_FB_composition_layer_alpha_blend: パススルーレイヤーのブレンド係数を指定します。例えば、加算的ブレンドを実現したり、パススルーレイヤーを別のレイヤーのアルファチャネルでマスキングしたりすることが可能です(「複合現実の合成とマスキング」を参照)。
    • XR_KHR_composition_layer_color_scale_bias: 合成時のパススルーレイヤーの色とアルファ値に変更を加えます。

システムの推奨事項に基づいて有効にする

アプリの中で、ユーザーの選択に基づいてVRやパススルー背景を表示したいと思う可能性があります。Metaのシステムはすでにホーム環境でユーザーにこの選択肢を提供しているため、ユーザーのホーム環境設定をアプリに流用できます。より一般的な言い方をすれば、ユーザーの個人設定に基づいて、システムはMRとVRのどちらをデフォルト値としてアプリに推奨するかを決めます。この推奨事項は、拡張機能XR_META_passthrough_preferencesによって利用可能になります。
  • xrGetPassthroughPreferencesを呼び出します。
  • フラグXR_PASSTHROUGH_PREFERENCE_DEFAULT_TO_ACTIVE_BIT_METAが設定されている場合、アプリでパススルーを表示することがシステムから推奨されます。これは現在、ユーザーがホーム環境でバックグラウンドとしてパススルーを選択した場合に該当します。
ナビゲーションロゴ
日本語
© 2026 Meta