--- title: WebXR の幾何学と参照空間 slug: Web/API/WebXR_Device_API/Geometry tags: - API - Geometry - Guide - Math - Orientation - Placement - Position - Reference Spaces - Spaces - WebXR - WebXR API - WebXR Device API translation_of: Web/API/WebXR_Device_API/Geometry ---

{{DefaultAPISidebar("WebXR Device API")}}

基本的なレベルでは、拡張現実または仮想現実のコンテキストでの WebXR プレゼンテーションのシーンのレンダリングは WebGL を使用して実行されるため、2つの API は同じ設計言語の多くを共有します。 ただし、XR ヘッドセットなどの機器を使用して真の 3D でシーンを提示する機能を提供するために、WebXR には理解する必要がある追加の概念があります。

この記事では、WebXR が WebGL の幾何学を拡張する方法と、オブジェクトの位置と方向(物理的および仮想的)が空間、特に参照空間を使用して相互にどのように記述されるかを紹介します。

WebXR での空間追跡の記事は、ユーザーの頭の物理的な位置と向きだけでなく、手などの潜在的に身体の他の部分がデジタル世界にマッピングされ、物理オブジェクトと仮想オブジェクトの両方が動き回るときに追跡されるかをカバーするため、ここで提供される情報に基づいて、シーンを適切にレンダリングして合成できるようにします。

3D 幾何学の基礎

ここでは、仮想空間内のオブジェクトの位置、方向、動きを計算するために使用される必要な数学演算に加えて、シーンの人間のビューアーを混合物の中に統合する必要性について説明しますが、幾何学やシーンの 3D 表現を管理するための行列とベクトルは、この記事で達成できることの範囲をはるかに超えています。 ウェブの行列計算で個々の演算について詳しく知ることができます。

単位

WebXR で使用される 3D 空間の幾何学の詳細について説明する前に、3D の世界に適用される測定単位を理解しておくと役に立ちます。

長さと距離

WebGL はすべての距離と長さをメートル(meters)で測定します。 WebXR はこの標準を継承しています。 また、世界は幅 2 メートル、高さ 2 メートル、奥行き 2 メートルの立方体であるという事実も継承しています。 3つの軸のそれぞれの最小値は -1.0、最大値は 1.0 で、立方体の中心は (0, 0, 0) にあります。

X、Y、Z 座標軸のそれぞれの最小値が -1、最大値が 1 である WebXR 空間を示す図。

この 2 立方メートルの空間は、コードのために宇宙全体を囲んでいます。 描画するすべてのものは、コード内で明示的に、または変換を使用してすべての頂点の座標を調整することにより、この空間に収まるように座標をマッピングする必要があります。 もちろん、最も効率的な方法は、WebGL と同じ座標系を使用するようにオブジェクトとコードを設計することです。

WebGL の座標と長さは、レンダリング時にシーンがレンダリングされているビューポートの大きさに自動的に変換されます。

角度

角度は{{interwiki("wikipedia", "ラジアン")}}(radians)を使用して指定します。 度をラジアンに変換するには、度の値に π/180 を掛けるだけです。 次のコードスニペットは、2つの単純な関数、degreesToRadians()radiansToDegrees() を示しています。 これらは、角度を測定するために2つの単位間で相互に変換します。

const RADIANS_PER_DEGREE = Math.PI / 180.0;

let degreesToRadians = (deg) => deg * RADIANS_PER_DEGREE;
let radiansToDegrees = (rad) => rad / RADIANS_PER_DEGREE;

時刻と持続時間

セキュリティ上の理由から、DOMHighResTimeStamp は通常、フィンガープリントやタイミングベースの攻撃で使用されないようにするために、クロックに少しの不正確さを導入します。

WebXR のすべての時刻と持続時間は、{{domxref("DOMHighResTimeStamp")}} 型を使用して測定します。 これは、開始時刻を基準にミリ秒単位で時刻を指定する倍精度浮動小数点値です。 値は浮動小数点数であるため、プラットフォームとハードウェアによっては、ミリ秒レベルよりも正確である場合があります。

時刻は主に、シーンの前のアニメーションフレームが描画されてからの経過時間を決定するために使用します。 そのため、時刻は通常、ディスプレイのリフレッシュレートに同調し、パフォーマンスの問題によりフレームレートを制限する必要がある場合は、その一部に同調します。 これは、60 FPS のフレームレートを想定して、時刻は通常 1/60 秒の間隔で進むことを意味します。 計算すると、これは各フレームが 16.6667 ミリ秒間隔で理想的にレンダリングされることを意味することがわかります。

行列を使用した幾何学操作

以下に、3D シーンのレンダリング時に実行する必要がある3つの主要な変換に行列を使用する方法など、3D 幾何学に関連する行列数学のガイドを提供します。

変換が点に適用されると言うとき、その延長線上で考えると、点の集まりに適用できることに注意してください。 オブジェクトは空間内のいくつかの点で構成されるいくつかのポリゴンで表されるため、オブジェクトを構成するすべての点に同じ変換を適用すると、オブジェクト全体に同じ変換が適用されます。 ベクトルは座標値を使用して記述され、ベクトルの方向と大きさを定義するため、変換をベクトルに適用することもできます。

空間の原点について

完全な XR 拡張シーンは、仮想であれ拡張であれ、1から数十の基準系を合成したものです。 位置と方向のデータを WebXR システムと直接交換する必要があるシーン内の各オブジェクトは、シーン内の他のオブジェクトが理解できるように、必要に応じて理解および適応できる方法でその情報を報告できる必要があります。

拡張現実(AR)では、これは、仮想オブジェクトを現実の世界に挿入する必要があるためです。 仮想オブジェクトを正しく配置するだけでなく、ユーザーの視点が変化しても、仮想オブジェクトが自分でさまよっているように見えないようにします。 仮想現実(VR)では、不快感やもっと悪いことを引き起こす可能性のある分離や切断を防ぐために、ユーザーの動きが仮想ディスプレイに表示される画像と正確に一致する空間感覚を作り出すことがすべてです。

したがって、それは空間感覚を作り出すことがすべてです。 XR 開発者の観点から見ると、ステージの設計はユーザーにとって最も重要な部分です。 建築家やセットデザイナーのように、あなたは物理的な環境を通して気分や体験を生み出す力を持っています。 その空間をどのように構築するかは、ユーザーがどのように対話して探索できるかに依存し、影響を与えます。

空間には通常、前景、中距離、背景の要素があります。 適切なバランスは、ユニークな存在感を生み出し、ユーザーを導くことができます。 前景には、直接対話できるオブジェクトとインターフェイスが含まれています。 中距離には、ある程度対話できるオブジェクト、またはより密接に調査して関与するために近づくことができるオブジェクトが含まれます。 一方、背景は通常、少なくともユーザーが中距離または前景の範囲に移動して近づくことができない限り、ほとんどまたは完全に非対話です。

WebXR では、(シーンが起こる座標空間など)空間(space)の基本的な概念は、{{domxref("XRSpace")}} のインスタンスによって表されます。 この空間は、ユーザーの環境内のオブジェクトと(光源やカメラなど)他のエンティティの相対位置と動きを決定するために使用します。

3D 空間内の点は、前述のとおり、3つの成分で構成され、それぞれが3つの軸の1つに沿った点の距離を識別します。 世界内の特定の点の位置は、3つの軸が交わる位置である空間の中心からその点が位置する3つの軸のそれぞれに沿ってどのくらい離れているかを示すことによって記述されます。

これは空間のネイティブの原点(native origin)であり、ユーザーの環境内の特定の物理的な場所に対応しています。 各空間には、XR デバイスの追跡システムによって追跡される独自のネイティブの原点があります。 これは、空間のローカル座標系の原点である実際の原点(effective origin)とは異なる場合があります。

座標系の方向性を次の図に示します。

WebGL および WebXR で使用される座標系を示す図。

原点オフセット(origin offset)と呼ばれる {{domxref("XRRigidTransform")}} を使用して、点を空間自体の実際の座標系から XR デバイスのネイティブ座標系に変換します。 通常、2つの原点は空間が最初に確立されるときに位置合わせされるため、原点オフセットは最初は単純に恒等変換です。 ただし、位置合わせの変化は時間とともに蓄積されるため、補正するために原点オフセットが変化する場合があります。

原点に対する空間内の点の位置は、上の図に示す3つの空間軸のそれぞれに沿った点の距離を決定することによって決定されます。 空間の原点は、空間の中心にあり、各軸に沿ってゼロの位置にある点 (0, 0, 0) です。 具体的には、初期の開始条件の下で、空間に対するビューアーのデフォルトの向きを使用します。

すべてのオブジェクトは、最も単純なレベルでは、3D 空間内の点とオフセット変換によって定義される一連のポリゴンであり、オブジェクトを移動および回転して空間内の目的の点に配置する方法を示します。 オフセット変換が単位行列の場合、オブジェクトは原点に配置されます。

ただし、空間追跡やシーン幾何学に役立つためには、XR デバイスの知覚位置を空間の座標系と相関させる必要があります。 そこで参照スペースの出番です。

参照空間

さまざまな XR ハードウェアが利用可能であり、多くの開発者からさまざまなフォームファクターで提供されるため、開発者が使用している追跡技術と直接通信する必要があることを期待することは非現実的であり、拡張性がありません。 代わりに、WebXR デバイス API は、開発者がユーザーエクスペリエンスを計画し、それらのニーズを最もよく表す適切な参照空間を要求するように設計されています。 これは、これらのニーズに一致する {{domxref("XRReferenceSpace")}} を{{Glossary("user agent","ユーザーエージェント")}}に要求することによって行われます。

XRReferenceSpace オブジェクトは、1つの座標系の基準系を別の座標系の基準系に適合させる手段として機能します。 ヘッドセットを装着した後、あなたの周りの仮想世界が、あなたの位置が (0, 0, 0) である座標系を持っていると考えてください。 つまり、あなたはすべての中心にいます。 それは力強さを感じませんか? ヘッドセットに向かって 真正面が -Z 軸で、+Z が後ろにあります。 X は右が正、左が負です。 Y は下に行くと負、上に行くと正になります。 これは、XRシステムの使用開始時の空間におけるヘッドセットの位置を示し、原点 (0, 0, 0) は基本的には鼻梁に配置されています。 この空間が世界空間(world space)です。

次に、左手にある XR コントローラーについて考えます。 動きとその向きを報告する機能がありますが、ヘッドセットの位置や、より重要なことに、その座標系については何も知りません。 ただし、コントローラーにはその位置をアプリに報告する方法が必要です。 したがって、独自の座標系があります。 これは、入力イベントが発生したときにアプリに提供される参照空間です。 この参照空間は、コントローラーの座標をヘッドセットの座標にマップする方法を内部的に認識しているため、WebXR は座標を相互に変換できます。

XRReferenceSpace を作成すると、モーションと方向の追跡を一定のレベルでサポートし、空間がユーザーのヘッドセット、オブザーバーのヘッドセット、仮想カメラなどのビューアーを表す場合に、世界空間に対して空間の位置と向き方向を表す行列を取得できる {{domxref("XRViewerPose")}} を取得するためのメカニズムを提供します。

これはすべてブラウザーの処理責任であり、基盤となる各参照空間の能力に関係なく、一貫した振る舞いを提供します。 個々の XR デバイスがどれほど強力であったりシンプルであっても、WebXR を使用して記述されたコードは、利用可能なハードウェアの制限内で機能します。

選択する参照空間のタイプに関係なく、その型は {{domxref("XRReferenceSpace")}} または XRReferenceSpace から派生した型です。 {{domxref("XRReferenceSpaceType")}} 列挙で定義されている現在利用可能な参照空間タイプを以下に示します。

{{page("/ja/docs/Web/API/XRReferenceSpaceType", "Values")}}

このガイドの残りの部分では、アプリのニーズに適した参照空間を選択する方法について説明します。

参照空間を使用した空間関係の定義

環境に対するオブジェクトの位置と方向を参照したり、環境自体を制約したりするために一般的に使用される方法がいくつかあります。 そのために、WebXR は、参照空間(reference spaces)と呼ばれる標準空間のセットを定義します。 それぞれの標準空間は、ローカル空間の基準系の座標系を、それが存在する空間の座標系に関連付けるさまざまな手法をサポートしています。

ただし、使用している参照空間のタイプに関係なく、同じ関数を使用して座標を空間から親空間に変換できます。

参照空間タイプの選択

まず、使用する参照タイプを決定するプロセスの最も簡単なステップを説明しましょう。 使用する可能性が最も高い参照空間は、locallocal-floorunboundedbounded-floor です。

床レベルの参照空間

名前に -floor が含まれている参照空間タイプは、対応する非床空間と同じように機能しますが、ビューアーが地面またはその近く(常に上)の安全な場所に自動的に配置されるようにします。 これは、他に床が確立されていない限り、y 座標が常に 0 である平面です。 これらの空間タイプは、部屋の床が平らでない場合や、地上の高さが変化する床の場合、アバターの垂直位置の変更をサポートしないため、実行できません

主な参照空間タイプ

viewer 参照空間は、ビューアーの空間内の位置に対応します。 {{domxref("XRFrame")}} メソッド {{domxref("XRFrame.getViewerPose", "getViewerPose()")}} によって返される {{domxref("XRViewerPose")}} によって使用されます。 それ以外の場合、通常は直接使用されません。 唯一の実際の例外は、ウェブコンテンツ内で XR シーンをインラインで実行するときに viewer 参照空間を使用する可能性が高いことです。

local 参照空間は、通常、シングルルームなどの比較的小さなエリアを記述するために使用されます。 没入型セッションモード(immersive-vr または immersive-ar)を使用している場合は常に使用できるだけでなく、新しいセッションを要求するときに常にオプション機能に含まれます。 したがって、{{domxref("XRSystem.requestSession", "navigator.xr.requestSession()")}} によって作成されたすべてのセッションは、local 参照空間タイプをサポートします。

複数の部屋が含まれる可能性のある大きな領域を表すには、ビューアーの動きに制約を指定しない unbounded 参照空間タイプを使用できます。 ユーザーが特定の領域に移動できないようにする場合は、自分で処理する必要があります。

bounded-floor 参照空間タイプには、対応する床に制限されないタイプはありません。 ユーザーの XR ハードウェアが現実世界の空間内を移動することを許可し、それが可能である場合、bounded-floor 参照空間を使用すると、通過が許可され安全な領域の境界を明確に定義できるため便利です。 制限付き参照空間の使用の詳細については、制限付き参照空間の使用の記事を参照してください。

参照空間を使用してオブジェクトの位置と方向を記述することにより、WebXR は、基盤となる XR ハードウェアに関係なく、これらの記述に使用するデータの形式を標準化できます。 参照空間の構成は、空間のコンテンツを正しくレンダリングするために必要なビュー行列とオブジェクトポーズを提供します。

参照空間の確立

最上位の空間({{domxref("XRSession")}} のメソッド {{domxref("XRSession.requestReferenceSpace", "requestReferenceSpace()")}} を呼び出すことによって取得される空間)は、世界空間全体に使用される座標系を表します。 すべては基本的にこの座標系に関連付けられ、ユーザーの機器の位置と仮想世界の間の関係を表します。

WebXR を使用して、アノテーションによる世界の拡張から 360°動画再生、科学シミュレーション、仮想現実トレーニングシステムなど、想像できるあらゆるものに対応できますが、3D ビデオゲームを典型的な WebXR アプリケーションの例として取り上げましょう。 ゲーム世界の空間に立っているプレイヤーのアバターのモデルを考えてみましょう。 世界空間を基準にしてアバターを配置するには、世界の参照空間で定義された座標系を使用します。

プレーヤーを新しい位置に移動するには、すべての座標を書き換えるか、移動するたびに手動で変換を適用しますが、参照空間とそれらを相互に作成できるため、より簡単な方法があります。 プレーヤーのアバターの新しい位置と方向を表す {{domxref("XRRigidTransform")}} オブジェクトを作成してから、{{domxref("XRReferenceSpace")}} メソッド {{domxref("XRReferenceSpace.getOffsetReferenceSpace", "getOffsetReferenceSpace()")}} を使用して、新しい位置にアバターの視点を表す新しい参照空間を作成します。 これは、キーボードやマウスなどの非 XR デバイスを使用してプレーヤーのアバターを世界中に移動するためのサポートを実装する場合に特に便利です。

{{EmbedYouTube("nVSlQkSSQeQ")}}

新しく作成された参照空間を使用すると、アバターは同じ座標に留まることができますが、新しい位置に配置され(そして世界をその視点から見ることができるように)世界に現れます。 参照空間を使用してプレーヤーの視点を管理する方法の詳細については、の記事を参照してください。

私たちのゲームアバターの例の場合、アバター(または他の動いているクリーチャーや機械)が世界中を滑走する単純なブロブになることはまれです。 それらは通常、追加の形だけでなく、動く脚、歩くときに揺れる腕、回転したり素早く上下する頭、動き回る武器などの内部の動きも持っています。 標準の WebGL 手法を使用してこれらを実現し、位置決め行列または {{domxref("XRRigidTransform")}} オブジェクトで実際の原点に対して正しい位置にシフトします。

参照空間に関するデバイスの制限

一部の XR デバイスは、API が不足している機能を補うために努力しているにもかかわらず、特定の体験をサポートするように作成できないものもあります。 例えば、GearVR デバイスなどの基本的なヘッドセットを、ユーザーが実際の動きを追跡して環境を歩き回るのをサポートする必要があるアプリで機能させる方法はありません。

プログレッシブエンハンスメントをサポートし、それによってアプリまたはサイトの可用性を広げるには、必要な機能の量が最も少ない参照空間を選択するか、参照空間の取得の失敗を検出し、あまり強力でない代替手段で再試行するフォールバックメカニズムを提供します。

発生する互換性の問題は、VR のみのヘッドセットで immersive-ar モード(拡張現実セッション)をサポートできないのと同じくらい根本的なものであるか、XR セッションを作成しようとしたときに満たすことができない1つ以上の必須オプションの要求が含まれる場合があります。

XR セッションは、{{domxref("XRSystem.requestSession", "navigator.xr.requestSession()")}} メソッドを使用して作成します。 オプションのパラメーターの1つは、{{domxref("XRSessionInit")}} ディクショナリに準拠したオブジェクトであり、これを使用して、セッションがサポートする必要がある(または理想的にはサポートすべき)必須またはオプションの機能を指定できます。 現在サポートされているオプションは、標準参照空間を識別する文字列のみです。 これらを使用すると、コードを実行する前に、必要な、または優先する参照空間タイプをサポートできる WebXR セッションにアクセスできることを保証できます。

: 現在、{{domxref("XRSession")}} を作成するときに使用できるオプションは、使用または優先する参照空間のみです。 将来的には、より多くのオプションが利用可能になる可能性があります。

<<<--- 参照空間要件の表をここに挿入 --->>>

オブジェクトの配置と方向付け

アプリと WebXR API の間で交換されるすべての空間(位置、方向、および動き)情報は、フレームのレンダリング時に特定の空間に関連して表現されます。 それ以上の位置と方向の管理はユーザーと WebGL の間で行われますが、オブジェクトを 3D 世界に正しく配置するために、参照空間からの原点オフセットを利用します。

アニメーションフレームをレンダリングするときは、WebXR セッションの {{domxref("XRSession")}} オブジェクトの {{domxref("XRSession.requestAnimationFrame", "requestAnimationFrame()")}} メソッドを呼び出したときに指定されたコールバック関数が呼び出されます。 コールバックは、そのパラメーターの1つとして、フレームが発生する時刻を示すタイムスタンプを受け取り、対応するアニメーションフレームのすべてのレンダリングを実行する必要があります。

時刻値を増やしながらコールバックが繰り返し呼び出されると、コールバックは XR ハードウェアを使用して提示される一連のフレームを生成し、それによって 3D シーンがユーザーに表示されます。

アニメーションプロセスの詳細については、レンダリングと WebXR フレームアニメーションコールバックの記事を参照してください。

仮想空間でオブジェクトを配置、方向付け、移動する方法の例と、コードレベルでの詳細な説明については、移動、向き、モーションの記事を参照してください。

関連情報