🥽

VRゴーグルを付けたままの WebXR 開発の課題と解決のためのツール

2023/12/19に公開

こんにちは。株式会社 Topotal@sawa-zen です。Meta Quest 3 を買ってひさびさにデバイスの進化に感動して最近はもっぱら WebXR の開発を趣味で楽しんでいます。

TL;DR

  • immersive 状態のままでの開発は最高の体験だったが問題がいくつかあった
  • それらを解決するためにthree-fiber-webxr-toolboxというツールを作成した

感動の体験との出会い

WebXR の開発が楽しくツイッターで呟いていたら@wakufactoryさんと出会い色々教えていただきました。そしてそのやり取りの中でXRコンテンツに入りつつそのまま開発する手法を見つけだし感動したので、まずは下の動画をからその様子を見てみてください。

https://x.com/sawa_zen/status/1720827286356922525?s=20

この今までにない開発体験に震えました。まるで現実世界の物体を自分のコードを書き換えることで形や色を変えられるようになったかのような感覚。まるで私がこの世界の創造主になったかのような感覚です。

やり方

詳しいことは @wakufactory が記事にしてくださると思うので簡単にやり方を説明します。

  1. yarn dev したVRコンテンツの開発環境を ngrok で https で公開
  2. Meta Quest のブラウザでアクセスする
  3. VR or AR(immersive) に入る
  4. Meta Quest の Remote Display を立ち上げて開発PCのディスプレイを表示する

やや面倒な手順ですがこの4ステップで感動の体験ができるので一度体験してみてください!

そのままでは開発は苦しい

感動したのもつかのま、実際に開発をしてみるといくつかの問題にぶち当たりました。

1. エラーが発生すると immersive 状態が解除される

開発段階のコードなのでコードの保存時点ではランタイムエラーなど様々なエラーが発生します。するとその時点で WebGL contextが破棄されてしまい immersive 状態が解除されてしまいます。その都度再度 immersive に入り直すのも手間であり、最悪なことにこれが発生すると Remote Display の接続もなぜか切れます。

2. デバッグがしづらい

immersive 状態でコンソールログを見ようとしても見ることができません。USB でPCと接続したりエミュレーターを使用すればデバッグできるらしいのですが、私は自分が開発しているXRコンテンツに入り込んだまま開発ができることを重視しているので、これらの方法では満足できませんでした。

3. VR の場合手元が見えない

自分はブラインドタッチがやや苦手なため、視界の中にわずかにキーボードが入っていないと打鍵がしずらく、immersive 状態での開発がかなり難しいと感じました。そのためアプリの immersed にあるポータルの機能のようなものが必須です。


↑ immersed のポータル機能

4. Remote Display 表示中はXRコンテンツの操作ができない

Remote Display の表示中はコントローラーやハンドトラッキングの操作は Remote Display への操作として判定されてしまうため、開発しているXRコンテンツへの操作ができなくなるためその時だけブラウザにフォーカスする必要がありやや面倒でした。

ツールを作って解決することにした

これらの課題を three-fiber-webxr-toolbox というツールを作ることで解決することにしました。

three-fiber-webxr-toolbox
↑ ChatGPT にロゴを作ってもらった

three-fiber-webxr-toolbox は react-three-fiber 用の便利コンポーネント群です。このツールを使うと以下のような開発環境を構築できます。
https://www.youtube.com/watch?v=jAYIertq6jA

コンポーネント紹介

今回上の課題をそれぞれ解決するための3つのコンポーネントを開発しました。

1. XRErrorBoundary

これは「エラーが発生すると immersive 状態が解除される」の課題を解決するためのコンポーネントです。XRErrorBoundaryの子要素でエラーが起きた場合に別のviewを表示させます。そのため、エラーが catch されるため WebGL context が破棄されず immersive 状態を維持できます。

さらにエラーが起きた際は視界の前方にエラーウィンドウの Sprite を表示させます。

https://youtube.com/watch?v=t6UuxGYNb4Y

2. ConsoleProvider

これは「デバッグがしずらい」の課題を解決するためのコンソールの代替となるコンポーネントです。Provider の子要素のコンポーネントでは useConsole という hooks が使用できるようになります。 useConsole から pushMessage という関数が受けとり、文字列を引数に渡して実行することで空間内に表示されたコンソールパネルに文字列を出すことができます。

https://youtube.com/watch?v=-Ics3FgQ8GY

3. Portal

これは「VR の場合手元が見えない」を解決するためのコンポーネントです。その名の通り immersed のポータル機能のパクリです。このコンポーネントは AR 限定で動作します。やっていることは単純で AR 前提で作られたコンテンツを VR っぽく見せて手元だけ風穴を開けて見せています。

https://youtu.be/rM7_0A17NJ4

今後の展望

最後の「Remote Display 表示中はXRコンテンツの操作ができない」の課題を解決するためにコンテンツ内にPCの画面を表示するコンポーネントを開発しているのですが、WebRTC を使用したりとやや複雑なため本記事を書くまでに間に合いませんでした。この機能があってようやく完成になるので近々公開予定です。

まだまだ生まれたてなのでかなり怪しい部分が多いです。バグや不便な箇所も引き続き修正していきますので皆さんご期待ください。

Discussion