WebXRでWeb小説サイトのVR対応に夢をみた

これは はてなエンジニア - Qiita Advent Calendar 2024 - Qiita の18日目の記事です。

昨日はid:r4wxiiさんによる AGP 8.4以降でアプリがクラッシュするようになった話 でした。


夢は夢のまま

この記事は VRWebGL の知識が皆無な人が書きました。

ドラえもんの)あたたかい目で見守ってください。

背景

課題

皆さんは寝る前に、スマホを見ていますか?

私はよくベッドで横になりながら、手に持ったスマホでWeb小説を読んでいます。 何時間も続けて読むと、首や肩がガチガチに凝るので困っています。

ちなみにこの画像は GPT-4o mini に描いてもらいました。

なぜか VR コントローラーを理解してくれずにゲームパッドになっています。

VR 端末

そこで考えたのが、VR 端末で上を向けば疲れないのでは?という案です。

(VRChat に造詣が深い人に出会ったら、上を向けば本当に疲れないか聞いてみたい)

手元にある PICO 4 の VR ブラウザを触ってみましょう。 公式の PICO Browser では Bluetooth で接続したキーボードが使えるらしく、スペースキーでスクロールもできました。

ブラウザのスクロールやページングは、 ジョイスティックやトリガーで画面をクリックすることで操作することができます。

スマホよりかは軽いとはいえ上を向いてウィンドウにカーソルを合わせる必要があり、 腕を上げてコントローラーやハンドジェスチャーを操作するのは疲れそうです...

WebXR

では、既存の Web サイトを VR コントローラーのボタン(A / B や X / Y)で操作することはできないのでしょうか?

Web の世界には WebXR と呼ばれる標準 API が提供されています。 レンダリングでは WebGL が使われています。

developer.mozilla.org

そこで WebXR Device API について調べてみました。

通常の表示では VR コントローラーの入力がブラウザに吸われてしまいますが、
没入型 VR モード(immersive-vr)なら VR コントローラーの入力を扱うことができるみたいです。*1

方針

ということで、 既存の Web サイトをなるべく少ない工数で没入型 VR モードに対応させることができれば、 VR コントローラーのボタンだけで操作可能にできそうです。

GitHub - ergofriend/reimagined-sniffle

本物の Web アプリで遊ぶわけにはいかないので、 ダミーの小説サイトを用意したのでこれを弄っていくことにします。

A-Frame

aframe.io

A-Frame は HTML タグだけで構築することができるので、 最も工数を少なくすることができそうです。 (学習コストは無料ということにする)

最初は aframe-htmlmesh を使ってみました。 これは Three.js の HTMLMesh 実装を移植したもので、テキストの折り返しができません。

修正 p-r*2 があったので覗いてみると、日本語には未対応で Intl.Segmenter で書き直すことがオススメされていました。

このまま行くと工数が膨らみそうなので、別の方針を検討します。

vr-lab.voyagegroup.com

その最中に aframe-html-shader の存在を知りました。 実体は html2Canvas を用いて HTML を画像にして、それをジオメトリに貼り付けるアプローチです。

aframe-html-shader は A-Frame の最新バージョンと相性が悪いのか?動作しなかったので、 直接 html2Canvas を用いて表示してみました。

字詰めなど要調整っぽいですが、ひとまずコンテンツを表示できたのでヨシとします。

HTMLMesh ➡️ html2Canvas

(余談ですが、エンジニアとして暮らす中で、何らかの課題を解決する手段として html2Canvas が候補に上がることが結構ある気がする)

in-VR navigation

aframe.io

ドキュメントにある gif をみて分かるように、没入型 VR モードを維持したままページ遷移をする機能が提供されています。

しかし手元の VR 端末(PICO 4)から試してみても、遷移するタイミングで没入型 VR モードが解除されてしまいました。

ドキュメントを改めて読むと、現時点では Oculus Quest のブラウザしかサポートしていないみたいです。

WebXR は発展途上も途上で、プラットフォームの独自色が大きいですね。

A-Frame まとめ

  • コンテンツを html2Canvas で表示することができた
  • ページ遷移時に没入型 VR モードが解除されてしまう

ということで、当初の没入型 VR モードを維持して VR コントローラーのボタンのみを利用した操作は難しいことがわかりました。

ページ遷移を防ぐために一つのページで完結するために自前のページングを実装する必要がありますが、これは工数がかかるのでやめておきます。

Babylon.js

www.babylonjs.com

気を取り直して、次は Babylon.js をみていきます。

GitHub - brianzinn/react-babylonjs: React for Babylon 3D engine

React 向けのラッパーもあるので、便利そうです。

HtmlMesh?

調べいくと HtmlMesh という機能があることがわかります。 iframeを指定すればサイト全体を表示することができ、自前のページングが不要になるので便利そうです。

しかし、意気揚々と没入型 VR モードに入ってみると、黒い画面しかありません。

Note that the use of HtmlMesh requires that the experience be accessed through a browser so in it's current form, this will not work in native apps or in XR - Babylon.js docs

ドキュメントを改めて読むと、没入型 VR モードでは動かないとありますね...

仕組みとしては、canvas を HTML上にオーバーレイすることで、擬似的な HtmlMesh を再現しているみたいです。 何を言っているか分かりませんが、変態的なことをやっていそうです。*3

これを HtmlMesh と呼ぶのはどうなんでしょうか...?

Babylon.js まとめ

  • React との相性は悪くはなさそう
  • 没入型 VR モードでは HtmlMesh が扱えないので、html2Canvas のアプローチになりそう

最後に、react-babylonjsVR 対応 & HtmlMesh の実装を供養しておきます...

結論

随分と遠回りをしてしまいましたが、WebGL では HTML を扱うことができないために様々な頑張りが必要そうです。

html2Canvas を使えば「理論上は可能」というやつですね! とはいえ、片手間では出来ないので VR 対応は夢のまま...

実際にやるなら、次のどちらかを検討することになりそうです。

A: 遷移しないページング機能を組み込んだ WebXR アプリを作る

  • Web のコンテンツと html2Canvas の一蓮托生でがんばる
  • A-Frame よりかは react-babylonjs が扱いやすそう
  • コンテンツをページングできる API があれば比較的簡単そう

↑画像しかないなら一から作るのと変わらない気がするので、どうせ Web をやるなら react-three-fiber を触ってみたい

github.com

エコシステムが便利そうで気になっています

B: Unity や Unreal Engine でペライチの WebView を表示する VR アプリを作る

VRアプリ 開発 入門 簡単」🔍

土地勘がないので大変そう〜

もしくは Android XR を待つ?

おわりに

工数なしで VR 対応ができるなんて美味い話はありませんでしたが、 今回は WebXR 周りの現状について知ることができました。

普段開発している Web の延長線とはいえ、知らないことが多くて面白いですね。

ということは、ネイティブ VR アプリを始めればもっと面白くなる...?

Hyperbeam(2024/12/19 追記)

WebGL上でブラウザを表示できるサービス Hyperbeam といういうのを知りました。

主要なフレームワーク A-Frame, Babylon.js, react-three-fiber などをサポートしています。 SaaS なので実務への導入コストは高そうですが、便利そうですね。

docs.hyperbeam.com


明日の はてなエンジニア - Qiita Advent Calendar 2024 - Qiita の担当はid:tokizuohさんです