WebVR環境としての OculusQuest (2021)

この記事は [WebXR ( WebVR/WebAR ) Advent Calendar 2021](https://adventar.org/calendars/6556) の5日目の記事です。
前回の記事は、[SkyWayとA-Frameを組み合わせて360度WebVR会議システムを作る！](https://bagelee.com/programming/vr_conference_skyway_aframe/)でした。

# WebVRといえばOculus

Oculusが2018年5月にOculusGoを発売した時、標準でブラウザが搭載され、なんとWebVR(当時のWeb標準のAPI名称)に初めから対応していました。この時から、手軽に使えるWebVR環境としてOculusは不動の地位を築いています。

当時書いた記事はこちら。

https://qiita.com/wakufactory/items/98658e8d089386a7b073

最新のOculusQuest2でもこれは踏襲されて、Web標準のAPIがWebVRからWebXRに変わった時も、いち早く対応がなされ、その後様々な拡張も実験的に取り入れられて今に至ります。

この記事では、最新のOculusQuestのブラウザの状況と、WebXR対応について2021年版としてまとめてみます。

OculusはFacebookに買収され、FacebookからMetaに名前が変わってしまって、Oculusの名称もなくなろうとしていますが、以下はOculus,OculusQuestで統一します。また、OculusQuest,OculusQuest2も総称してOculusQuestとしています。


# 最新Oculusブラウザはここまで来た

2021年12月の段階で、OculusシステムはV35、OculusブラウザはV15となっています。Oculusブラウザはchromiumベースであり、chromiumのバージョンは95です。

ブラウザとしての中身は、chromiumそのものですので、Web標準の各種API等はほぼそのまま使うことができます。サブセットのブラウザでは無いところがポイントです。

ブラウザとしてのUIに関しては、まだ発展途上の部分もありますが、V15でブラウザのウインドウサイズの横幅に加えて高さが変えられるようになったことで、一応の完成に達したと言ってもいいでしょう。

最大サイズにした場合の有効論理ピクセル数は、1999x1079となっていて、Webアプリ等を利用する場合にも十分な広さが確保できます。

![com.oculus.shellenv-20211205-112508.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74838/e41e9ef7-deb2-738a-1462-0e87d610616c.jpeg)

さらにマルチタスク機能を有効にすると、ブラウザ３面まで横に並べて使えるので、かなり色々なことができる環境になったと言えます。

:::note info
OculusシステムV35の段階では、マルチタスクはβ版です。設定のテスト機能のところで有効にする必要があります。
:::

その他、開発する場合のターゲットブラウザとしてのポイントを以下にまとめておきます。

 - ウインドウの最大サイズ(内法)は1999x1079
 - コントローラのビームによる操作は、マウスとタッチの両方のイベントを発生する
 - 日本語フォントはNotoフォントのSerifとSans-serif(明朝とゴシック)が内蔵
 - inputのファイル選択では、ダウンロードフォルダの任意のローカルファイルを指定することができる

以上のように、Oculusブラウザは、普段使いのブラウザとしても、Webアプリを動かす環境としてもとりあえず十分と言えるでしょう。

# WebVR環境としてのOculusブラウザ

WebXR,WebVR,WebAR等の呼び方については、いろいろ混乱もありますが、こちらの記事に簡潔にまとめられています。

https://zenn.dev/ikkou/articles/c2832ccbe6a078

OculusQuestのブラウザは、WebXR Device APIのうち、VRのimmersiveなモードをサポートしています。

HMDを被ってVR空間内で見ているブラウザは、すでにVRのブラウザと言えるのですが、あくまで普通のPCやスマホのブラウザと同様に平面の画面上に描画されるものです。

WebXRでは、この平面の状態からさらに３６０度を使った空間に遷移できるのがWebVRということになります。英語ではimmersiveモードと言っていますが、日本語で適切な訳語が無いところがちょっと不便ではあります。

## WebGLのパラメータ

WebVRの3D表示のベースとなるのが当然ながらWebGLです。OculusQuestはハイエンドスマホと同等の性能を持っているので、WebGLによる表示性能もスマホ相当になります。

WebGL2の各種パラメータを以下に示しておきます。

<details><summary>WebGL2のパラメータ</summary><div>

```
VERSION = WebGL 2.0 (OpenGL ES 3.0 Chromium)
RENDERER = WebKit WebGL
SHADING_LANGUAGE_VERSION = WebGL GLSL ES 3.00 (OpenGL ES GLSL ES 3.0 Chromium)
MAX_VERTEX_ATTRIBS = 32
MAX_VERTEX_UNIFORM_VECTORS = 256
MAX_FRAGMENT_UNIFORM_VECTORS = 256
MAX_VARYING_VECTORS = 31
MAX_RENDERBUFFER_SIZE = 16384
MAX_TEXTURE_SIZE = 16384
MAX_COMBINED_TEXTURE_IMAGE_UNITS = 96
MAX_TEXTURE_IMAGE_UNITS = 16
MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16
MAX_ARRAY_TEXTURE_LAYERS = 2048
MAX_CUBE_MAP_TEXTURE_SIZE = 16384
MAX_DRAW_BUFFERS = 8
MAX_VIEWPORT_DIMS = 16384,16384
PACK_ALIGNMENT = 4
ALPHA_BITS = 8
DEPTH_BITS = 24
ALIASED_LINE_WIDTH_RANGE = 1,8
ALIASED_POINT_SIZE_RANGE = 1,1023
  
support extensions
EXT_color_buffer_float
EXT_color_buffer_half_float
EXT_float_blend
EXT_texture_filter_anisotropic
EXT_texture_norm16
OCULUS_multiview
OES_texture_float_linear
OVR_multiview2
WEBGL_compressed_texture_astc
WEBGL_compressed_texture_etc
WEBGL_compressed_texture_etc1
WEBGL_debug_renderer_info
WEBGL_debug_shaders
WEBGL_lose_context
WEBGL_multi_draw
WEBGL_multisampled_render_to_texture
```
</div></details>

## WebXR周辺の拡張機能

Oculusブラウザは、基本的なimmersiveモードの他に、WebVRに関わる各種の拡張機能もサポートしています。これら機能はまだWeb標準としてはdraftの段階だったりしますが、Oculusのブラウザでは積極的に先行実装が行われており、最新のAPIに触れることができます。

### コントローラの利用

OculusQuestのtouchコントローラは、通常のブラウザで使う場合はビームを出してポインティングデバイスとして使う使い方に限定されます。

immersiveモードでは、コントローラのボタンの状態や６DoFの位置情報等の情報を取得することができます。
仕様は [WebXR Gamepads Module - Level 1](https://www.w3.org/TR/webxr-gamepads-module-1/)

### ハンドトラッキング

手の指の１本一本まで取れるハンドトラッキングも、OculusQuestが先行して実装しています。
仕様は [WebXR Hand Input Module - Level 1](https://www.w3.org/TR/webxr-hand-input-1/) になります。

### WebXR Layer

3D表示の文字や画像のコンテンツは、３Dモデルの表面にテクスチャをマッピングする方法で表現されます。しかしこの方法では、各種の変換操作が多重に入るため、どうしても画質が劣化してしまう問題があります。

これを解決するために考案されているのが、WebXR Layerという機能です。これは画像や動画を3Dオブジェクトにマッピングするのではなく、VR空間内に直接表示することで画質を向上しようというものです。

これも、現在Oculusブラウザでは先行実装されていて、A-Frameでサンプルを見ることができます。普通のマッピングと比較すると明らかに画質が向上していることがわかります。

こちらの仕様は [WebXR Layers API Level 1 ](https://www.w3.org/TR/webxrlayers-1/)というものです。

### WebXR navigation API

immersiveモードで他のページや外部サイトに遷移しようとすると、一旦immersiveモードが解除され平面のブラウザ状態に戻ってしまいます。これだと、別サイトのVR空間を行き来するような場合に、没入感が損なわれてしまいます。

そこで考案されているのが、immersiveモードのままページ遷移ができるようになるAPIです。

こちらの仕様はまだproposalの段階なので、今後変わる可能性があります。 [WebXR navigation API](https://github.com/immersive-web/navigation)

Oculusブラウザでもまだテスト機能で、chrome://flags でフラグを設定しないとAPIが利用できない状態ですが、今後使えるようになってくることを期待したいと思います。

# ブラウザでバーチャルデスクトップ

PC/Macの画面をHMDで見ながら作業ができるバーチャルデスクトップ機能ですが、専用のアプリもいくつか出ていますが、ブラウザでできると、WebVRの開発やOculusネイティブのブラウザアプリとの併用が便利です。

以前は、Chrome remote desktopが使えていたのですが、chromeのバージョンが96になったあたりから使えなくなってしまいました。元々正式にサポートされていたものではないので仕方ないのですが残念です。

そこで代わりになるものとして、個人で開発されているもののようですが、ViRTCというサービスがあります。リモート側もクライアント側(Oculusブラウザ)もブラウザのみで、特別なソフトをインストールする必要もなく手軽に使えます。

https://virtc.app/

これは、まさにOculusQuestをターゲットにしているようで、当然ながら相性も良いようです。
WebRTCを使った画面共有なので、同一ネットワーク内のPC/Macのみですが、画面データはP2Pで共有されサーバに送信されることはないので安心して使えます。

ログイン等も必要ない代わりに、毎回リモート側でPINコードを発行してOculus側で入力しないとならないのがちょっと面倒ですが、とにかく手軽に使えるのがメリットです。

デフォルトでは、バーチャルデスクトップの表示が全画面モードになっていますが、settingsで変更できます。今では全画面モードより大きいウインドウサイズにできるので全画面モードにする必要もあまりないですね。

解像度的には、Oculusブラウザのサイズを目一杯広げれば、MacBookProの1440x900の画面でも十分実用になります。
![com.oculus.shellenv-20211205-112237.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74838/804e4bf9-a293-b3de-c2c6-a2db8d84ab83.jpeg)


バーチャルデスクトップをHMDで使うときに問題となるのが、キーボードの手元が見えない、ということがあります。ブラインドタッチができればあまり問題にはなりませんが、OculusQuestの場合は、パススルーのホーム画面があります。パススルーにすれば手元のキーボドの位置は十分に確認できるので不便はないでしょう。