DEV Community

Cover image for Building a Dichoptic Vision-Training Game in Unity for Meta Quest: Lessons from AmblyoPunch
Ashish
Ashish

Posted on

Building a Dichoptic Vision-Training Game in Unity for Meta Quest: Lessons from AmblyoPunch

Building a Dichoptic Vision-Training Game in Unity for Meta Quest: Lessons from AmblyoPunch

The August 2026 VR Games Showcase just dropped (Road to VR has the full rundown). While the headlines chase Total Chaos VR and the latest ports, I want to zoom in on a different launch: AmblyoPunch — a Meta Quest title that delivers dichoptic amblyopia therapy through an arcade loop.

Tech stack: Unity + URP + Meta XR SDK. Target: Quest 2/3/Pro. Single APK, no backend.

The core challenge: rendering two different images — one per eye — in real time, at 72/90Hz, with precise control over spatial frequency, contrast, and luminance of Gabor-pattern stimuli.

How we solved it:

  1. Single-pass stereo with custom shader

    • Unity’s single-pass instanced rendering gives us unity_StereoEyeIndex in the vertex shader.
    • We branch per-eye in a fragment shader that procedurally generates Gabor patches (sinusoid × Gaussian envelope) on the GPU. No texture lookups, no memory bandwidth — pure math. Parameters (frequency, orientation, phase, contrast) come from a ScriptableObject progression table keyed by stage.
  2. Dichoptic coin system

    • Each “coin” is a quad with the Gabor shader. Left eye sees one spatial frequency; right eye sees another (or same frequency, different contrast). The brain must fuse to perceive the coin cleanly.
    • Collection triggers a compute-shader-driven particle burst — also dichoptic — so reward feedback stays binocular.
  3. Red-spike avoidance

    • Spikes render identically to both eyes (non-dichoptic) to preserve depth cues and motion parallax. This keeps the vestibular load honest — players dodge in 6DoF, not 2D.
  4. Four-stage protocol as data, not code

    • Stage 1: Monocular stimulation (strong eye suppressed via alpha = 0 in shader)
    • Stage 2: Binocular fusion (balanced contrast)
    • Stage 3: Stereopsis recovery (disparity introduced via vertex offset)
    • Stage 4: Maintenance (randomized parameters)
    • All driven by a TherapyPlan ScriptableObject. Clinicians can swap plans without rebuild.
  5. Performance budget

    • Gabor shader: ~12 ALU instructions, zero texture fetches.
    • 60+ coins on screen @ 90Hz on Quest 2: <2ms GPU.
    • Zero allocations in gameplay loop — object pooling for coins, spikes, particles.
  6. Calibration & safety

    • First-run IPD + interpupillary distance check via OVRPlugin.GetEyeGazesState.
    • Luminance calibration gray-card step (uses Quest’s factory calibration).
    • Session timer + forced breaks (configurable per plan).

Why this matters for devs

  • Medical XR doesn’t need a custom engine. Unity + URP + shader gymnastics gets you there.
  • Procedural stimuli > texture atlases for vision science — infinite parameter space, zero download size.
  • Single-pass stereo + per-eye shader branching is the pattern. Learn it once, reuse for any dichoptic protocol.

Open questions we’re exploring

  • Dynamic contrast staircase (QUEST algorithm) driven by player performance in real time.
  • Hand-tracking fallback for controller-free home use.
  • Exporting session logs (CSV) for clinician review — currently local-only, looking at FHIR alignment.

Repo is private (clinical IP), but happy to field technical questions in comments.

Store link (Meta Quest): https://www.meta.com/en-gb/experiences/amblyopunch/1239507485902689/

Unity #MetaQuest #XRDevelopment #VisionScience #DichopticTraining #Amblyopia #MedicalVR #ShaderProgramming #URP

Top comments (0)