XRインターネット
電脳コイルのような世界を作りたい。1つの3D空間上で他人が作った様々なオブジェクトが動き回る世界を見てみたい。
そう思って色々やっているけど、技術的にも道のりは長いし、ビジネスとしてもなかなか難しいし、なかなかうまく進められんというところで、とりあえずメモ書きとかを集約してインターネットに公開してみようという試みです。
WebAssembly によるソーシャルVR/ARプラットフォーム
2018年12月3日
社内のアイディア用リポジトリより
第1段階: アイディアを思いついたら (Customer/Problem Fit)
まずは課題にフォーカスしよう. そのためには以下の問に答えよう.
1. 課題はなに?
- 現状の VR ではアプリ間で体験が途切れてしまう
- 視界が真っ暗になる
- アバターが維持されない
- 周囲の状態が維持されない (友達のアバター、手に持ったものなど)
- VR アプリを作ること自体が困難
- アバターシステムやコントローラーの扱い、UI の仕組みを自分で実装する必要がある
- 実機デバッグが辛い
- ホットリロードできない
- PC 上でエミュレーションできない
- VRChat ではユーザーがワールドを作ることで複数の世界をシームレスに体験できるが以下の課題がある
- VRChat のワールドではインタラクティブな仕組みを作るのが困難 (スクリプトなどを自由に実行できない)
- 仕様やマイルストーンが不透明でワールドの維持が難しい
- Oculus Go 非対応
- VR ゴーグルでしか体験できない。スマホやPCからの簡易的な閲覧や参加が不可能
- 制作環境が Unity に限られる。仕様が不透明
- VRChat のワールドではインタラクティブな仕組みを作るのが困難 (スクリプトなどを自由に実行できない)
2. その課題に出会った原体験は?
- ドメモ開発
- 普段 VR で遊んでて
3. 誰(具体的な名前)がその課題を持っている?
- 自分
4. ↑の人は今どのようにしてその課題を解決してる?
- 頑張ってる
5. 課題の質は高い? 課題の質はそれを思いついた人の専門性で決まる.
- 課題に対する高い専門性を持ってる?
- VR, AR, Web に詳しい。WebAssembly には詳しくない
- その業界(現場)の知識を持ってる?
- ドメモVR開発中。モバイルアプリ・Web サービス開発、提供経験あり。
6. なぜ今やる?
- なぜ2年前、2年後ではなく今やるのか?
- 今苦しんでおり、ソリューションが無いため
- VRM を始めとした VR 周りの標準化・オープン化の流れがある
- メジャーブラウザが WebAssembly をサポートした
- まだそのようなソリューションを見たことがない
- なぜコベリンがやるのか?
- 偉いから
7. 他に誰か同じことをやっている?
- VRChat が一番近いが、あくまでアバターとそのワールドとしての位置づけ
- A-frame での WebVR が近いが、各 web サイトで体験が途切れている。javascript による簡易的なコンテンツに限られる
- Oculus プラットフォーム自体が近いが、体験間のつなぎ込みが無い。またクローズドな Unity SDK で提供されるのが気に入らない
第2段階: ソリューション (Problem/Solution Fit)
1. どうやって課題を解決する?
一言で言うと VR 用ブラウザー
- ブラウザ上で動作する VR/AR アプリケーション
- 他者が作ったコンテンツをロードして実行する機能がある
- WebAssembly をサポート
- 完全にSandbox化されているためセキュリティの問題に対処しやすい
- カメラアクセスなどのプライバシー制御を実装できる
- 非常に高速なため、いままでブラウザで出来なかったコンテンツが提供できる可能性がある
- モジュールごとの実行時コンパイル・ロードによってホットリロードが実現できる
- 完全にSandbox化されているためセキュリティの問題に対処しやすい
- WebAssembly をサポート
- アバター・コントローラー・UIシステムをデフォルトで提供する
- Web の HTML と同じように、デフォルトの要素があり、インタラクションできる
- WebAssembly によって挙動の制御やカスタマイズができる
- シームレスな体験の遷移
- ロードしたコンテンツが視界全体をいきなり覆わない設計
- 遷移をコントロールできるようにする (どこでもドアとして実装、ワープホールとして実装など。CSS+JS で a タグの挙動をコントロールできるようなもの)
- 他者が作ったコンテンツをロードして実行する機能がある
Web ブラウザーと Web サイトとの関係性に近い。
HTML + JavaScript で構成された任意の Web サイトを読み込める Web ブラウザーに対して、WebAssembly で構成された任意の体験を読み込めるアプリになっている。
しかし、WebAssembly のラインタイムやコントローラーの API を実装するのは非常に難しい。しかしそれらは全てブラウザが既に実装している。
作るべきもの
- 言語によらずに利用できる WebAssembly モジュールの API
- 何かを作るためには最終的にはブラウザの API にアクセスしなければならないが、そのバインディングが各言語ごとに作られている状態
- 他者が WebAssembly のバイナリだけで体験を構築できるようにするには、言語によらない API が必要
- 特に描画周り。現状では OpenGL を使うには Rust で実装されたバインディングを使うしか無いので言語の選択ができない
- UI 要素の実装
- コンテンツのロード機能
- コンテンツのドメインごとのプライバシー制御機構 (モバイルのカメラ許可ポップアップのようなもの)
2. それは質の高いソリューション?
- 質の高いソリューションは一見クレイジーに見える
かなりクレイジー 🤡
3. あなたしか知らない秘密(高い専門性)がある?
- WebVR/WebGL が結構イケてること
避けるべきアイデア
になっていない?
4. 避けるべきアイディアとは以下のようなもの.
- 誰が見ても最初から良いものに見えるもの -> どうだろう
- ニッチすぎる -> VR 制作の敷居を下げるもの。VRChat のワールドを作るために Unity を始める人もいる
- 自分が欲しいものではなく作れるものになっている -> 作るのは困難
- 根拠の無い課題 -> 自分は困ってるしこういうのほしいが、WebAssembly + ブラウザじゃなくても単にそういうことができる VRChat の代替品があれば満足するかもしれない
- 分析から生まれたアイデア -> ではない
- 例えば市場を分析して隙間があったからそこに他者と似たサービスを展開する。それだとうまくいかなかった時にピボットできずに終わる。
- 激しい競争に切り込むアイディア -> ソーシャル VR は各社が今仕込んでいると思われ、そこにあまり使われてない WebAssembly で切り込むのは挑戦的だと思う
- 一言で言い表せないアイデア -> VR 用ブラウザーと言える。実際はそれ自体がブラウザ上で動くものだが・・・
第3段階: モックアップ & 体験 (Problem/Solution Fit)
第4段階 (Problem/Solution Fit)
解決に値する課題と、その課題の最適な解決方法を見つける
2018年5月25日
社内 esa のアイディア置き場より
Unity を楽しくつかいたい
事業化とかじゃなくて単にアイディアのメモ(置き場所が欲しかった)
アイデアの簡単な内容
- Unity のシーンを React で書くぞ!
背景
GUI を JSX で書くと、エンジニア的な発想・ワークフローでフロントエンドが実装できて良いねというのが React で分かった。(diff が見やすい、lint とかテストとかできる等)
Unity でもそれができたらいいんじゃない?というアイディア
WhitestormJS という 3D フレームワークがある。
これを React スタイルで記述する react-whs というライブラリがあり、とても良いなぁと思った。
また、A-frame という Mozilla が作っている WebVR/AR 向けのフレームワークでは、HTML から 3D のシーンを生成するという面白い仕組みになっている。HTML が読める人工は非常に多いと思われ、これから VR/AR の制作が求められる現場で Web 担当者が A-frame を使って対応していくとかとてもありそうと思った。
例
上のようなシーンが次の JSX で記述できる
<Scene>
<HoloLensCamera />
<ARCamera />
<DirectionalLight />
<ImageTargetChips>
<Teapot color="gray" />
</ImageTargetChips>
<ImageTargetChips>
<Teapot color="brown" />
</ImageTargetChips>
</Scene>
タグ
Prefab をタグとして使え、シーンが Instantiate された時にこれらのタグが GameObject として Instantiate される。Prop には GameObject にアタッチされる Component に渡す情報や、Component そのものを指定する
Prefab ではなく、コードによってタグを作成できる。
擬似コード
const Cube = () =>
<GameObject transform={new Transform(position: Vector3())} meshRenderer={new MeshRenderer()}>
<Mesh mesh={createCubeMesh()} />
</GameObject>
2019年2月25日
社内 esa のアイディア進捗報告より
WebAssembly によるソーシャルVR/ARプラットフォーム
やったこと
そもそも WebAssembly でやるメリットがあるのか、どのような能力が WebAssembly にあるのかを知るため、言語仕様に詳しくなるためにインタプリタを実装した。
わかったこと
WebAssembly に期待していたもの
- 言語によらずに利用できる WebAssembly モジュールの API
- Dynamic Linkの仕組みがある。しかしstable ABIがないため事実上不可能
- 各言語のコンパイラ側での対応もまだできていない
- アバター・コントローラー・UIシステムをデフォルトで提供する WebAssembly モジュールを作る
- 可能だが、結局 JavaScript API を提供しなければいけないため、パフォーマンスの問題が大きく、WebAssembly でやる理由がない
知ったこと
- まともな WebAssembly 処理系は 2, 3 つくらいしかない
- テキスト形式のフォーマットは安定していなくてどんどん変わっている
- asm.js から来たプロジェクトということもあり、想定された用途はプログラムをまるごとすべて wasm として書き出すことであり、モジュールとして使うのは要望は多いが現状難しい
- JavaScript は結構早いので、WebAssembly で高速化される部分はあまり多くない
- JavaScript API を介してモジュール同士がやりとりするため、あえて wasm モジュール化するメリットがほとんど無い (今後 Dynamic Link がちゃんと実装されてきたら使えてくる)
振り返って
そもそも何が問題意識だったか
- Unity の開発体験が悪いことを意識していた
- エディタの改善を待てば良い
- ブラウザで動くワールドの仕組みが欲しい
- ブラウザで障壁を下げることはそこまで重要ではない気がしてきた。そもそもVRゴーグルを購入しているため
- ブラウザにこだわらなければ VRChat でやればいい
- できないことは何だったか
- 簡単にアバターとしてシーンに入れてマルチプレイできる仕組み (アバターシステムとゲームの分離)
- たぶん SpatialOS が解決しようとしてる部分 https://improbable.io/games
2022年1月31日
社内 esa のアイディア置き場より
概要
2018年頃から Unity での XR 開発につらみを解決したくて色々考えたりしていること
最近 Warp というプロジェクト名を付けた
変遷
2018年
Unity 上で WebAssembly で作ったスクリプトを動かせたらいいんじゃないかというアイディア
2019年
楽しかったけど、特に何か使える感じではなかった
2020年
Unity 上で WebAssembly を実行して、GameObject に反映する PoC。結局 WebAssembly 側から GameObject をいじるにはインターフェースを沢山作らないといけないので、手足が縛られた感じがすごかった。
任意のゲームのシーンを Unity Editor で見られて楽しい。
2021年
子育て忙し期。メモ帳に書き連ねるだけの日々。
2022年
やるべきはワークフローの改善と位置づけて、再ビルドが必要無い世界を目指し、Prefab をネットワーク越しに同期する仕組みの実装を開始
Problem についての思索
最初は考えがまとまっておらず、Unity での XR 開発ワークフローを改善したいという思いと、コンテンツのオープンスタンダードが必要だという思いがモヤモヤしていた。しかし、WebXR ではだめなのか、VRChat ではだめなのかという問いに答えられないでいた。
そして、自分の仕事含め、世の中は Unity で XR コンテンツを作るという方向に向かっており、そこに対してオープンな仕様や、WebAssembly の必要性という需要があるわけではないという考えに時間をかけて至った。
必要なものは、XR 制作における日々の業務フローを改善できるものであり、そのためには新たな言語やフレームワークは最小限にすべきであるとした。
そこで 2022/1/31 現在考えている Problem, Solution は次のようになる。
Problem
- 実機でのホットリロードができないため開発に時間がかかる
- ストア申請や APK 配布などが必要でアプリの変更をユーザーに届けるのが大変
Solution
「アプリのビルドを無くす」を目標とし、以下のソリューションを提供する
- Prefab の変更を実行中のプログラムに反映するシステム (第1段階)
- QR コード等からアプリを読み込むことができるクラウドサービスを提供する (第2段階)
- ローカルで動かしているもののホスティング版
- 事前に各ストアに配布された Runner アプリをインストールすれば、QR コード等からアプリを読み込むことができる
- またアプリの更新は即座に反映されるためストア申請などの必要がない
結果として、Vercel が提供するような Web 開発のベストプラクティスの XR への導入が実現される
Business model
Vercel や React Native Expo のようなビジネスモデルを構築する。つまり、開発中に必要なものはオープンソースであり無料であるが、そのシステムにワークフローが最適化されたクラウドサービスは有料である。
- 第1段階の、Prefab の変更を実行中のプログラムに反映するシステムはオープンソースとして実装する (Next.js や React Native に相当)
- 第2段階のクラウドサービスは有料 (Vercel や Expo に相当)
Market
- XR 開発を行う企業。特にホロラボの Spirare 作者のような、実機でのホットリロードができないことを不満に思う開発者
自己問答
- なぜ WebXR ではだめなんですか?
- ネイティブアプリが体験の一等地であり、Web は二等地であるから。そして XR 体験は、より高級な体験を求めて行われるから。なぜなら平面のディスプレイでは得られない没入感を求めているからであり、ヘッドセットなどユーザーの手間や金銭的な障壁を超えているため、二等地の WebXR を体験したいと思う理由がない
- Unity が備えている Addressables / AssetBundle の仕組みで十分ではないですか?
- Addressables や AssetBundle を利用することで、アプリのアップデートなしにネットワーク越しにリソースを更新することはできるが、これはゲームの DLC を作るためにあるようなもので、更新チェック処理などは自分で書かなければいけない。また、何を AssetBundle にいれ、何を入れないかといった難しさもあり、開発体験は非常に悪かった。そして実行中はスクリプトを更新することができない。
ローカル開発時のアーキテクチャ
- Prefab とそれが依存するリソースをローカルサーバでサーブし、変更があれば通知する。
rectangle "VS Code" as VSCode
rectangle "Unity Editor" as Unity {
rectangle "Warp Editor Plugin (Local Server)" as EditorPlugin
rectangle "Prefab File" as PrefabFile
}
rectangle "Device (VR Headset/Smartphone)" as Device {
rectangle "Unity Runtime" {
rectangle "Warp Plugin" as Plugin
rectangle GameObject
}
}
Unity --> PrefabFile: Update
PrefabFile --> EditorPlugin
EditorPlugin --> VSCode: Debug Information
EditorPlugin --> Plugin: Update Prefab
Plugin -> GameObject: Update
Plugin -> EditorPlugin: Scripting Debug Information
クラウドサービスのアーキテクチャ
rectangle "Unity Editor" as Unity {
rectangle "Warp Editor Plugin" as EditorPlugin
rectangle "Prefab File" as PrefabFile
}
rectangle "Warp Prefab File" as WarpPrefab
rectangle "GitHub"
rectangle "Warp Cloud Service" as WarpCloud
rectangle "Device (VR Headset/Smartphone)" as Device {
rectangle "Unity Runtime" {
rectangle "Warp Plugin" as Plugin
rectangle GameObject
}
}
Unity --> PrefabFile: Update
PrefabFile --> EditorPlugin
EditorPlugin --> WarpPrefab: Debug Information
WarpPrefab --> GitHub: Push
GitHub --> WarpCloud: main マージ時にデプロイ
WarpCloud --> Plugin: Update Prefab
Plugin -> GameObject: Update
PoC 進捗
- Prefab ファイルのパース
- パースした情報から実行中のプログラムで GameObject を生成
- Prefab の変更を実行中のプログラムで GameObject に反映
- Prefab 内の依存リソースを解決する仕組み (ブラウザの ES Module の実行時 import に相当)
-
スクリプトを更新する方法
- C# は実行時に差し替えられるが、dll のロード・アンロードを行うのであまり安全でない。安全に差し替える方法があるか調査する。なければ C# を諦めて独自のスクリプトランタイムを用意する必要がある。ただユーザーの障壁をいっきに上げるのでなるべく避けたい
- リアルタイムに実行中のプログラムに反映する
- スクリプトのデバッグ方法の提供
調査
Project Spirare
ホロラボの人が趣味で作っているプロジェクト。HTML 的なオブジェクト定義と WebAssembly によるオブジェクトの定義と操作を実現しており、僕が当初思い描いていたものが実現されている。
2022年7月15日
社内 esa より
AR/VR 系
自分の中にこうなるだろう、こうなってほしいというビジョンがある。
それと現在の間にあるまだ無いものを課題として取り組みたいとずっと思っている。
AR/VR に対するビジョン
数十年後はパソコンやスマートフォンは AR/VR のサブセットになると思っている。(電話がスマホのサブセットになったように)
今ある2次元ディスプレイは AR グラス内の空間上で再現される、含まれる存在になる。
AR/VR インターネットが実現され、空間上に不特定多数の人々が制作したコンテンツが配置されるようになる。それらのコンテンツはホームページやブログなどと同じくらい簡単に作ってシェアすることができる。
バーチャルオブジェクトをシェアするのが難しい
バーチャルオブジェクト: スクリプトを含んだ 3D モデルのような、VR/AR 環境上に出現させることができ、機能を持つものとする。
例えば「弾が発射できる銃」をやりとりする方法は存在しない。そういった銃が実装されたワールドを作るか、アバターに含める改造をする必要がある。
現状のソリューション
- VRChat や cluster のワールド・アバターとして作成
- Unity エディタで専用のプラグインを使って作成、アップロードできるようにすることで、ユーザー生成コンテンツを実現している
- ワールドに入ることはできるが、直接オブジェクトを配布する方法は無い (Unity アセットとして配布するしかない)
- Unity アセットとして配布
- 非常にポピュラー
- 非常に柔軟
- ランタイムで読み込むことが出来ない (一度 Unity エディターに読み込んで書き出す必要がある)
- スクリプトは書き出すことができない (VRChat では独自のプログラミング環境を用意)
- USDZ を配布
- Apple が提供する Reality Composer で、3D モデルに対して簡単なトリガーに対するアクションを付加し、USDZ 形式で保存することができる
- iOS でしか見れない
- 見たこと無い
問題点
- VRChat は BOOTH などで洋服やアイテムの売買が盛んだが、Unity エディターを使ってワールドやアバターに組み込む必要があり、ハードルが高い。VRChat 固有のコンポーネントが多く、VRChat でしか使えない
- Unity アセットは多くを解決しているが、Unity エディターが必須になる・C# が書き出せない問題がある
- USDZ は対応している環境が殆どない。事前に用意された動きを組み合わせることはできるがスクリプトのような自由度はない
やったこと
普通に動いた
こんなのあったらいいな
- いろいろな環境で起動中に読み込むことが出来るバーチャルオブジェクトのフォーマット
- バーチャルオブジェクトのマーケットプレイス
悩みどころ
- こんなことが出来たら良いなと思ってるけど、どれくらいの人がそう思っているのかわからない
- どう進めたらいいか?
- 「こんなのあったらいいな」をいきなり作るのではなく、そこに向かえる、スモールかつ需要のある形で進めたい
- 例えば共通仕様を作ったとして、すぐに cluster や VRChat が導入してくれはしなそう
- 最初はめちゃくちゃ具体的に、VRChat のお洋服売り場を作るとかでも良いのか?
AR で自由な場所に好きにオブジェクトを配置することができない
有名な動画 https://www.youtube.com/watch?v=YJg02ivYzSs
問題点
- 現在は不特定多数が作ったコンテンツが同時に表示される AR アプリは存在しない
- メッセージやお絵かきを残すことぐらいしかできない
- 基本的にはアプリを作った会社が用意したコンテンツしか存在しない
- 没入感やコンテンツの多さが重要になる AR で、コンテンツを見るためにアプリを切り替えたり、コンテンツが少ないことは致命的
- 一方で、だれでも自由に何でも配置できると、Hyper Reality 以上の地獄になる
- 視界が奪われ非常に不快 (スマホの画面がバナー広告で専有されることの究極版になる)
- 何が本物で何が偽物かわからなくなる
こんなのあったらいいな
- 位置情報から逆引きできる DNS
- 今いる場所に配置されたコンテンツを提供するサーバーの IP アドレスを提供するサービス
- インターネットの URL のように、認証されたサーバのみがその場所に登録できるようにする
- 地球を細かく分割して IP アドレスに対応させるサービスとも言える
- ブロックチェーンを使ったDNSのように特定のレジストラにお金を払わなくても使えるようにしたい
悩みどころ
- 課題は山積みなんだけど、今代替手段すらないので、そもそもニーズがあるのか不明
- こんなARインターネットの未来を作ります!ってホワイトペーパーを出して、位置情報DNSの細分化した地球をトークンとして売りまくる方法を考えていた
- いわゆる ICO だけどもうそういうの流行ってない・・・?
- ICO どうやってやるのかよく知らない。イーサリアム上で動作する ERC-20 トークンを作ればいいとかは出てくるけど、人が集まってくるビジョンがわかない
- そういう怪しげな方法じゃなくて、「不特定多数が作ったコンテンツが同時に表示される AR アプリ」を作るのもありうるけど、鶏と卵で、過疎化したつまんないアプリが出来上がるだけなのが目に見えてる。しかも AR グラスは普及してないからスマホ AR になるが、いまさら誰がわざわざ体験しようと思うのか・・・
AR/VR コンテンツを作るのが難しい
問題点
- PCの画面とゴーグルで見え方や感じ方が全然違うから、ゴーグルで確認する必要がある
- ゴーグルを被ったり外したりするのがめんどくさい
- スタンドアロンのデバイスではいちいちビルドする必要がある
- Unity の開発体験が良くない
やったこと
React 風のシンタックスで Unity の GameObject を構築できる仕組み。
Unity エディタ上で更新した Prefab をネットワーク越しにアプリに同期する。
スクリプトは同期できない問題がある。
悩みどころ
- React 風にかけても、ビジュアルで構築していけるという Unity の良さがなくなるだけだった
- Warp も結局 Unity のすべての機能が使えるわけじゃないので、すごく制限された感じになって開発体験があまり良くなかった
- Unity 最悪〜〜って思ってるけどこういうライブラリみたいな小手先の工夫ではどうにもならない気がしてきてる
2022年8月4日
社内 Slack より
プログラマブルなバーチャルオブジェクトがインターネットでシェアされて同じ空間上で動くっていう世界観、存在しなくて分からない問題があるので作ってる。
Unity のようにスクリプトがエンジンと密結合していると、自由なインターネットとは程遠い感じになるので、HTML の世界観を参考にして、JSON でシーンを宣言的に表現できるようにした。
これでスクリプトは単に JSON を出力するだけで良いので、あらゆるプログラミング言語が利用できるし、デバッグも超簡単。
動的なオブジェクトを作るために、出力した JSON に対する JSON Patch を適用する形で操作できる仕様とした。
JSON Patch は標準化されていて、中身も単なる JSON なので、これもまたスクリプトは JSON を出力するだけでよいことになる。
また、ネットワーク越しの別のデバイスに状態を同期することも、JSON Patch を適用するだけでよくなる。
レンダラー側では JSON を解釈して three.js (とりあえず簡単だから) で対応するオブジェクトやメッシュ、マテリアルを生成・更新する
差分計算もやりたくないので、JSON Patch の add や replace を見てそのまんま実行する
これはいわば DOM を操作する API と同じようなものなので、作りたければユーザーのスクリプト側で差分計算を行って、適切な JSON Patch を生成することで React みたいなものも作ることができる。