DEV Community

Ashish
Ashish

Posted on

Trump signs executive order to split up MMR vaccine - Axios

From Vaccine Headlines to Vision Therapy: Why I Built a VR App for Lazy Eye

This week’s MMR executive order consumed the health discourse. Meanwhile, 1 in 50 kids has amblyopia — and the standard treatment (patching) has a compliance crisis.

I’m a dev at Seven Sports. We built Amblyotube, a Meta Quest app that delivers dichoptic therapy (different visual input per eye) while kids watch YouTube‑style content.

Stack: Unity 2022 LTS, URP, OpenXR, custom compute shaders for per‑eye texture manipulation. The trick: making clinical‑grade dichoptic stimulation feel like entertainment.


Lessons learned

Content pipeline matters more than rendering tricks

We started obsessing over shader perf. Then realized: if the video library is stale, kids quit. The pipeline had to accept any 2D source — YouTube embeds, local MP4s, network streams — and transform it to dichoptic in real time. That meant decoupling content ingestion from the per‑eye render pass. We built a MediaPlayer abstraction that feeds a single RenderTexture, then our stereo shader splits it: left eye gets occlusion + base, right eye gets MFBF‑sharpened base + magenta cue + optional accents. One texture upload, two eye outputs.

To keep the library fresh we added a server‑side playlist manager that curates age‑appropriate channels, checks for DRM‑free streams, and pushes new entries nightly. The client pulls a lightweight JSON manifest at launch, so a new cartoon appears without an app update. This design also lets clinicians upload a custom playlist for a supervised protocol — just drop a CSV of URLs into the clinician portal and the next session loads it automatically.

Calibration UX is make‑or‑break for home use

Clinic settings have orthoptists. Homes have tired parents. Our first‑run flow:

  1. IPD measurement – Quest eye‑tracking where supported, manual slider fallback.
  2. Lazy‑eye selection – critical; wrong eye = wrong therapy.
  3. Suppression‑depth test using the magenta focus cue.
  4. Session‑length preference (default 30 min, max 60 min).

All steps are skippable but strongly encouraged. We store a JSON config locally; clinicians can side‑load a supervised protocol via a secure QR code that overwrites the local file without leaving the headset. A quick “Re‑calibrate” button on the main menu lets families repeat the test after a growth spurt or a new headset fit.

App Store review for health‑adjacent apps is… thorough

Meta’s policy team flagged:

  • Age gate (13+)
  • Session hard cap (60 min with reminders at 45 min and 55 min)
  • Disclaimer language – training/assistive tool, not a medical device, not a cure, complements professional care
  • No diagnostic claims

We added a dedicated Safety screen accessible from the main menu and the first‑run flow, plus an in‑app “Help & Resources” page linking to the American Association for Pediatric Ophthalmology guidelines. Review took ~3 weeks with two rounds of metadata revisions; the final build passed after we added a persistent “Session timer” overlay that pauses automatically when the headset is removed.

The shader math (simplified)

Occlusion layer (dominant eye)

float4 occlusion = tex2D(_MainTex, uv);
occlusion.rgb = lerp(occlusion.rgb, _BlurColor, _BlurAmount);
occlusion.rgb *= _Contrast;
occlusion.rgb += _Brightness;
occlusion.a = _Opacity;
return occlusion;
Enter fullscreen mode Exit fullscreen mode

MFBF sharpening (amblyopic eye) – AI person mask → dilation → unsharp mask confined to mask region. Runs on a compute shader, writes to a mask texture sampled in the composite pass.

Visual Accents – all rendered lazy‑eye only:

  • Highlight – additive yellow‑green glow.
  • Outline – red silhouette via Sobel on the mask.
  • Pulsesin(time * frequency) modulating accent intensity.

Because the compute dispatch runs at 72 Hz (Quest 2/3 refresh), the mask updates every frame with < 1 ms GPU time, leaving headroom for the video decode pipeline.

Performance & battery considerations

We profiled on Quest 2, Quest 3, and Quest Pro. The video decode (hardware‑accelerated H.264/HEVC) consumes ~ 30 % GPU; the dichoptic composite adds ~ 8 %. To keep thermals comfortable for a 30‑minute session we:

  • Dynamically lower the render resolution to 90 % when the headset temperature exceeds 40 °C.
  • Switch the compute shader to a half‑precision variant after the first 10 minutes.
  • Offer a “Low‑Power” toggle in Settings that disables the Pulse accent and reduces the Outline thickness.

Battery drain stays under 12 % per 30‑minute session on a fully charged Quest 2.

Community feedback loop

Since launch we’ve collected anonymized session logs (opt‑in) and a short in‑app survey. Early data shows:

  • Average compliance – 4.2 sessions/week vs. 1.8 for patching in the same households.
  • Drop‑off points – mostly after the first calibration if the IPD slider feels “guesswork.” We’re adding a guided AR overlay that projects a virtual ruler onto the lenses.
  • Feature requests – multi‑user profiles, a “parent dashboard” on the phone app, and a library of educational shorts about eye health.

These insights feed a two‑week sprint cycle; the next update will ship the AR‑guided IPD step and a lightweight companion app for progress tracking.


Happy to share code snippets, shader approaches, or the regulatory path we navigated.

https://www.meta.com/en-gb/experiences/amblyotube/25906906972338493/

Top comments (0)