[Astro] #177 監視室のモニタ壁で MSX・動画・SID を動かす — Quest 3 の VR で、壁がそのままメニューになる
はじめに
前回は、3D Gaussian Splatting のビューアでした。
[Astro] #176 3D Gaussian Splatting Viewer — ブラウザだけで 3DGS を見て、切って、測って、VR でも見る
3D Gaussian Splatting のデータを、ブラウザだけで見られるビューアを作りました。ライブラリは使わず、WebGL2 と Web Worker で書いています。
lain-lab.com今回は、サイトの 3D 空間のほうです。監視室の GLB を使って、モニタがずらっと並んだ壁に、今まで作ったものを映しました。MSX のゲーム、MP4 の動画、SID の曲、の 3 つです。
壁のモニタには、映すだけでなく、メニューの役目もさせました。VR では、コントローラーから出るレーザーで、壁のモニタを押して操作します。
ターミナルで monitor と打つと、入れます。
画面
監視モニタのGLB
操作パネル UI
一番下のモニタでモード選択
シングルモニタ、マルチモニタにタイル表示、手前に大きなモニタ
下から二番目のモニタで各モードの選択
上のモニタ
上部のモニタにファイルリストと情報パネル
VIDEO
ビデオモードでは、事前に読み込んだMP4ファイルを再生。
BIGモード
タイルモード
GAME
過去に制作したMSX emulatorを起動。
SOUNDモード
SID PLAERを簡易移植。
SIDファイルの再生及び波形の表示。 SID の曲を再生している画面です。3 つのボイスの波形と、その下のスペクトラムを、壁のモニタを重ねた 1 枚の大きな画面に出しています。
動画(WebXR)
WebVRに対応しています。 ファイルは事前にQuestブラウザで表示されてるFILEから読み込み。
作ったもの
全体
- 監視室の GLB(Draco 圧縮で約 1.4 MB)を読み込みます
- モニタの部分を、1 枚ずつ別のメッシュに分けて、28 枚にしました。それぞれのモニタに、平らな UV を張っています
- 表示は、SINGLE(1 枚の画面を壁全体に出す)と TILE(1 つの画像を、壁のモニタに分けて出す)を選べます
- 映すものは、VIDEO(MP4)、GAME(MSX)、SOUND(SID)です
- BIG は、壁のモニタが手前に飛び出して、すきまなく 1 枚の大画面になります。もう一度押すと、壁に戻ります
壁がメニュー
右の列の、4 枚のモニタが、メニューです。
| モニタ | 役目 |
|---|---|
| MODE | LAYOUT(SINGLE / TILE / BIG)と、SOURCE(VIDEO / GAME / SOUND)の切り替え |
| 一覧 | GAME なら ROM、VIDEO なら MP4、SOUND なら SID の曲 |
| オプション | GAME ならマッパー選択と RESET、VIDEO なら再生・ミュート、SOUND なら再生・前後の曲 |
| STATUS | 状態の表示と EXIT |
左右で分けたのは、LAYOUT と SOURCE が、まったく別の機能だからです。最初は 1 つの列に混ぜていて、「2 つ選ばれているのに、何が何だかわからない」という状態になっていました。
メニューの絵は、Canvas に描いて、モニタのテクスチャにしています。ボタンの位置は、押された UV から、当たったボタンを判定します。
GAME(MSX)
以前に作った、Z80 / MSX1 のエミュレーターを、壁に映しました。キーボードの入力は、GAME のときだけ拾います。VR では、コントローラーのスティックを十字キーに、トリガーをスペースに割り当てました。
ROM は、ファイルを追加したあと、端末内の IndexedDB に保存されます。ROM ごとに、マッパーも覚えます。
VIDEO
MP4 を、壁に映します。ファイルを追加すれば、一覧から選べます。ほかの画面に切り替えたときは、動画の再生を止めて、負荷を減らします。
SOUND(SID)
SOUND は、SID の曲を再生して、波形を出します。最初に、MP3 を再生してスペクトラムを出すものを作ってしまいましたが、これは、頼んだものとは違いました(あとの節に書きます)。
SID:既存のプレイヤーをそのまま使う
SID は、以前に作った SID Player があります。reSID と fake6502 を WASM にしたもので、AudioWorklet で鳴らしています。これを、コピーせずに、同じファイルを読み込んで使いました。
/sid/sid_core.wasmと、/sid/sid-processor.jsの組み合わせです- 曲の読み込み(
load)は、worklet にメッセージを送るだけです。WASM は worklet の側で動きます - 壁の側では、
SidPlayer.tsという小さなファイルで、再生と、波形の描画だけをします。EQ や、鍵盤、プレイリストは、入れていません
波形が、めちゃくちゃになった
最初に出した波形は、縦の縞だらけで、使えるものではありませんでした。原因は、2 つあります。
- 大きさの自動調整が、ありませんでした。 元のプレイヤーは、波形の最大値に合わせて、大きさを自動で変えています。生の値は大きいので、枠からはみ出していました
- 断片を、つなげていました。 元の worklet は、23 回に 1 回だけ、128 サンプル(約 3 ms)の断片を送ってきます。それを 16 個つなげて、2048 サンプルの波形にしていたので、つなぎ目で線が上下に跳んでいました
最新の 128 サンプルだけを描くと、波形はきれいになりました。ただ、約 3 ms では短くて、すぐ消えてしまいます。
波形を、もう少し長く
壁用の worklet を、1 つ追加しました。sid-processor-wave.js です。元の sid-processor.js のコピーで、違うのは、波形の送り方だけです。連続した 512 サンプルを溜めて、まとめて送ります。壁の側では、それを 2048 サンプル(約 46 ms)の窓にして描いています。
元の sid-processor.js と、SID Player のページは、触っていません。共有しているファイルを、壁のために書き換えたくなかったからです。
その代わり、音が速いので、波形は、画面の上で、かなり細かく見えます。見た目は、3 ms のときよりは広がりましたが、劇的に変わったわけではありません。
スペクトラム
波形の下に、スペクトラムを 40 本、出しました。再生している音そのもの(ミックス)を、AnalyserNode に通して、低音側が広く見えるように、周波数を対数に近い形でまとめています。
詰まったこと
Quest で、重くて、レーザーも出なくなった
壁をメニューにしたところで、2D のブラウザは動いたのに、Quest の VR に入ると、カクカクで、レーザーも出ませんでした。
原因は、レイキャスト(当たり判定)でした。React Three Fiber の <primitive> に、クリックの処理をつけると、XR のポインターが、GLB の全部のメッシュを調べてしまいます。壁の全部が、毎フレーム、当たり判定の対象になっていました。
直し方は、次のとおりです。
- メニューのモニタ以外のメッシュは、
raycastを何もしない関数にします - ルートに、当たり判定の対象を、メニューのモニタだけだと伝えます
レーザーは、「クリックの処理をもつ物」に当たったときにしか出ません。そのため、メニューのモニタ以外では、レーザーが出ません。これは、不具合ではなく、そういう動きです。
余計なものを、足してしまった
壁をメニューにする作業の途中で、頼まれていない機能(SOUND など)を、一緒に作ってしまいました。そして、Quest で動かなくなったときに、原因が、どの変更なのか、切り分けられなくなりました。1 つずつ作って、実機で確かめるべきでした。
SOUND の意味を、取り違えた
SOUND は、最初から、SID の再生のことでした。それなのに、普通の MP3 を再生して、スペクトラムを出すものを作ってしまいました。MP3 だけなら、いらない機能でした。取り違えに気づいてからは、MP3 の再生を外して、SID に置き換えました。
調整した値を、上書きしてしまった
ファイルを差し替えたときに、手元の古い版で、BIG の距離や幅など、調整済みの値を戻してしまいました。調整は、作った側のリポジトリが正で、こちらの手元のコピーが古いことがあります。値を持つファイルを渡す前には、現行の値を確認することにしました。
ファイルを追加する
ROM、MP4、SID は、ADD FILES と ADD FOLDER のボタンで追加します。拡張子で、自動的に振り分けます。追加したファイルは、端末内の IndexedDB に残ります。サーバーには、上げません。
注意が、1 つあります。VR の中では、ファイル選択のダイアログが開きません。 ファイルの追加は、VR に入る前に、2D の画面でしておきます。
確認できたこと
- PC のブラウザで、壁のメニューが動く(SINGLE / TILE / BIG、VIDEO / GAME / SOUND の切り替え)
- Meta Quest 3 の VR で、壁のメニューをレーザーで選べる。GAME と VIDEO の切り替え、BIG が、すべての表示で動く(Quest で実機確認)
- PC のブラウザで、SID の曲を再生して、3 ボイスの波形とスペクトラムが出る
未確認のこと・未対応のこと
- SOUND(SID)を、Quest の VR では、まだ確かめていません。 PC のブラウザでだけ、動作を確認しました
- VR での FPS は、測っていません。画面の右下に FPS などを出していますが、記事に載せられるほどの計測は、していません
- SID の、1 曲(
Nemesis_MSX_OST.sid)で、再生の途中で、波形が平らになり、音が止まったことがありました。コンソールには、IRQ count=0と出ていました。原因は、わかっていません。元の SID Player でも同じかどうかを、確かめていません。SID Player は、もともと、一部の曲に対応していません - SID の曲番号は、先頭の曲だけです。サブ曲の切り替えは、ありません
- ファイルを、VR の中から追加することはできません。VR の中でファイルを選べないためです。LAN 経由で取り込む案がありますが、試していません
- 表示のボタンを、見た目だけ小さくして、押せる範囲は大きいままにする、という調整は、まだです
おわりに
壁のモニタを、映すだけでなく、操作する場所にしたことで、VR の中で、ほとんどの操作が、レーザーだけでできるようになりました。
今回は、動いたものを、また壊して、また直す、ということを、何度もしました。1 つずつ作って、実機で確かめる。当たり前のことですが、これが、一番、速いと思いました。
今は、v1 です。SID の曲が止まる件や、Quest での SOUND の確認は、次に、やります。