1. 序論
Virtual Reality と Augmented Reality がより普及するにつれて、ユーザーがいる環境について より詳細な情報にアクセスできる新機能が native APIs によって導入されています。Depth Sensing API は、 そのような機能の 1 つを WebXR Device API にもたらし、WebXR を利用した体験の作者が、 ユーザーのデバイスからユーザー環境内の現実世界の geometry までの距離に関する情報を取得できるようにします。
この文書は、WebXR Device API および
WebXR Augmented
Reality Module 仕様に読者が精通していることを前提としています。これは、それらの上に構築され、
XRSessions
に追加機能を提供するためです。
1.1. 用語
この文書では、AR という略語は拡張現実を、VR という略語は仮想現実を表すために使用する。
この文書では、XR デバイスによって返されるか、API 自体によって返される、深度情報を含むバイト配列を
指す場合に、「depth buffer」、「depth buffer data」、「depth data」などの用語を同じ意味で使用する。
深度バッファの具体的な内容についての詳細は、仕様の data、
texture、
および texture
の各項目を参照されたい。
この文書では、ビューの左上隅を原点とし、X 軸が右方向に増加し、Y 軸が 下方向に増加する座標系を指す場合に、正規化ビュー座標という用語を使用する。
ネイティブ深度
バッファは、ネイティブ深度センシングによって生成される実装定義のストレージであり、
生の深度値を含む。これは CPU からアクセス可能な割り当て、またはネイティブ API テクスチャである場合があり、作者には直接公開されない。
これは幅、高さ、およびデータ形式を持ち、1 つの二次元レイヤー、または
同じサイズの複数の二次元配列レイヤーのいずれかで構成される。特定の XRView
に対して返される非レイヤー化ネイティブ深度バッファには、そのビューの深度値が含まれる。レイヤー化されたネイティブ深度バッファは、
取得された時点での XRSession
の
ビューのリストの各エントリーにつき 1 つの配列レイヤーを含まなければならず、それらのレイヤーは
同じ順序でそれらのビューに対応しなければならない。
ネイティブ深度
情報は、ネイティブ深度センシングを照会した実装定義の結果である。これには、
ネイティブ深度
バッファ、その値をメートルに変換するためのスケール係数、深度座標
変換行列、ならびにそのバッファを生成したセンサーの 投影行列および transform
が含まれる。
2. 初期化
2.1. Feature descriptor
アプリケーションは、適切な feature descriptor を渡すことで、XRSession で depth sensing を有効にするよう要求できます。 このモジュールは、depth sensing feature の新しい有効な feature descriptor として、新しい文字列 - depth-sensing を導入します。
デバイスが native depth sensing capability を公開している場合、そのデバイスは depth sensing feature を capable of supporting とされます。inline XR device は、depth sensing feature を capable of supporting として扱ってはなりません。
depth sensing feature は feature policy の対象であり、
要求元文書の origin で "xr-spatial-tracking" policy が許可されている必要があります。
2.2. 意図される depth type、data usage、および data formats
enum {XRDepthType "raw" ,"smooth" , };
-
"raw"の使用は、depth data に追加処理を 行うべきでないことを示します。 -
"smooth"の使用は、runtime が potential noise を除去するために depth texture に追加処理を行うべきであることを示します。
enum {XRDepthUsage "cpu-optimized" ,"gpu-optimized" , };
-
"cpu-optimized"の使用は、 深度データがXRCPUDepthInformationインターフェイスとのやり取りを通じて、CPU 上で使用されることを意図していることを示す。 -
"gpu-optimized"の使用は、 深度データがXRWebGLDepthInformationインターフェイス、または WebGPU 互換セッションの場合はXRGPUDepthInformationインターフェイスとのやり取りを通じて、GPU 上で使用されることを意図していることを示す。
enum {XRDepthDataFormat "luminance-alpha" ,"float32" ,"unsigned-short" , };
-
"luminance-alpha"または"unsigned-short"の data format は、API から取得された depth data buffers 内の項目が 16 bit unsigned integer values であることを示します。 -
"float32"data format は、API から 取得された depth data buffers 内の項目が 32 bit floating point values であることを示します。
次の表は、さまざまな data formats を利用できる方法を要約します:
| データ形式 | WebGL 形式 | WebGPU 形式 | 深度バッファエントリーのサイズ | CPU での使用 | GPU での使用 |
|---|---|---|---|---|---|
"luminance-alpha"
| LUMINANCE_ALPHA | サポートされていない | 8 ビットの 2 倍 | data
を Uint16Array
として解釈する
| WebGL で Luminance チャネルと Alpha チャネルを調べ、単一の値を再構成する。Luminance チャネルには最下位バイトが含まれる。 |
"float32"
| R32F | "r32float"
| 32 ビット | data
を Float32Array
として解釈する
| Red チャネルを調べ、その値を使用する。 |
"unsigned-short"
| R16UI | "r16uint"
| 16 ビット | data
を Uint16Array
として解釈する
| Red チャネルを調べ、その値を使用する。 |
"luminance-alpha"
データ形式は、XRGPUDepthInformation
とともに使用してはならない。
2.3. Session configuration
dictionary {XRDepthStateInit required sequence <XRDepthUsage >;usagePreference required sequence <XRDepthDataFormat >;dataFormatPreference sequence <XRDepthType >;depthTypeRequest boolean =matchDepthView true ; };
usagePreference
は、session に望まれる depth sensing usage を記述するために使用される、XRDepthUsage
の
ordered sequence です。
dataFormatPreference
は、session に望まれる depth sensing data format を記述するために使用される、XRDepthDataFormat
の
ordered sequence です。
depthTypeRequest
は、session に望まれる depth sensing type を記述するために使用される、XRDepthType
の
ordered sequence です。この要求はユーザーエージェントによって無視されてもよいです。
matchDepthView
は、depth information の view が XRView
と揃っていなければならないことを要求します。
これが true の場合、XRSystem
は current frame を反映する depth information を返すべきです。これが false の場合、XRSystem
は earlier point in time で capture された depth information を返してもよいです。
注: matchDepthView
が false の場合、作者は XRDepthInformation
からの view
を使用して reprojection を行うべきです。
XRSessionInit
dictionary は、新しい depthSensing
key を追加することで拡張されます。この key は XRSessionInit
では optional ですが、depth-sensing が
requiredFeatures
または optionalFeatures
のいずれかに含まれる場合は、提供されなければなりません。
partial dictionary XRSessionInit {XRDepthStateInit ; };depthSensing
depth sensing feature が required feature であるにもかかわらず、application が depthSensing
key を提供しなかった場合、ユーザーエージェントはこれを unresolved required feature として扱い、requestSession(mode, options)
promise を NotSupportedError
で reject しなければなりません。
optional feature として要求された場合、ユーザーエージェントはその feature request を無視し、新しく作成された session で
depth sensing を有効にしてはなりません。
depth sensing feature が required feature であるにもかかわらず、XRDepthStateInit
を用いて呼び出された finding supported configuration combination
algorithm の結果が null である場合、ユーザーエージェントはこれを unresolved required feature として扱い、requestSession(mode, options)
promise を NotSupportedError
で reject しなければなりません。
optional feature として要求された場合、ユーザーエージェントはその feature request を無視し、新しく作成された session で
depth sensing を有効にしてはなりません。
XRSession
が depth sensing を有効にして作成された場合、depthUsage、
depthDataFormat、
および depthType
attributes は、XRDepthStateInit
を用いて呼び出された finding supported configuration combination
algorithm の結果に設定されなければなりません。
depthActive
は true を既定値としなければなりません。
注: この algorithm の意図は、 preferences を最も制約の強いものから最も制約の弱いものへ処理することです。したがって、単一の item のみが示されている場合から items の処理を開始し、その後 multiple、最後に preference が示されていない場合を処理します。
-
depthStateInit で
depthTypeRequestkey が設定されている場合はそれに含まれる値を、そうでない場合は空の sequence を depthTypeRequest とします。 -
selectedType を
nullとします -
depthStateInit 内の
usagePreferencekey に含まれる値を usagePreference とします -
selectedUsage を
nullとします。 -
depthStateInit 内の
dataFormatPreferencekey に含まれる値を dataFormatPreference とします -
selectedDataFormat を
nullとします。 -
processingOrder を、(preferences, selection) pairs の sequence とします。ここで selection は前の手順で導入された variables の 1 つへの reference です: [(depthTypeRequest, selectedType), (usagePreference,selectedUsage),(dataFormatPreference,selectedDataFormat)]
-
processingOrder 内の各 (preferences, selection) について、 次の手順を実行します
-
preferences が単一の値のみを含む場合、selection をその値に設定します。
-
-
processingOrder 内の各 (preferences, selection) について、 次の手順を実行します:
-
selection が
nullでない場合、次の entry に進みます。 -
preferences sequence が空の場合、次の entry に進みます。
-
preferences 内の各 preference について、次の手順を実行します:
-
selectedType,selectedUsage,selectedDataFormat の他の値を伴う preference が、device の native depth sensing capabilities によって supported depth sensing configuration と見なされない場合、次の entry に進みます。
-
selection を preference に設定し、これらの nested steps を中止します。
-
-
processingOrder 内の各 (preferences, selection) について、 次の手順を実行します:
-
selection が
nullでない場合、次の entry に進みます。 -
selection を、selectedType,selectedUsage,selectedDataFormat の他の値を伴う preferred native depth sensing capability によって決定される値に設定します。
-
-
selectedType,selectedUsage,selectedDataFormat のいずれかが
nullの場合、nullを返し、これらの手順を中止します。 -
selectedType,selectedUsage,selectedDataFormat が device の native depth sensing capabilities によって supported depth sensing configuration と見なされる場合、 selectedType,selectedUsage,selectedDataFormat の depth sensing configuration を返し、これらの 手順を中止します。
-
depthTypeRequest が空の list でない場合、それを空の list に設定し、これらの手順を繰り返します。
-
nullを返し、これらの手順を中止します。
サポートされる構成の組み合わせを検索する際、
WebGPU 互換セッションについて、"gpu-optimized"
の使用と "luminance-alpha"
データ形式を組み合わせた構成を、サポートされる深度センシング構成と見なしてはならない。
注: ユーザーエージェントは、既存の使用法とデータ形式の すべての組み合わせをサポートする必要はない。これは、効率的な方法でデータを提供できるようにすることを意図しており、 基盤となるプラットフォームに依存する。この決定は、アプリケーション開発者に追加の負担を課すが、API の複雑さを隠蔽するライブラリを 作成することで軽減できる可能性があり、その場合はパフォーマンスが犠牲になる可能性がある。
深度センシング API をサポート可能なユーザーエージェントは、少なくとも
1 つの XRDepthUsage
モードをサポートしなければならない。深度センシング API をサポート可能なユーザーエージェントは、"luminance-alpha"
データ形式をサポートしなければならず、その他の形式をサポートしてもよい。
const session= await navigator. xr. requestSession( "immersive-ar" , { requiredFeatures: [ "depth-sensing" ], depthSensing: { usagePreference: [ "cpu-optimized" , "gpu-optimized" ], dataFormatPreference: [ "luminance-alpha" , "float32" ], }, });
partial interface XRSession {readonly attribute XRDepthUsage ;depthUsage readonly attribute XRDepthDataFormat ;depthDataFormat readonly attribute XRDepthType ?;depthType readonly attribute boolean ?;depthActive undefined ();pauseDepthSensing undefined (); };resumeDepthSensing
depthUsage
は、セッションが構成された際の深度センシングの使用法を表す。この属性が、
深度センシングが有効になっていないセッションでアクセスされた場合、ユーザーエージェントは InvalidStateError
をスローしなければならない。
depthDataFormat
は、セッションが構成された際の深度センシングデータ形式を表す。この属性が、
深度センシングが有効になっていないセッションでアクセスされた場合、ユーザーエージェントは InvalidStateError
をスローしなければならない。
depthType
は、セッションが構成された際の深度センシングの種類を表す。この属性が、
深度センシングが有効になっていないセッションでアクセスされた場合、ユーザーエージェントは InvalidStateError
をスローしなければならない。
ランタイムが単一の XRDepthType
のみをサポートする場合、またはその他の理由で depthTypeRequest
を無視した場合、これは null を返してもよい。
depthActive
は、現在の深度センシングのアクティブ状態を返す。この属性が、
深度センシングが有効になっていないセッションでアクセスされた場合、ユーザーエージェントは InvalidStateError
をスローしなければならない。
この値が false の場合、ユーザーエージェントは深度データの取得試行を拒否しなければならない。この
値が true の場合、ユーザーエージェントは有効な深度データまたは null を返してもよい。
resumeDepthSensing()
が XRSession
session に対して呼び出された場合、ユーザーエージェントは次の手順を実行しなければならない。
-
session の
endedの値がtrueの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
frame を session の アニメーションフレームとする。
-
frame の active ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
depth-sensing 機能記述子が、session の XR デバイスの、session の モードに対する 有効化された機能のリストに含まれて いない場合、スローする
NotSupportedErrorとしてこれらの手順を中止する。 -
深度センシングのアクティブ状態が
trueの場合、これらの手順を中止する。 -
深度センシングのアクティブ状態を
trueに設定する。
pauseDepthSensing()
が XRSession
session に対して呼び出された場合、ユーザーエージェントは次の手順を実行しなければならない。
-
session の
endedの値がtrueの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
frame を session の アニメーションフレームとする。
-
frame の active ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
depth-sensing 機能記述子が、session の XR デバイスの、session の モードに対する 有効化された機能のリストに含まれて いない場合、スローする
NotSupportedErrorとしてこれらの手順を中止する。 -
深度センシングのアクティブ状態が
falseの場合、これらの手順を中止する。 -
深度センシングのアクティブ状態を
falseに設定する。
3. Depth data の取得
3.1. XRDepthInformation
[SecureContext ,Exposed =Window ]interface {XRDepthInformation readonly attribute unsigned long ;width readonly attribute unsigned long ; [height SameObject ]readonly attribute XRRigidTransform ;normDepthBufferFromNormView readonly attribute float ; };rawValueToMeters XRDepthInformation includes XRViewGeometry ;
width
属性は、depth buffer の幅(すなわち列数)を含みます。
height
属性は、depth buffer の高さ(すなわち行数)を含みます。
normDepthBufferFromNormView
属性は、depth buffer
に index する際に適用する必要がある XRRigidTransform
を含みます。
その matrix が表す transformation は、coordinate system を normalized view coordinates から
normalized depth buffer coordinates に変更し、それを depth buffer の width
および height
で scale することで、absolute depth buffer coordinates を得られるようにします。
注: applications が結果の depth buffer を mesh の texturing に使用する意図がある場合、mesh vertices の texture coordinates が normalized view coordinates で表現されていること、または適切な coordinate system change が shader 内で実行されることを確保するよう注意しなければなりません。
rawValueToMeters
属性は、depth buffer
からの raw depth values を meters 単位の depth にするために掛けなければならない scale factor を含みます。
transform
は、関連付けられた view の reference
space 内で与えられます。
sensor
が関連付けられた view と揃っている場合、XRViewGeometry
から含まれるすべての値は、関連付けられた view が返すものと同じ値を返さなければなりません。
各 XRDepthInformation
は、関連付けられた view を持ち、これは sensor に最も近い XRView
であり、XRDepthInformation
を取得するために使用されます。
各 XRDepthInformation
は、関連付けられた sensor を持ち、これは depth information が取得された
XRViewGeometry
の containing object です。
各 XRDepthInformation
は、関連付けられた depth buffer を持ち、これは depth buffer data を含みます。
異なる XRDepthInformation
は、depth buffer 内に異なる concrete types の objects を格納することがあります。
XRDepthInformation
またはそれを継承する任意の interface の depth buffer にアクセスしようとする とき、
ユーザーエージェントは次の手順を実行しなければなりません:
-
depthInformation を、member がアクセスされた instance とします。
-
depthInformation の view を view とします。
-
view の frame を frame とします。
-
frame が active でない場合、
InvalidStateErrorを投げ、これらの手順を中止します。 -
frame が animationFrame でない場合、
InvalidStateErrorを投げ、これらの手順を中止します。 -
depthInformation の member にアクセスするために必要な通常の手順を続行します。
3.2. XRCPUDepthInformation
[Exposed =Window ]interface :XRCPUDepthInformation XRDepthInformation { [SameObject ]readonly attribute ArrayBuffer ;data float (getDepthInMeters float ,x float ); };y
data
属性は、必要であれば WebGL texture へ upload するのに適した raw format の depth buffer information を含みます。
data は padding なしの row-major format で格納され、各 entry は sensor の near plane から
users' environment までの距離に対応し、
単位は unspecified です。各 data entry のサイズと type は depthDataFormat
によって決定されます。
値は rawValueToMeters
を掛けることで unspecified units から meters に変換できます。
normDepthBufferFromNormView
は、normalized view coordinates から depth buffer の coordinate
system へ transform するために使用できます。アクセス時には、depth buffer にアクセスする
algorithm を実行しなければなりません。
注: Applications は data
array の内容を変更しようとすべきではありません。これは getDepthInMeters(x, y)
method によって返される結果を不正確にする可能性があるためです。
getDepthInMeters(x, y)
method は、obtain depth at coordinates するために使用できます。呼び出されたとき、
depth buffer にアクセスする algorithm を実行しなければなりません。
getDepthInMeters(x, y)
method が、x, y とともに XRCPUDepthInformation
depthInformation 上で呼び出されたとき、ユーザーエージェントは次の手順を実行して
obtain depth
at coordinates しなければなりません:
-
depthInformation の view を view、view の frame を frame、そして frame の
sessionを session とします。 -
x が
1.0より大きい、または0.0より小さい場合、RangeErrorを投げ、これらの手順を中止します。 -
y が
1.0より大きい、または0.0より小さい場合、RangeErrorを投げ、これらの手順を中止します。 -
normalizedViewCoordinates を、space 内の 3-dimensional point を表す vector とします。 その
xcoordinate は x、ycoordinate は y、zcoordinate は0.0、wcoordinate は1.0に設定されます。 -
normalizedDepthCoordinates を、normalizedViewCoordinates vector を depthInformation の
normDepthBufferFromNormViewによって左から premultiply した結果とします。 -
depthCoordinates を、normalizedDepthCoordinates を scale した結果とします。
xcoordinate は depthInformation のwidthで乗算され、ycoordinate は depthInformation のheightで乗算されます。 -
depthCoordinates の
xcoordinate の値を integer に切り捨て、[0, width-1]integer range に clamp したものを column とします。 -
depthCoordinates の
ycoordinate の値を integer に切り捨て、[0, height-1]integer range に clamp したものを row とします。 -
row に
widthを掛け、column を加えた値と等しいものを index とします。 -
index に depth data format のサイズを掛けたものを byteIndex とします。
-
data内の index byteIndex にある値を、session のdepthDataFormatに従って number として解釈したものに等しいものを rawDepth とします。 -
depthInformation の
rawValueToMetersに等しいものを rawValueToMeters とします。 -
rawDepth に rawValueToMeters を掛けた値を返します。
partial interface XRFrame {XRCPUDepthInformation ?getDepthInformation (XRView ); };view
getDepthInformation(view) method は、XRFrame
上で呼び出されたとき、application が frame に関連する CPU depth information を取得 したいことを示します。
getDepthInformation(view)
メソッドが XRFrame
frame に対して XRView
view とともに呼び出された場合、ユーザーエージェントは次の手順を実行して CPU 深度情報を取得しなければならない。
-
session を frame の
sessionとする。 -
depth-sensing 機能記述子が、session の XR デバイスの、session の モードに対する 有効化された機能のリストに含まれて いない場合、スローする
NotSupportedErrorをスローし、これらの手順を中止する。 -
frame の active ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
frame の animationFrame ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
frame が view の frame と一致しない場合、スローする
InvalidStateErrorをスローし、これらの手順を中止する。 -
session の
depthUsageが"cpu-optimized"でない場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
depthInformation を、frame と view を与えて CPU 深度情報 インスタンスを作成した結果とする。
-
depthInformation を返す。
XRFrame
frame と XRView
view を与えて CPU 深度情報インスタンスを作成するには、
ユーザーエージェントは次の手順を実行しなければならない。
-
result を
XRCPUDepthInformationの新しいインスタンスとする。 -
time を frame の 時刻とする。
-
session を frame の
sessionとする。 -
device を session の XR デバイスとする。
-
depthActiveがfalseの場合、nullを返し、これらの手順を中止する。 -
nativeDepthInformation を、指定された view について、 session の
depthType、depthUsage、 およびdepthDataFormatを考慮して、time 時点で有効な深度情報を device に問い合わせることで取得した ネイティブ深度 情報とする。 -
nativeDepthInformation が
nullの場合、nullを返し、 これらの手順を中止する。 -
nativeDepthBuffer を nativeDepthInformation の ネイティブ深度バッファとする。
-
nativeDepthBuffer が深度データへのアクセスをブロックするためのユーザーエージェントの基準を満たす場合、
nullを返し、これらの手順を中止する。 -
nativeDepthBuffer が、深度バッファで利用可能な情報量を 制限するためのユーザーエージェントの基準を満たす場合、それに応じて nativeDepthBuffer を調整する。
-
result の
widthを nativeDepthBuffer の幅で初期化する。 -
result の
heightを nativeDepthBuffer の高さで初期化する。 -
result の
normDepthBufferFromNormViewを、nativeDepthInformation の 深度座標変換 行列に基づく新しいXRRigidTransformで初期化する。 -
result の
rawValueToMetersを nativeDepthInformation によって提供されたスケール係数で初期化する。 -
result の
dataを、nativeDepthBuffer から取得した view の生の深度値のコピーで初期化する。 -
result の ビューを view で初期化する。
-
result の
transformを、view の 参照空間における time 時点の センサーの姿勢で初期化する。 -
result を返す。
XRFrameRequestCallback
内で depth data を取得する方法を示します。
depth sensing が有効で、usage が "cpu-optimized" に設定され、data format が "luminance-alpha" に設定された
session であると仮定します:
const session= ...; // Session created with depth sensing enabled. const referenceSpace= ...; // Reference space created from the session. function requestAnimationFrameCallback( t, frame) { session. requestAnimationFrame( requestAnimationFrameCallback); const pose= frame. getViewerPose( referenceSpace); if ( pose) { for ( const viewof pose. views) { const depthInformation= frame. getDepthInformation( view); if ( depthInformation) { useCpuDepthInformation( view, depthInformation); } } } }
XRCPUDepthInformation
が取得されると、それを使用して view plane から user’s environment までの距離を調べることができます(詳細は
§ 4 結果の解釈 節を参照)。以下の code は
normalized view coordinates (0.25, 0.75) における depth を取得する例を示します:
function useCpuDepthInformation( view, depthInformation) { const depthInMeters= depthInformation. getDepthInMeters( 0.25 , 0.75 ); console. log( "Depth at normalized view coordinates (0.25, 0.75) is:" , depthInMeters); }
3.3. XRWebGLDepthInformation
[Exposed =Window ]interface :XRWebGLDepthInformation XRDepthInformation { [SameObject ]readonly attribute WebGLTexture ;texture readonly attribute XRTextureType ;textureType readonly attribute unsigned long ?; };imageIndex
texture
属性は、depth buffer information を opaque
texture として含みます。各 texel は、sensor の near plane から
users' environment までの距離に対応し、単位は unspecified です。各 data entry のサイズと type は depthDataFormat
によって決定されます。
値は rawValueToMeters
を掛けることで unspecified units から meters に変換できます。
normDepthBufferFromNormView
は、normalized view coordinates から depth buffer の coordinate
system へ transform するために使用できます。アクセス時には、depth
buffer にアクセスする algorithm を XRDepthInformation
について実行しなければなりません。
textureType
属性は、texture が TEXTURE_2D
型であるか、TEXTURE_2D_ARRAY
型であるかを記述します。
imageIndex
属性は、texture array への offset を返します。textureType
が TEXTURE_2D_ARRAY
と等しい場合は定義されなければならず、TEXTURE_2D
である場合は undefined でなければなりません。
partial interface XRWebGLBinding {XRWebGLDepthInformation ?(getDepthInformation XRView ); };view
getDepthInformation(view)
method は、XRWebGLBinding
上で呼び出されたとき、application が frame に関連する WebGL depth information を取得 したいことを示します。
getDepthInformation(view)
method が、XRWebGLBinding
binding 上で、XRView
view とともに呼び出されたとき、ユーザーエージェントは次の手順を実行して
WebGL
depth information を取得 しなければなりません:
-
binding の session を session とします。
-
view の frame を frame とします。
-
session が frame の
sessionと一致しない場合、InvalidStateErrorを投げ、これらの手順を中止します。 -
depth-sensing feature descriptor が、session の XR device の、session の mode に対する list of enabled features に contained されていない場合、
NotSupportedErrorを投げ、 これらの手順を中止します。 -
session の
depthUsageが"gpu-optimized"でない場合、InvalidStateErrorを投げ、これらの手順を中止します。 -
frame の active boolean が
falseの場合、InvalidStateErrorを投げ、これらの手順を中止します。 -
frame の animationFrame boolean が
falseの場合、InvalidStateErrorを投げ、これらの手順を中止します。 -
frame および view が与えられた WebGL depth information instance の作成 の結果を depthInformation とします。
-
depthInformation を返します。
XRFrame
frame と XRView
view を与えて WebGL 深度情報インスタンスを作成するには、
ユーザーエージェントは次の手順を実行しなければならない。
-
result を
XRWebGLDepthInformationの新しいインスタンスとする。 -
time を次のように初期化する。
-
XRSessionがmatchDepthViewをtrueに設定して作成された場合: - time を frame の 時刻とする。
- それ以外の場合
- time を device が深度情報をキャプチャした時刻とする。
-
-
session を frame の
sessionとする。 -
device を session の XR デバイスとする。
-
depthActiveがfalseの場合、nullを返し、これらの手順を中止する。 -
nativeDepthInformation を、指定された view について、 session の
depthType、depthUsage、 およびdepthDataFormatを考慮し、 time 時点で有効な深度情報について device の ネイティブ深度センシングに 問い合わせることで取得した ネイティブ深度 情報とする。 -
nativeDepthInformation が
nullの場合、nullを返し、 これらの手順を中止する。 -
nativeDepthBuffer を nativeDepthInformation の ネイティブ深度バッファとする。
-
nativeDepthBuffer が深度データへのアクセスをブロックするためのユーザーエージェントの基準を満たす場合、
nullを返し、これらの手順を中止する。 -
nativeDepthBuffer が、深度バッファで利用可能な情報量を 制限するためのユーザーエージェントの基準を満たす場合、それに応じて nativeDepthBuffer を調整する。
-
result の
widthを nativeDepthBuffer の幅で初期化する。 -
result の
heightを nativeDepthBuffer の高さで初期化する。 -
result の
normDepthBufferFromNormViewを、nativeDepthInformation の 深度座標変換 行列に基づく新しいXRRigidTransformで初期化する。 -
result の
rawValueToMetersを nativeDepthInformation によって提供されたスケール係数で初期化する。 -
result の ビューを view で初期化する。
-
result の
transformを、view の 参照空間における time 時点の センサーの姿勢で初期化する。 -
result の
textureTypeを次のように初期化する。- result の
textureが texture-array の textureType で作成された場合: - result の
textureTypeを "texture-array" で初期化する。 - それ以外の場合
- result の
textureTypeを "texture" で初期化する。
- result の
-
result の
imageIndexを次のように初期化する。textureTypeが texture の場合- result の
imageIndexをnullで初期化する。 - そうでなく、view の
eyeが"right"の場合 - result の
imageIndexを1で初期化する。 - それ以外の場合
- result の
imageIndexを0で初期化する。
-
result を返す。
XRFrameRequestCallback
内で深度データを取得する方法を示す。
セッションでは深度センシングが有効になっており、使用法が "gpu-optimized" に、データ
形式が "luminance-alpha" に設定されているものとする。
const session= ...; // 深度センシングを有効にして作成されたセッション。 const referenceSpace= ...; // セッションから作成された参照空間。 const glBinding= ...; // セッションから作成された XRWebGLBinding。 function requestAnimationFrameCallback( t, frame) { session. requestAnimationFrame( requestAnimationFrameCallback); const pose= frame. getViewerPose( referenceSpace); if ( pose) { for ( const viewof pose. views) { const depthInformation= glBinding. getDepthInformation( view); if ( depthInformation) { useWebGLDepthInformation( view, depthInformation); } } } }
XRWebGLDepthInformation
を取得すると、それを使用してビュー平面からユーザーの環境までの距離を求めることができる(詳細は § 4
結果の解釈の節を参照)。以下のコードは、
データをシェーダーに転送する方法を示す。
const gl= ...; // 使用する GL コンテキスト。 const shaderProgram= ...; // リンク済みの WebGLProgram。 const programInfo= { uniformLocations: { depthTexture: gl. getUniformLocation( shaderProgram, 'uDepthTexture' ), uvTransform: gl. getUniformLocation( shaderProgram, 'uUvTransform' ), rawValueToMeters: gl. getUniformLocation( shaderProgram, 'uRawValueToMeters' ), } }; function useWebGLDepthInformation( view, depthInformation) { // ... gl. bindTexture( gl. TEXTURE_2D, depthInformation. texture); gl. activeTexture( gl. TEXTURE0); gl. uniform1i( programInfo. uniformLocations. depthTexture, 0 ); gl. uniformMatrix4fv( programInfo. uniformLocations. uvTransform, false , depthInformation. normDepthBufferFromNormView. matrix); gl. uniform1f( programInfo. uniformLocations. rawValueToMeters, depthInformation. rawValueToMeters); // ... }
深度バッファを使用するフラグメントシェーダーは、たとえば次のように記述できる。
precision mediump float ; uniform sampler2D uDepthTexture ; uniform mat4 uUvTransform ; uniform float uRawValueToMeters ; varying vec2 vTexCoord ; float DepthGetMeters ( in sampler2D depth_texture , in vec2 depth_uv ) { // 深度はテクスチャの luminance 成分と alpha 成分にパックされる。 // テクスチャは、ミリメートル単位で格納する正規化形式である。 vec2 packedDepth = texture2D ( depth_texture , depth_uv ). ra ; return dot ( packedDepth , vec2 ( 255.0 , 256.0 * 255.0 )) * uRawValueToMeters ; } void main ( void ) { vec2 texCoord = ( uUvTransform * vec4 ( vTexCoord . xy , 0 , 1 )). xy ; float depthInMeters = DepthGetMeters ( uDepthTexture , texCoord ); gl_FragColor= ...; }
3.4. XRGPUDepthInformation
WebGPU 互換セッションでは、GPU 最適化された深度情報を、
XRGPUBinding
を介して XRGPUDepthInformation
として公開しなければならず、XRWebGLBinding
を介して XRWebGLDepthInformation
として公開してはならない。
各 XRGPUDepthInformation
には、関連付けられた非負整数の 配列レイヤーインデックスがあり、
これは、関連付けられたビューの深度情報を含む texture
の配列レイヤーを識別する。
[Exposed =Window ]interface :XRGPUDepthInformation XRDepthInformation { [SameObject ]readonly attribute GPUTexture ;texture GPUTextureViewDescriptor getViewDescriptor (); };
texture
属性には、XRGPUBinding
の
デバイスで作成された GPUTexture
として深度バッファ情報が含まれる。各テクセルは、センサーの近接平面からユーザーの環境までの距離に対応し、
単位は規定されていない。値に rawValueToMeters
を乗算することで、規定されていない単位からメートルに変換できる。normDepthBufferFromNormView
は、正規化ビュー座標から深度バッファの
座標系へ変換するために使用できる。この属性にアクセスした場合、XRDepthInformation
の深度バッファへのアクセスを試みるアルゴリズムを
実行しなければならない。
返されるテクスチャには、次のプロパティがある。
-
**dimension**:
"2d"。 -
**format**: § 2.2 意図される深度タイプ、データ使用法、およびデータ形式 の表において、セッションの
depthDataFormatに対応するGPUTextureFormat。 -
**width**: この
XRGPUDepthInformationのwidth。 -
**height**: この
XRGPUDepthInformationのheight。 -
**depthOrArrayLayers**: ネイティブ深度バッファ内の配列レイヤー数。 ネイティブ深度バッファがレイヤー化されていない場合は `1`。
-
**usage**:
TEXTURE_BINDING。 -
**mipLevelCount**: `1`。
-
**sampleCount**: `1`。
texture
に対して destroy()
を呼び出すと、その GPUTexture
を介したアクセスを終了しなければならないが、その基盤となる ネイティブ深度バッファを破棄または変更してはならない。
getViewDescriptor()
メソッドは、このオブジェクトの深度情報を含む texture
の部分について二次元ビューを作成するよう構成された GPUTextureViewDescriptor
を返す。
XRGPUDepthInformation
depthInformation に対して呼び出された場合、ユーザーエージェントは次の手順を実行しなければならない。
-
depthInformation を使用して、深度バッファへのアクセスを試みる アルゴリズムを実行する。
-
descriptor を新しい
GPUTextureViewDescriptorとする。 -
descriptor の
baseMipLevelを `0` に設定する。 -
descriptor の
mipLevelCountを `1` に設定する。 -
descriptor の
baseArrayLayerを depthInformation の 配列レイヤーインデックスに設定する。 -
descriptor の
arrayLayerCountを `1` に設定する。 -
descriptor を返す。
各 XRFrame
には、関連付けられた WebGPU 深度テクスチャのリストがあり、初期状態では空の リストである。
XR アニメーションフレームアルゴリズムを次のように拡張する。XRFrame
の
active ブール値を false に設定する直前に、
ユーザーエージェントは次の手順を実行しなければならない。
-
XRFrameの WebGPU 深度テクスチャのリスト内の各 texture について:-
texture の基盤となる ネイティブ深度バッファが 変更または再利用される前に、この
XRFrameの処理中に送信され、texture にアクセスするすべての WebGPU 処理が完了していることを確認するか、 同等の GPU 側の依存関係を使用して、その処理をネイティブ深度センシング実装と同期する。 -
texture の基盤となる ネイティブ深度バッファを破棄せずに、 texture に対して
destroy()を呼び出す。
-
-
XRFrameの WebGPU 深度テクスチャのリストを 空の リストに設定する。
注: 作者は、XRGPUDepthInformation
を取得した XRFrameRequestCallback
の実行中に、texture
を使用するすべての処理をエンコードして送信しなければならない。XRGPUDepthInformation
またはそのテクスチャを保持しても、テクスチャの存続期間は延長されない。
partial interface XRGPUBinding {XRGPUDepthInformation ?getDepthInformation (XRView ); };view
getDepthInformation(view) メソッドは、
XRGPUBinding
に対して呼び出された場合、アプリケーションがフレームに関連する WebGPU 深度情報を取得することを望んでいることを通知する。
getDepthInformation(view)
が XRGPUBinding
binding に対して XRView
view とともに呼び出された場合、ユーザーエージェントは次の
手順を実行して WebGPU 深度情報を取得しなければならない。
-
session を binding の セッションとする。
-
device を binding の デバイスとする。
-
frame を view の フレームとする。
-
session が frame の
sessionと一致しない場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
depth-sensing 機能記述子が、session の XR デバイスの、session の モードに対する 有効化された機能のリストに含まれて いない場合、
NotSupportedErrorをスローし、 これらの手順を中止する。 -
session の
depthUsageが"gpu-optimized"でない場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
device が破棄されている場合、
InvalidStateErrorをスローし、これらの手順を中止する。 -
frame の active ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
frame の animationFrame ブール値が
falseの場合、InvalidStateErrorをスローし、これらの手順を中止する。 -
depthInformation を、binding、frame、および view を与えて WebGPU 深度情報 インスタンスを作成した結果とする。
-
depthInformation を返す。
XRGPUBinding
binding、XRFrame
frame、および XRView
view を与えて WebGPU 深度情報インスタンスを作成
するには、ユーザーエージェントは次の手順を実行しなければならない。
-
result を
XRGPUDepthInformationの新しいインスタンスとする。 -
session を frame の
sessionとする。 -
xrDevice を session の XR デバイスとする。
-
gpuDevice を binding の デバイスとする。
-
time を次のように初期化する。
- session が
matchDepthViewをtrueに設定して作成された場合: - time を frame の 時刻とする。
- それ以外の場合:
- time を xrDevice が深度情報をキャプチャした時刻とする。
- session が
-
depthActiveがfalseの場合、nullを返し、これらの手順を中止する。 -
nativeDepthInformation を、指定された view について、 session の
depthType、depthUsage、 およびdepthDataFormatを考慮し、time 時点で有効な深度情報について xrDevice の ネイティブ深度センシングに問い合わせることで 取得した ネイティブ深度 情報とする。 -
nativeDepthInformation が
nullの場合、nullを返し、 これらの手順を中止する。 -
nativeDepthBuffer を nativeDepthInformation の ネイティブ深度バッファとする。
-
nativeDepthBuffer が、深度データへのアクセスをブロックするためのユーザーエージェントの基準を満たす場合、
nullを返し、これらの手順を中止する。 -
nativeDepthBuffer が、深度バッファで利用可能な情報量を 制限するためのユーザーエージェントの基準を満たす場合、それに応じて nativeDepthBuffer を調整する。
-
result の
widthを nativeDepthBuffer の幅で初期化する。 -
result の
heightを nativeDepthBuffer の高さで初期化する。 -
result の
normDepthBufferFromNormViewを、nativeDepthInformation の 深度座標変換 行列に基づく新しいXRRigidTransformで初期化する。 -
result の
rawValueToMetersを nativeDepthInformation によって提供されたスケール係数で初期化する。 -
format を、§ 2.2 意図される深度タイプ、データ使用法、およびデータ形式 の表において session の
depthDataFormatに対応するGPUTextureFormatとする。 -
arrayLayerCount を nativeDepthBuffer 内の配列レイヤー数とする。 nativeDepthBuffer がレイヤー化されていない場合は `1` とする。
-
arrayLayerCount が `1` の場合、arrayLayerIndex を `0` とする。それ以外の場合、 view の
indexとする。 -
arrayLayerIndex が arrayLayerCount より小さいことを表明する。
-
descriptor を、次のメンバーを持つ新しい
GPUTextureDescriptorとする。-
sizeを、幅が result のwidth、 高さが result のheight、 深さまたは配列レイヤー数が arrayLayerCount であるGPUExtent3Dに設定する。 -
mipLevelCountを `1` に設定する。 -
sampleCountを `1` に設定する。 -
formatを format に設定する。 -
usageをTEXTURE_BINDINGに設定する。 -
viewFormatsを空のシーケンスに設定する。
-
-
result の
textureを、descriptor を指定して gpuDevice.createTexture()を呼び出した結果で初期化する。ただし、GPUTextureの基盤ストレージは nativeDepthBuffer を参照するものとする。 -
result の 配列レイヤーインデックスを arrayLayerIndex で初期化する。
-
result の
textureを frame の WebGPU 深度テクスチャのリストに付加する。 -
result の ビューを view で初期化する。
-
result の
transformを、view の 参照空間における time 時点の センサーの姿勢で初期化する。 -
result を返す。
"gpu-optimized"
の使用法および "unsigned-short"
データ形式で構成された WebGPU 互換セッションから深度データを取得する方法を示す。
const adapter= await navigator. gpu. requestAdapter({ xrCompatible: true }); const device= await adapter. requestDevice(); const session= await navigator. xr. requestSession( "immersive-ar" , { requiredFeatures: [ "depth-sensing" , "webgpu" ], depthSensing: { usagePreference: [ "gpu-optimized" ], dataFormatPreference: [ "unsigned-short" ], }, }); const referenceSpace= await session. requestReferenceSpace( "local" ); const gpuBinding= new XRGPUBinding( session, device); const projectionLayer= gpuBinding. createProjectionLayer({ colorFormat: gpuBinding. getPreferredColorFormat(), }); session. updateRenderState({ layers: [ projectionLayer] }); function requestAnimationFrameCallback( time, frame) { session. requestAnimationFrame( requestAnimationFrameCallback); const pose= frame. getViewerPose( referenceSpace); if ( ! pose) return ; for ( const viewof pose. views) { const depthInformation= gpuBinding. getDepthInformation( view); if ( ! depthInformation) continue ; const depthTextureView= depthInformation. texture. createView( depthInformation. getViewDescriptor()); // このコールバック中に送信される WebGPU 処理で depthTextureView を使用する。 } } session. requestAnimationFrame( requestAnimationFrameCallback);
4. 結果の解釈
あるピクセルが 無効な深度データを持つと判断された場合、またはそれ以外の理由で深度データを判定できない場合、 ユーザーエージェントは深度値として 0 を返さなければならない。
data、
texture、
および texture
に格納された値は、カメラ平面から現実世界のジオメトリ(XR システムが認識しているもの)までの距離を表す。
以下の例では、点 a = (x, y) における深度値は、点
A からカメラ平面までの距離に対応する。具体的には、深度値は aA
ベクトルの長さを表すものではない。

上の画像は、次のコードに対応する。
// depthInfo は XRCPUDepthInformation 型である: const depthInMeters= depthInfo. getDepthInMeters( x, y);
5. Native device concepts
5.1. Native depth sensing
深度センシング仕様では、深度センシング API が実装される基盤となるネイティブデバイスが、
デバイスの ネイティブ深度センシング機能を照会する方法を提供することを前提としている。デバイスが ネイティブ
深度情報を取得する方法を公開している場合、そのデバイスは
デバイスのネイティブ深度センシング機能の照会をサポートするとされる。ネイティブ深度情報内の 深度座標変換行列は、正規化ビュー
座標から正規化深度バッファ座標への座標系変換を行い、変換された 3D ベクトルの z
座標には影響を与えないことが望ましい。
デバイスは 2 つの方法で 深度センシングタイプをサポートできる。デバイスが最小限の
後処理のみを施した推定深度値を返す場合、そのデバイスは "raw"
深度タイプをサポートするとされる。デバイスまたはランタイムが、このデータのノイズを「平滑化」するために追加処理
(たとえば、同じ深度値を持つより大きな領域にするなど)を適用できる場合、そのデバイスは "smooth"
深度タイプをサポートするとされる。
注: "Raw" 深度データには、多くの場合 信頼度値が付随する。UA は、そのようなデータをページに返す際、信頼度値が低い深度データを 無効な深度 データとして扱うことを選択できる。
デバイスは 2 つの方法で 深度センシングの使用法をサポートできる。デバイスが
主として CPU からアクセス可能なメモリを介して深度データを返すことができる場合、"cpu-optimized"
の使用法をサポートするとされる。デバイスが主として GPU からアクセス可能なメモリを介して深度データを返すことができる場合、
"gpu-optimized"
の使用法をサポートするとされる。
注: ユーザーエージェントは、両方の 使用モードをサポートすることを選択できる(たとえば、デバイスが CPU と GPU の両方からアクセス可能なデータを提供できる場合、 または CPU からアクセス可能なデータと GPU からアクセス可能なデータの間の転送を手動で行う場合)。
デバイスは、指定された深度センシングの使用法およびタイプについて、次の方法で 深度センシングデータ形式をサポートできる。指定された深度センシングの
使用法およびタイプにおいて、デバイスが 16 ビット符号なし整数を含むバッファとして深度データを返すことができる場合、
"luminance-alpha"
および "unsigned-short"
データ形式をサポートするとされる。指定された深度センシングの使用法およびタイプにおいて、デバイスが
32 ビット浮動小数点値を含むバッファとして深度データを返すことができる場合、"float32"
データ形式をサポートするとされる。
深度
センシング構成は、1 つの XRDepthType、
1 つの XRDepthUsage、
および 1 つの XRDepthDataFormat
の組み合わせによって表される。
デバイスが、指定された構成について 深度センシングタイプをサポートし、深度センシングの 使用法をサポートし、かつ 深度センシングデータ形式をサポートする場合、そのデバイスは 深度センシング構成をサポートするとされる。
注: 深度センシング API のサポートは、 AR 対応として分類されるハードウェアだけに限定されない。ただし、この機能はそのようなデバイスでより 一般的になると予想される。適切なセンサーを備えた VR デバイスや、その他の技術を使用して 深度バッファを提供する VR デバイスも、深度センシング API の実装に必要なデータを提供できるはずである。
depthTypeRequest、
usagePreference、
および dataFormatPreference
のそれぞれについて、デバイスは、対応する配列が空の場合に使用しなければならない 優先される ネイティブ深度センシング
機能を持たなければならない。タイプ、使用法、および形式は、相互に依存する場合があるものの、
デバイスにとって最も効率的なものを反映することが望ましい。
デバイスは 深度センシングのアクティブ状態を持つとされ、これは
深度センシング機能がアクティブに動作しているかどうかを表すブール値である。この状態は true で開始しなければならない。ユーザー
エージェントは、この状態が false の場合、この機能が有効になっていることによるパフォーマンスへの影響を
軽減するための措置を講じることが望ましい。
6. プライバシーおよびセキュリティに関する考慮事項
depth sensing API は、depth buffer という format で、ユーザー環境に関する追加情報を websites に提供します。 十分に高い resolution と十分に高い precision を持つ depth buffer が与えられると、websites はユーザーが 快適と感じる範囲を超える、より詳細な情報を潜在的に知ることができます。使用される underlying technology によっては、 depth data は camera image および IMU sensors に基づいて作成されることがあります。
ユーザーに対する privacy risks を軽減するため、user agents は session で depth sensing API を有効にする前に user consent を求めるべきです。さらに、depth sensing technologies および hardware が向上するにつれて、 user agents は API を通じて公開される information の量を制限する こと、またはそのような制限を 導入することが feasible でない場合、API から返される data への access を block する ことを考慮すべきです。information の量を制限するために、 user agents はたとえば、結果の depth buffer の resolution を下げたり、depth buffer 内に存在する値の precision を 下げたり(たとえば quantization によって)できます。そのような方法で data の量を制限することを決定した user agents は、それでもこの仕様を実装していると見なされます。
user agent が、device の cameras によって提供される情報と等価になるほど詳細な depth buffers を提供できる場合、 まず camera access を取得するために必要な consent と等価な user consent を取得しなければなりません。
変更点
First Public Working Draft 31 August 2021 からの変更点
7. 謝辞
次の個人が WebXR Depth Sensing 仕様の設計に貢献しました: