WebXR 平面検出モジュール

編集者草案,

この文書の詳細情報
この版:
https://immersive-web.github.io/plane-detection/
課題追跡:
GitHub
編集者:
(Google)
(Meta)
以前の編集者:
(Google)
参加:
課題を報告 (未解決の課題)
メーリングリストのアーカイブ
W3C の #immersive-web IRC

概要

平面検出は、WebXR Device API の機能を拡張するモジュールです。より没入感の高い体験を実現するために、 ネイティブ XR デバイスによって検出された平面の集合をアプリが受け取れるようにします。

この文書の位置付け

この節では、この文書の公開時点における位置付けについて説明します。現在の W3C 公開文書の一覧およびこの 技術報告書の最新版は、 W3C 技術 報告書索引(http://www.w3.org/TR/)で確認できます。

この文書は、Immersive Web Working Group によって編集者草案として公開されました。この文書は W3C 勧告となることを意図しています。 この仕様に関するフィードバックおよびコメントを歓迎します。 GitHub の課題を使用してください。 議論は、 public-immersive-web-wg@w3.org アーカイブでも確認できます。

編集者草案としての公開は、 W3C およびその会員による承認を意味するものではありません。これは草案文書であり、 いつでも他の文書によって更新、置換、または廃止される可能性があります。この文書を 作業中の文書以外のものとして引用することは不適切です。

この文書は、 W3C 特許方針の下で活動するグループによって作成されました。 W3C は、グループの成果物に関連して行われた 特許 開示の公開一覧を管理しており、そのページには 特許を開示するための手順も含まれています。必須 クレームを含むと本人が考える特許について 実際に知っている個人は、 W3C 特許方針の 第 6 節に従って、その情報を開示しなければなりません。

この文書は、2025年8月18日付 W3C プロセス文書に準拠します。

1. 序論

2. 初期化

2.1. 機能記述子

アプリケーションがセッション中に平面検出を使用することへの関心を示すには、そのセッションを 適切な機能 記述子とともに要求する必要があります。文字列 plane-detection は、平面検出機能の新しい有効な機能 記述子として、このモジュールによって導入されます。

デバイスの追跡システムがネイティブ平面検出機能を公開する場合、そのデバイスは plane-detection 機能をサポート可能です。インライン XR デバイスを、plane-detection 機能をサポート可能なものとして扱ってはなりません。

plane-detection 機能を有効にしてセッションを作成する場合、平面を更新するアルゴリズムを、そのセッションのフレーム更新のリストに追加しなければなりません。

次のコードは、平面検出を必要とするセッションを要求する方法を示します。
const session = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["plane-detection"]
});

3. 平面

3.1. XRPlaneOrientation

enum XRPlaneOrientation {
    "horizontal",
    "vertical"
};

3.2. XRPlane

[Exposed=Window]
interface XRPlane {
    [SameObject] readonly attribute XRSpace planeSpace;

    readonly attribute FrozenArray<DOMPointReadOnly> polygon;
    readonly attribute XRPlaneOrientation? orientation;
    readonly attribute DOMHighResTimeStamp lastChangedTime;
    readonly attribute DOMString? semanticLabel;
};

XRPlane は、 基盤となる XR システムによって検出された単一の平坦な表面を表します。

planeSpace は、平面の座標系を確立する XRSpace です。planeSpaceネイティブ原点は、平面の中心を追跡します。基盤となる XR システムが、 平面の中心の正確な意味を定義します。planeSpace によって定義される座標系の Y 軸は、平面の法線ベクトルを表さなければなりません。

XRPlane には、 関連付けられたネイティブエンティティがあります。

XRPlane には、 関連付けられたフレームがあります。

polygon は、平面の形状を記述する頂点の配列です。これらは、多角形の辺上の点を一周するループとして返され、 planeSpace によって定義される座標系で表現されます。各頂点の Y 座標は 0.0 でなければなりません。

semanticLabel 属性は、多角形のセマンティックラベルを記述する文字列です。セマンティック情報がない場合、この文字列は null または空であってもかまいません。XRSystem は、認識しているセマンティックラベルをこの属性に設定するべきです。

セマンティックラベルは、 XRSystem が把握している XRPlane の現実世界における名称を記述する ASCII 小文字の DOMString です。セマンティックラベルの一覧は、セマンティックラベルレジストリで定義されます。

orientation は、基盤となる XR システムによって分類された平面の向きを記述します。基盤となる XR システムが向きを "horizontal" または "vertical" に分類できない場合、この属性は null に設定されます。

lastChangedTime は、平面のいずれかの属性が最後に変更された時刻です。

注: 平面の姿勢は平面の 属性とはみなされないため、平面の姿勢が更新されても lastChangedTime は変更されません。これは、平面の姿勢が、2 つの異なるエンティティ、すなわち planeSpace と、getPose() 関数によって姿勢を計算する際の基準となる XRSpace から導出されるプロパティであるためです。

4. 検出された平面の取得

4.1. XRPlaneSet

[Exposed=Window]
interface XRPlaneSet {
  readonly setlike<XRPlane>;
};

XRPlaneSet は、XRPlane のコレクションです。これは、 XRFrame で検出された平面のコレクションを取得するための主要な仕組みです。

partial interface XRFrame {
  readonly attribute XRPlaneSet detectedPlanes;
};

XRFrame は、フレーム内で引き続き追跡されているすべての平面を含む detectedPlanes 属性を持つよう拡張されます。この集合は最初は空であり、平面を 更新するアルゴリズムによって設定されます。フレームがアクティブでないときにこの属性へアクセスした場合、 ユーザーエージェントは InvalidStateError を投げなければなりません。

partial interface XRSession {
  Promise<undefined> initiateRoomCapture();
};

XRSession は、関連付けられた追跡される平面の集合を持つよう拡張され、この集合は最初は 空です。集合の要素は XRPlane 型になります。

XRSession は、真偽値のルームキャプチャ完了を持つよう拡張され、この値は最初は false です。

XR デバイスが手動キャプチャをサポートする場合、そのデバイスは真偽値を返す非同期のルームキャプチャメソッドを持ちます。

XRSession は、initiateRoomCapture メソッドを持つようにも拡張されます。このメソッドは、サポートされている場合、XR デバイスに現在の部屋のレイアウトをキャプチャするよう要求します。これによって追跡される 平面の集合を置換するか拡張するかは、XR デバイスに委ねられます。

このメソッドが呼び出されたとき、ユーザーエージェントは次の手順を実行しなければなりません。
  1. sessionthis とします。

  2. promise を、session関連するレルムにおける新しい Promise とします。

  3. sessionended 値が `true` の場合、promise を "InvalidStateError" DOMException拒否し、 promise を返します。

  4. ルームキャプチャ完了が `true` の場合、 promise を "InvalidStateError" DOMException拒否し、promise を返します。

  5. plane-detection 機能記述子が、 sessionXR デバイスにおける sessionモード用の有効な機能のリスト含まれていない場合、 promise を "NotSupportedError" DOMException拒否し、 promise を返します。

  6. sessionXR デバイスが手動キャプチャをサポートしていない場合、または XRSystem がルームキャプチャは不要であると判断した場合:

    1. sessionルームキャプチャ完了を `true` に設定します。

    2. promise解決します。

    3. promise を返します。

  7. 次の手順を実行するタスクをキューに入れます

    1. sessionXR デバイスルームキャプチャメソッドを呼び出して結果を待ち、その結果を result に代入します。

    2. 次の手順を実行します。

      result が `true` の場合:

      promise解決します。

      それ以外の場合:

      promise を "OperationError" DOMException拒否します。

    3. sessionルームキャプチャ完了を `true` に設定します。

  8. promise を返します。

frame平面を 更新するために、ユーザーエージェントは次の手順を実行しなければなりません。
  1. session を、frameセッションとします。

  2. device を、sessionXR デバイスとします。

  3. plane-detection 機能記述子が、 sessionモード用の device有効な機能のリスト含まれていない場合、これらの手順を中止します。

  4. trackedPlanes を、frame時刻における追跡中の平面を取得するために、deviceネイティブ平面検出機能を呼び出した結果とします。

  5. trackedPlanes 内の各 native plane について、次を実行します。

    1. 必要に応じて、native planetrackedPlanes に存在しなかったものとして扱い、次の項目へ進みます。この方法で項目を 無視するかどうかを判断するために使用できる基準については、§ 6 プライバシーとセキュリティに関する考慮事項を参照してください。

    2. session追跡される平面の集合に、 native plane対応するオブジェクト plane が含まれている場合、 planenative plane、および frame を指定して平面オブジェクトを更新するアルゴリズムを呼び出し、次の 項目へ進みます。

    3. plane を、native plane および frame を指定して平面オブジェクトを作成する アルゴリズムを呼び出した結果とします。

    4. planesession追跡される平面の集合に追加します。

  6. このアルゴリズムの呼び出し中に作成も更新もされなかった各オブジェクトを、session追跡される 平面の集合から削除します。

  7. framedetectedPlanes追跡される平面の集合に設定します。

ネイティブ平面オブジェクト native plane および XRFrame frame から平面 オブジェクトを作成するために、ユーザーエージェントは次の手順を実行しなければなりません。
  1. resultXRPlane の新しいインスタンスとします。

  2. resultネイティブエンティティnative plane に設定します。

  3. resultplaneSpace を、sessionframesession に設定され、ネイティブ原点native plane の ネイティブ原点を追跡するよう設定された新しい XRSpace オブジェクトに設定します。

  4. resultnative plane、および frame を指定して平面オブジェクトを更新するアルゴリズムを呼び出します。

  5. result を返します。

このように作成された平面オブジェクト result は、渡されたネイティブ平面 オブジェクト native plane対応するといいます。

ネイティブ平面オブジェクト native plane および XRFrame frame から平面 オブジェクトを更新するために、ユーザーエージェントは次の手順を実行しなければなりません。
  1. planeフレームframe に設定します。

  2. native plane が基盤となるシステムによって垂直として分類される場合、 planeorientation"vertical" に設定します。それ以外で、native plane が基盤となるシステムによって水平として分類される場合、 planeorientation"horizontal" に設定します。それ以外の場合、planeorientationnull に設定します。

  3. planepolygon を、ネイティブ平面における多角形の表現の違いを考慮するために必要なすべての変換を行った、 native plane の多角形を表す新しい頂点配列に設定します。

  4. planesemanticLabel を、セマンティックラベルを含む新しい文字列に設定します。

  5. 必要に応じて、§ 6 プライバシーとセキュリティに関する考慮事項で説明されているように、 planepolygon の詳細度を低下させます。

  6. planelastChangedTime時刻に設定します。

次の例は、アプリケーションが検出された平面に関する情報を取得し、それに応じて処理する方法を示します。 平面のグラフィカルな表現を描画するために使用できるコードは示していません。

// `planes` は、アプリケーションが認識しているすべての検出済み平面と、
// それらが更新されたタイムスタンプを追跡します。最初は空のマップです。
const planes = Map();

function onXRFrame(timestamp, frame) {
  const detectedPlanes = frame.detectedPlanes;

  // まず、認識していた平面のいずれかが追跡されなくなったかどうかを確認します。
  for (const [plane, timestamp] of planes) {
    if(!detectedPlanes.has(plane)) {
      // 削除された平面を処理します。`plane` は前のフレームには存在しましたが、
      // 現在は追跡されていません。

      // その平面が存在しなくなったことが分かっているため、マップから削除します。
      planes.delete(plane);
    }
  }

  // 次に、引き続き追跡されているすべての平面を処理します。
  // これには、以前に確認した追跡中の平面(更新されている可能性があります)と、
  // 新しい平面の両方が含まれます。
  detectedPlanes.forEach(plane => {
    if (planes.has(plane)) {
      // 以前に確認した平面を処理します。

      if(plane.lastChangedTime > planes.get(plane)) {
        // 更新された、以前に確認した平面を処理します。
        // これは、平面のいずれかのプロパティが以前とは異なることを意味します。
        // 最も可能性が高いのは、多角形が変更されたことです。

        ... // 平面を描画する、または描画用に準備するなど。

        // 平面を更新した時刻を更新します。
        planes.set(plane, plane.lastChangedTime);
      } else {
        // 現在のフレームで更新されなかった、以前に確認した平面を処理します。
        // 他の空間を基準とする平面の姿勢は変更されている可能性があることに注意してください。
      }
    } else {
      // 新しい平面を処理します。

      // 平面を更新した時刻を設定します。
      planes.set(plane, plane.lastChangedTime);
    }

    // 平面を以前に確認したかどうか、または更新されたかどうかにかかわらず、
    // その姿勢は変更されている可能性があります。
    const planePose = frame.getPose(plane.planeSpace, xrReferenceSpace);
  });

  frame.session.requestAnimationFrame(onXRFrame);
}

5. ネイティブデバイスの概念

5.1. ネイティブ平面検出

平面検出 API は、ユーザーの環境で検出された平坦な表面に関する情報を提供します。この仕様では、 ユーザーエージェントが plane-detection 機能を実装するために、基盤となるプラットフォームが提供するネイティブ平面検出機能に依存できると仮定します。具体的には、基盤となる XR デバイスは、特定の XRFrame時刻に対応する時点で追跡されているすべての平面を照会する方法を提供するべきです。

さらに、ネイティブ平面オブジェクトと呼ばれる追跡中の平面は、 フレーム間でその同一性を維持すると仮定します。つまり、時刻 t0 に基盤となるシステムから返された平面オブジェクト P と、時刻 t1 に基盤となるシステムから返された平面オブジェクト Q がある場合、 PQ が同じ論理的な平面オブジェクトに対応するかどうかを、ユーザーエージェントが 基盤となるシステムへ照会できるものとします。また、基盤となるシステムは、時刻 t における 姿勢の位置を照会するために使用できるネイティブ原点を提供することも期待されます。ただし、平面の姿勢が 常に判明するとは限りません(たとえば、引き続き追跡されているものの、ある時点では位置を特定できない平面などです)。さらに、ネイティブ 平面オブジェクトは、検出された平面のおおよその形状を記述する多角形を公開するべきです。

さらに、基盤となるシステムは、XRAnchor を作成する目的では、ネイティブ平面をネイティブエンティティとして認識するべきです。詳細については、WebXR Anchors Module § native-anchor の節を参照してください。

6. プライバシーとセキュリティに関する考慮事項

平面検出 API は、ユーザーの物理的な環境に関する情報を公開します。ユーザーエージェントの判断により、 公開される平面情報(平面の多角形など)が制限される場合があります。ユーザーエージェントが公開する情報を 削減できる方法には、次のものがあります。平面オブジェクトを更新するアルゴリズム内で平面の多角形の詳細度を低下させること (たとえば、頂点の数を減らすか、頂点の座標を丸める、または量子化すること)、 あるいは、平面を更新するアルゴリズムの trackedPlanes コレクションに平面オブジェクトが存在しなかったかのように振る舞い、平面自体を完全に削除することです(たとえば、 検出された平面が小さすぎる、または詳細すぎて公開すべきではないと判断され、平面について公開される詳細を削減する仕組みが ユーザーエージェントに実装されていない場合に、この処理を行えます)。平面の姿勢 (planeSpace から取得可能)も量子化できます。

平面検出 API の概念は、[webxr-anchors-module] 仕様で公開されるメソッドで使用できるため、WebXR Anchors Module に関連するプライバシーとセキュリティに関する考慮事項の一部は、 ここにも適用されます。詳細については、WebXR Anchors Module § privacy-security の節を参照してください。

平面検出 API が WebXR Device API を拡張する方法により、WebXR Device API § 13. セキュリティ、プライバシー、および快適性に関する考慮事項の節も、WebXR Plane Detection Module が公開する 機能に適用されます。

7. 謝辞

次の方々が、WebXR Plane Detection 仕様の設計に貢献しました。

適合性

文書の 規約

適合要件は、説明的な表明と RFC 2119 の用語を組み合わせて 表現されます。 この文書の規範的な部分におけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、 「MAY」、および「OPTIONAL」は、 RFC 2119 で説明されているとおりに 解釈されます。 ただし、読みやすさのため、 この仕様ではこれらの語をすべて大文字では表記しません。

明示的に非規範的と示されている節、例、および注記を除き、 この仕様のすべての本文は規範的です。[RFC2119]

この仕様の例は、「たとえば」という語で導入されるか、 class="example" を使用して 規範的な本文から区別されます。 次のようになります。

これは参考例の一例です。

参考注記は「注」という語で始まり、 class="note" を使用して 規範的な本文から区別されます。 次のようになります。

注: これは参考注記です。

適合 アルゴリズム

アルゴリズムの一部として命令形で記述された要件 (「先頭の空白文字をすべて除去する」 または「false を返し、これらの手順を中止する」など)は、 そのアルゴリズムを導入する際に使用された キーワード(「must」、「should」、「may」など)の 意味で解釈されます。

アルゴリズムまたは特定の手順として記述された適合要件は、 最終的な結果が同等である限り、 どのような方法でも実装できます。 特に、この仕様で定義されるアルゴリズムは、 理解しやすいことを目的としており、 高い性能を目的としたものではありません。 実装者には最適化が推奨されます。

索引

この仕様で定義される 用語

参照によって定義される 用語

参考文献

規範的参考文献

[GEOMETRY-1]
Sebastian Zartner; Yehonatan Daniv. Geometry Interfaces Module Level 1. URL: https://drafts.csswg.org/geometry/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML 標準. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. RFC において要件レベルを 示すために使用するキーワード. 1997年3月. 現行のベストプラクティス. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. 現行 標準. URL: https://webidl.spec.whatwg.org/
[WEBXR]
Brandon Jones; Manish Goregaokar; Rik Cabanier. WebXR Device API. URL: https://immersive-web.github.io/webxr/

参考文献

[WEBXR-ANCHORS-MODULE]
Piotr Bialecki. WebXR Anchors Module. DR. URL: https://immersive-web.github.io/anchors/

IDL 索引

enum XRPlaneOrientation {
    "horizontal",
    "vertical"
};

[Exposed=Window]
interface XRPlane {
    [SameObject] readonly attribute XRSpace planeSpace;

    readonly attribute FrozenArray<DOMPointReadOnly> polygon;
    readonly attribute XRPlaneOrientation? orientation;
    readonly attribute DOMHighResTimeStamp lastChangedTime;
    readonly attribute DOMString? semanticLabel;
};

[Exposed=Window]
interface XRPlaneSet {
  readonly setlike<XRPlane>;
};

partial interface XRFrame {
  readonly attribute XRPlaneSet detectedPlanes;
};

partial interface XRSession {
  Promise<undefined> initiateRoomCapture();
};