[Astro #44] Protocol Atlas: 144枚の情報の海をサルベージするVRアーカイブ

[Astro #44] Protocol Atlas: 144枚の情報の海をサルベージするVRアーカイブ

1. はじめに

Wired(情報の海)に漂う無数の断片たち。それらをただ眺めるだけでなく、自らの手でサルベージ(抽出)し、実存を確かめるための装置。それが今回完成した「Protocol Atlas」です。

React Three Fiber (R3F) と WebXR を駆使し、144枚のビデオを同時に描画しつつ、VR空間を自由に泳ぎ回れるギャラリーを構築しました。本稿では、その実装の核心と、VR開発特有の「罠」をどう突破したかについて記録しておきます。

[Astro #44] Protocol Atlas: 144枚の情報の海をサルベージするVRアーカイブ

NOTE:

Youtube:

動画:

前回の記事:

2. 144並列の実存:Texture AtlasとInstancedMesh

144個の独立したビデオテクスチャを愚直に読み込んでしまえば、ブラウザは即座に悲鳴を上げます。 これを解決するため、4K解像度の1枚のビデオに144個の映像を敷き詰めた「Texture Atlas」を作成しました。

[Astro #44] Protocol Atlas: 144枚の情報の海をサルベージするVRアーカイブ

シェーダー内で vUv = uv * 0.08333 + instanceUvOffset; のようにUV座標を計算し、InstancedMesh を用いて1回のドローコールで144枚の板ポリゴンを描画しています。これにより、圧倒的なパフォーマンスを維持したまま、膨大な情報の壁を現出させることが可能になりました。

3. WebXRの罠:GSAPからの脱却と useFrame への統合

開発中、最大の障壁となったのが「VR空間に入るとアニメーションが止まる」という現象でした。 PCブラウザでは完璧に動作していた GSAP によるパネルの展開やフォーカス(サルベージ)処理が、HMDを被った瞬間に足元に固まってしまうのです。

原因は、ブラウザ標準の requestAnimationFrame(GSAPが依存するもの)が、VRモード突入時にスリープ状態になり、XR専用の描画ループに切り替わってしまうためでした。

解決策: GSAPを完全に排除し、R3Fネイティブの useFrame 内で THREE.MathUtils.damp を用いて数値を補間する方式へと移行しました。

useFrame((state, delta) => {
  const currentFocus = materialRef.current.uniforms.uFocusProgress.value;
  // 目標値に向けて毎フレーム滑らかに数値を追従させる
  materialRef.current.uniforms.uFocusProgress.value = THREE.MathUtils.damp(currentFocus, focusTarget.current, 5, delta);
});

これにより、PC・VR問わず、HMDのリフレッシュレートに完全に同期した滑らかなアニメーションが実現しました。

4. VRネイティブな操作系:レーザーとスティック

単なる「鑑賞」ではなく「探索」を可能にするため、コントローラーの物理ボタンとアナログスティックの入力を直接監視するカスタムフック (VRControllerListener) を実装しました。

  • サルベージ (Trigger): @react-three/xruseXRControllerButtonEvent を用いてレーザーの衝突判定を取得します。対象を手前(Z = -12.0〜15.0)へ引き出し、閲覧状態にします。
  • モード切替 (Xボタン): 球体(Sphere)と平面(Plane)のジオメトリを動的に変形させます。
  • 空間移動 (アナログスティック): gamepad.axes の値を読み取り、プレイヤーの原点である <XROrigin /> の座標を直接更新することで、情報の海を自在に泳ぎ回れるようにしました。

5. GPUリソースの解放とVR最適化

144枚のビデオを描画する Protocol Atlas と、メインのアバター表示 (WiredScene) が競合すると、甚大なGPU負荷が発生してしまいます。 これを防ぐため、トップページのギャラリーで別の作品を見ている間は、コンポーネント自体を return null して Unmount(ノードの破棄)させる「知性」を持たせました。display: none という透明な幽霊を殺し、GPUメモリを完全に解放しています。

さらに、VR内でのチラつき(ジッター)を抑えるため、以下の最適化を施しました。

  • frustumCulled={false}: 画面外判定の計算コストをカット。
  • transparent={false}: アルファブレンド(重なり計算)を無効化し、描画速度を劇的に向上。
  • antialias: false: HMDの高解像度を活かし、不要なアンチエイリアス処理を停止。

6. 結び:Wiredへのダイブ

バラバラな映像がひとつの集合体として蠢き、選ばれた情報だけが目の前に立ち現れる。そして用が済めば、再び元の暗闇へと帰還していく。

これまで609件の記事を積み重ねてきたこのアーカイブに、ついに「Protocol Atlas」という新たな実存のレイヤーが追加されました。現実とWiredの境界線を曖昧にするこの装置で、これからも世界の断片を収集し続けていきたいと思っています。