Mini-XR: 各社VR SDKの比較
今やっているC-WebGL(WebGLのCバインディング)と同様にWebXR Device APIのCバインディングも必要なので検討することにした。
...が、WebXR Device APIは雲行きが怪しく、ちょっとコレに100%賭けるのは危い気もしている。ひとまず、諸々比較してから考えることにする。
WebXR Device API
- 公式: https://www.w3.org/TR/webxr/
- 公式: https://immersive-web.github.io/
- 公式: https://immersive-web.github.io/webxr/
フレームベースで完全なpull型。つまり、全ての位置センサデータをframeとして受けとり、そのframeのデータを出力すること のみ できる。よってMini-XRも自然とこの方式のAPIとなる。
- secondary-view が仕様に組込まれている。PS VRで言うところの ソーシャルスクリーン 。
- 他のVR APIと異なり、projection matrixを任意個返却できるようになっている。これにより、 CAVE のような表示環境でも原理的には同じAPIを使用できる。
- マルチレイヤコンポジションが無い。ただし、拡張としてOculus browserに搭載されている。
- マスキングが無い。 ...こればっかりはどうしようも無い気もするが、メモリ帯域が厳しいモバイルではあった方が良いと思うんだけど。。
- FFRは
fixedFoveation
として定義されている https://immersive-web.github.io/webxr/#dom-xrwebgllayer-fixedfoveation
VR環境で運用することを考えると、マルチレイヤとコンポジションはどうしても追加したくなる。
ARは残念ながらARCoreとARKitに上手いオーバーラップが無い。
OpenXR
- 公式: https://www.khronos.org/openxr/
- 仕様: https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html
- リファレンスカード(処理の流れの概要): https://www.khronos.org/registry/OpenXR/specs/1.0/refguide/openxr-10-reference-guide.pdf
- 各社:
既にデファクトスタンダードと言って良い状況になっている。現状のVRプラットフォームで採用していないのはVive FocusのみでVive Focusも採用予定自体は表明している。
フレームベースだがpush型。
-
xrSyncActions
でセンサ値をpumpする必要がある -
xrLocateViews
APIでHMDトラッキング情報を取得する。 - 標準でマルチレイヤプロジェクションをサポートしている。
XrCompositionLayerProjectionView
にpose(方向ベクトル)とFOVの形で与える。 - 直接的にガーディアンを表現する拡張は現状無いようだが
XR_REFERENCE_SPACE_TYPE_STAGE
として有限サイズの矩形床をシステム側が定義することはできる。 - secondary-viewは仕様になく
XR_MSFT_secondary_view_configuration
拡張のみ。 - マスキングも拡張
XR_KHR_visibility_mask
。
OpenXRの特徴的なところとして、 "actionSet" と呼ぶ仕組みでゲームプレイ要素をある程度抽象化している点。VRコントローラでは従来型のコントローラのようにABXYボタンが標準化されて存在しているわけではないので、OpenXRでは文字列のpathベースで入力イベントを扱えるようにしている。 OSC に近い。
Oculus Quest
- 本家: https://developer.oculus.com/documentation/native/android/mobile-vrapi/
- OpenXR: https://developer.oculus.com/documentation/native/android/mobile-openxr/
- SDK: https://developer.oculus.com/downloads/native-android/
Oculus QuestはOpenXRと独自のVrApiの両方をサポートし、更に、専用のオーディオエンジンも提供している。 FIXME: 課金系は?
フレームベース ではない 。アプリケーションは任意のタイミングでデバイスポーズを取得し、そのポーズに対してレンダリングできる。フレームのサブミッションはOpenXRに近い(というか多分Oculusの方が元祖だろう)。
- APIは ガーディアン (PS VRで言うところのプレイエリア)をサポートしている。ジオメトリを取得可能で、ヒットしているかどうかの直接クエリもできる。
- デバイスポーズは直近の値を取得する他システムに絶対時間を与えて予測させることもできる。
- 色空間として Rec.2020 を推奨している 。
- Eyeごとに ProjectionMatrix、ViewMatrix を直接受けとる
- マルチレイヤもOculusが元祖。
- リフレッシュレートを最大120Hzに設定できる 。
- マスキングはない。
Foveated Rendering( 中心窩レンダリング )をどう処理しているのか読みとれなかった。ドキュメント的には暗黙にやってそうだけど、システム側はRenderTargetを知る方法が無いから手動で GL_QCOM_texture_foveated
等を設定するしか無いんでは。。暗黙なのはリプロジェクションだけとか。。?
EDIT: 独自APIは廃止予告された。
Vive Focus
- 本家(Wave): https://developer.vive.com/jp/wave/
- 本家: https://hub.vive.com/storage/docs/en-us/index.html
- 本家: https://developer.vive.com/resources/vive-wave/
Vive Focusはちょっと特殊で、Android搭載のスタンドアロンVRデバイス向けのSDKとしてVive Waveが存在し、それを実装したハードウェアがVive FocusシリーズなのでSDKはVive Waveのものを使用することになる。
Vive Waveが特徴的なのは、SDKにコンポジションやコントローラエミュレーションを行う.apkが同梱されていて、これらを使用しての開発を可能にしている点。ただしSnapdragon搭載機を推奨してはいる。
フレームベース ではない 。アプリケーションは任意のタイミングでデバイスポーズを取得できる。
- バッテリ状態のクエリができる。サーマルも欲しいところか。。
- プレイエリアは Arena と呼ばれる。アリーナの形状は地面上の円形または矩形。
- Eyeごとに ProjectionMatrixを直接受けとる 。
- リプロジェクションは マルチレイヤ合成を直接サポートしている 。
- Foveated Renderingは 設定APIを提供している 。
- 2D要素の描画用に Overlay が存在する。Oculusほどの柔軟性はない。
- デバイスのトラッキングについて、人間の体形状、つまり 首 や 腕 の長さでconstraintするかを選択できる。
- Recenterの制御用APIが存在する 。(Oculusにも有るがDeprecateされている)
Pico
- 本家: https://developer.pico-interactive.com/
- OpenXR: https://sdk.picovr.com/docs/OpenXRMobileSDK/en/chapter_one.html
- Native SDK: https://sdk.picovr.com/docs/NativeSDK/en/index.html
最近Neo 3も投入 され、スタンドアロンVRヘッドセットとしては第三勢力となりつつあるPicoは、OpenXRを基本にネイティブSDKも持っている。
... ちょっとドキュメントがアレで機能性はわからない。
- Native APIは.aarで提供されJava I/Fのみが存在するように見える。実際にはいくつかのAPIはC I/Fも存在するっぽいが多分OpenXRなりUnity統合なりを使うべきなのだろう。。
- 任意のタイミングでHMDポーズを取得できるが、 予測は表示タイミングが何ms後かを指定する という割と独特な方法になっている。いわゆるリプロジェクションが無い。。? ...の割には
nativeSetRenderPose
ではレンダリングしたposeを指定できる。 - レンダリングするfovをクライアントが設定できる。ただし
onResume
タイミングでしか効かないと注釈されている。また、中央の場所を指定する方法がない。通常は4方向(in, out, up, down)のtangentで指定するが、PicoのAPIは横FOVと縦FOVしかない。
CEDECでの講演が出た。