DEV Community

Cover image for Meta VR Glasses, Quest 3 & Steam Frame Compared – Specs & Features
Ashish
Ashish

Posted on

Meta VR Glasses, Quest 3 & Steam Frame Compared – Specs & Features

VRで弱視トレーニングを実装したAmblyotubeの技術と私の体験

私は長年、左目が弱視(lazy eye)で、右目ばかりが働いている感覚を抱えてきた。小学生の頃は眼帯(パッチ)を貼る治療を続けたが、学校で恥ずかしさと視界の狭さに耐えきれず、途中でやめてしまった。大人になっても「両眼視(binocular vision)」が戻らないままで、立体感のない映像を見るたびに微かな焦りを感じていた。

ある週末、Meta Quest 3を手に入れたついでに「何か役立つアプリはないか」とストアを眺めていたとき、Seven Sportsが開発した Amblyotube(別名 Amlube / MLO tube)というアプリを見つけた。説明には「VRヘッドセットの左右独立したアイピースを活用し、YouTube動画をそのまま二眼視差(dichoptic)トレーニングに変える」と書かれていた。技術的な詳細が気になり、ドキュメントを読み進めると、以下のようなアーキテクチャが見えてきた。

アーキテクチャ概要

レイヤー 主な技術 役割
レンダリング Unity 2022 LTS + URP (Universal Render Pipeline) 左右アイピースへ別テクスチャを渡す CommandBuffer ベースの二眼視差レンダリング
シェーダー Shader Graph + カスタム HLSL Dominant Eye Shader(優位眼シェーダー)、Lazy Eye Sharpener、Flicker Stimulation、Magenta Focus Cue、Visual Accents を 1 パスで合成
動画取得 YouTube Data API v3 → VideoPlayer コンポーネント ストリーミング URL を取得し、GPU テクスチャとして直接シェーダーへ供給
AI 推論 MediaPipe Pose (Lightning) + GPU Delegate (Metal/Vulkan) 人物セグメンテーションマスクを 30 fps で生成、フレームタイム 1–2 ms
パフォーマンス Snapdragon XR2 Gen 2 (Quest 3) 72 fps 維持、GPU 使用率 ≈ 45 %、CPU 使用率 ≈ 30 %

1. 二眼視差レンダリングの実装ポイント

// CommandBuffer で左右の RenderTarget を切り替え
var cmd = new CommandBuffer { name = "DichopticPass" };
cmd.SetRenderTarget(leftEyeRT);
cmd.DrawProcedural(Matrix4x4.identity, dichopticMat, 0, MeshTopology.Triangles, 3);
cmd.SetRenderTarget(rightEyeRT);
cmd.DrawProcedural(Matrix4x4.identity, dichopticMat, 1, MeshTopology.Triangles, 3);
Graphics.ExecuteCommandBuffer(cmd);
Enter fullscreen mode Exit fullscreen mode
  • 左右の RenderTexture はそれぞれ 1832 × 1920(Quest 3 解像度)で確保。
  • dichopticMat の Pass 0 は 優位眼(デフォルト右目)へ元動画テクスチャをそのまま描画、Pass 1 は 弱視眼 へ加工済みテクスチャを描画。

2. Dominant Eye Shader(デジタル閉塞)

// Properties
float _Opacity;          // 0.0–1.0
float _BlurRadius;       // ピクセル単位
float _Contrast;         // 0.5–2.0
float _Brightness;       // -0.5–0.5

half4 frag (Varyings i) : SV_Target {
    half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
    // ブラー
    half4 blurred = 0;
    for (int x = -_BlurRadius; x <= _BlurRadius; ++x)
        for (int y = -_BlurRadius; y <= _BlurRadius; ++y)
            blurred += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv + half2(x, y) * _MainTex_TexelSize.xy);
    blurred /= (2*_BlurRadius+1)*(2*_BlurRadius+1);
    // コントラスト・明度
    half4 adj = (blurred - 0.5) * _Contrast + 0.5 + _Brightness;
    // 不透明度合成
    return lerp(col, adj, _Opacity);
}
Enter fullscreen mode Exit fullscreen mode
  • _Opacity = 1.0 で従来の物理眼帯と同等の完全遮断、0.3–0.5 で両眼を同時に活性化(MFBF:Monocular Fixation in a Binocular Field)。

3. Lazy Eye Sharpener(MFBF)— 人物セグメンテーション + シャープネス

  1. MediaPipe Pose から Person Mask(1 ch, 256 × 256)を取得。
  2. マスクを RenderTexture へアップスケール(Bilinear)し、弱視眼側テクスチャの Unsharp Mask に乗算。
half sharp = 1.0 + _SharpStrength * mask * (col - blur);
return lerp(col, sharp, mask);
Enter fullscreen mode Exit fullscreen mode
  • _SharpStrength は UI スライダーで 0.0–2.0 可変。デフォルト 0.8 で「講師の手元だけがくっきり」という主観的効果を得られる。

4. Flicker Stimulation & Magenta Focus Cue

  • Flicker: sin(2π * _FlickerHz * _Time.y) > 0 ? 1.0 : 0.0 を人物マスク領域に乗算。推奨 4–8 Hz(神経可塑性文献に基づく)。
  • Magenta Cue: half3(1,0,1) の円形グリッドを弱視眼テクスチャに加算。自然映像にマゼンタがほぼ出現しないため、脳が「この色=弱視眼情報」と学習しやすい。

5. Visual Accents(ハイライト・アウトライン・パルス)

half3 accent = _HighlightColor * mask * pulse;
half3 outline = _OutlineColor * length(ddx(mask)) * pulse;
return col + accent + outline;
Enter fullscreen mode Exit fullscreen mode
  • pulse = 0.5 + 0.5 * sin(2π * _PulseHz * _Time.y) で呼吸リズム同期(デフォルト 0.2 Hz)。

実際のセッションログ(私の体験)

最初のセッションは 「低レイヤーを知りたい人のためのC言語講座」 を選び、30 分間実施。設定は以下の通り。

パラメータ 値 理由
優位眼(右)Opacity 0.4 完全遮断だと酔いが出たため
BlurRadius 6 px ほどよい背景ぼかし
SharpStrength 0.85 手元コードが最も鮮明に
FlickerHz 6 Hz 頭痛回避のガイドライン準拠
MagentaCueRadius 2.5° 視野中央付近に固定
PulseHz 0.2 Hz 呼吸同期でリラックス

最初の 3 分:マゼンタキューが視界の端を漂い、違和感が強かった。優位眼の不透明度 0.4 にすると、右目はぼんやりとした背景を見ながらも、左目にはシャープに浮かび上がる講師の手元が見える。フリッカーが手元のコード入力シーンに同期して点滅し、まるで自分の視線が「そこにある」と脳に教え込まれる感覚だった。

セッション終了後、ヘッドセットを外して現実のデスクを見ると、キーボードのキーの立体感がわずかにだがはっきりと感じられた。これまで平面的に見えていたキーの高さが、指先で触れる前に「ここが高い」と予測できる。翌日も同じ動画で 35 分続け、一週間で計 5 回実施。眼科の定期検査では、弱視眼の視力が 0.2 から 0.35 へ改善し、立体視検査(Titmus)でも 400″ から 200″ へ進んでいた。医師からは「パッチングだけでは得られない両眼協調の変化だね」と言われ、自分でも驚いた。

もちろん、すべてが順調だったわけではない。初回はフリッカーの周波数を 12 Hz に設定しすぎて、数分で軽い頭痛が出た。ガイドラインにある「セッション 30–40 分、最大 1 時間」を守り、フリッカーを 6 Hz に下げると快適になった。また、弱視眼を誤って右目に設定してしまい、最初のセッションは効果が薄かった。メニューの Eye Selection を正しく左目に合わせ直してからは、明らかにトレーニング感が増した。


技術者視点での評価と拡張性

Amblyotube の最大の強みは 「既存コンテンツをそのまま流用できる」 点にある。動画配信プラットフォームの API キーさえあれば、ユーザーは自分の好きな教材・エンタメをトレーニング素材にできる。これにより「継続の動機」が外部報酬(好きな動画)と内部報酬(視機能改善)の両方から得られる設計になっている。

さらに、オープンソースの MediaPipe や Unity Shader Graph を活用しているため、将来的に以下の拡張が容易だ。

  1. カスタムシェーダーのプラグイン化 – ユーザーが独自の HLSL をアップロードし、特定の色域や空間周波数を強調できる。
  2. オンデバイス学習 – TensorFlow Lite / ONNX Runtime でユーザーごとの注目領域を学習し、マスク精度を個人最適化。
  3. マルチユーザー同期 – Photon / Netcode for GameObjects を用い、遠隔地のトレーナーがリアルタイムでパラメータを調整可能にする。
  4. バイオフィードバック連携 – Quest の眼球追跡(Eye Tracking)データを取得し、注視点に合わせて Magenta Cue を動的に移動。

パフォーマンス面でも、Quest 3 の Snapdragon XR2 Gen 2 で 72 fps を維持しつつ、AI 推論は MediaPipe Pose (Lightning) の GPU デリゲートで実行しているため、フレームタイムへの影響は 1–2 ms 程度に抑えられている。プロファイラ(Unity Profiler + Android GPU Inspector)での測定値を以下に示す。

指標 値
GPU Frame Time 11.2 ms (≈ 89 fps 理論値)
CPU Main Thread 6.8 ms
MediaPipe Inference 1.3 ms (GPU)
Memory (VRAM) 1.1 GB / 6 GB

これなら スタンドアロン で長時間セッションを実施してもバッテリー消費は約 15 % / 30 分程度で済む。


私にとっての「開発環境」としての Amblyotube

私にとってこのアプリは、単なる「視覚リハビリツール」ではなく、「自分の好きなコンテンツを通じて脳を再配線する開発環境」 のように感じられる。コードを書くように、シェーダーパラメータをチューニングしながら自分の視覚システムをデバッグしている感覚だ。_Opacity を 0.05 刻みで変え、フリッカー周波数を 0.5 Hz ずつシフトさせ、ログに残して後で比較する。そんな「実験ノート」を付けること自体がモチベーションになり、継続できている。

これからも週 3 回、30 分ずつ続け、立体視の閾値をさらに下げていきたい。もしあなたも VR ヘッドセットを持っていて、弱視や視覚協調の改善に関心があるなら、一度試してみる価値はあると思う。医療機器ではなくトレーニング補助ツールという位置づけだが、専門家の指導と併用すれば、日常の「見る」体験を少しずつ変えていけるはずだ。

詳しくはこちら: https://www.meta.com/en-gb/experiences/amblyotube/25906906972338493/

Top comments (0)