Developed by Michael Sanders: github.com/jakalnz/vor-simulator
Explore the ear model on its own, piece by piece: Labyrinth Model Lab
Why the canals lag behind a head turn, as a glass of water: The Spinning Glass
A white paper on the physiology model and 3D visualisation behind this app
The Vestibulo-Ocular Reflex (VOR) is the reflex that keeps your gaze fixed on a target while your head moves — it's why you can read a street sign while walking, or keep eye contact while shaking your head "no". This simulator drives a real-time, physiologically grounded model of that reflex from live device rotation (phone/tablet gyroscope) or mouse-drag input, and renders the downstream effects: fluid movement in the inner ear's semicircular canals, changes in vestibular nerve firing rate, and the resulting eye movement (nystagmus).
Every animation frame runs the same five-stage pipeline:
The six semicircular canals aren't aligned with simple up/down/left/right axes — each is tilted, and they work as three functional pairs:
Each canal is represented by a unit vector n̂ pointing along its sensing axis. The stimulation a canal receives is the dot product of the head's angular velocity vector ω with that canal's axis: ωcanal = ω · n̂canal. This is why tilting your head changes which canals respond to a given rotation — you're changing the alignment between the rotation axis and each canal's fixed sensing direction.
Each canal is a fluid-filled ring with a gelatinous membrane (the cupula) that bows in response to fluid inertia. Physiologically this behaves like a heavily overdamped torsion pendulum (the Steinhausen model): it responds promptly to acceleration, then relaxes back toward zero even during sustained constant-velocity rotation, with a biological time constant around 6 seconds. The app models this as a discrete high-pass filter run every frame — cupular deflection decays a little each tick while being driven by the canal's current angular velocity. This decay is the reason a prolonged constant-speed spin eventually stops producing a sensation of turning, and why stopping abruptly produces a strong after-sensation in the opposite direction.
Each vestibular nerve has a resting discharge rate of roughly 90 spikes/second even with no head movement at all — this baseline is what makes the reflex directionally sensitive, since a rate can go up or down from rest. Cupular deflection pushes the firing rate up or down from that baseline:
The canal panel's colour coding shows this directly — canals shift toward red as firing rises above baseline (excitation) and toward blue as it falls below baseline (inhibition), with neutral grey at rest.
The brainstem doesn't read absolute firing rates — it reads the difference between a canal pair's left and right members (e.g. Δf = fLH − fRH for the horizontal pair). That difference drives a smooth, involuntary slow-phase eye drift in the direction opposite the head's rotation, at a velocity (SPV) proportional to Δf — this is the reflex actually doing its job of holding gaze steady on the world while the head moves under it.
Because the eye can't drift indefinitely in one direction, once the accumulated slow-phase displacement crosses a mechanical threshold (about 15°), the eye snaps back rapidly in a fast-phase saccade before resuming slow-phase tracking. This slow-drift/fast-reset sawtooth is nystagmus, and it's what the simulator renders in the eye panels — by convention, the fast phase's direction is used clinically to name the nystagmus.
On a phone or tablet, the app requests access to the device's rotation-rate sensor
(DeviceMotionEvent) and reads angular velocity directly in degrees/second, converting
to radians for the physics. On desktop, mouse-drag gestures are converted into an equivalent
synthetic angular velocity so the same downstream pipeline runs unmodified. A library of scripted
diagnostic and repositioning maneuvers (Dix-Hallpike, Epley, Semont, BBQ-roll, Zuma, roll-test) can
also drive head orientation directly, useful for demonstrating canalithiasis (BPPV) scenarios where
free-floating otoconia debris in a canal generates its own transient stimulation independent of
real head motion.
The inner-ear geometry (semicircular canals, ampullae, utricle) is not a stylised cartoon — it's built from real anatomical geometry sourced from the IE-Map in-vivo inner-ear atlas (Ahmadi et al., 2021, Scientific Reports). Individual canal and ampulla meshes are identified during asset load and their materials are recoloured every frame from the neural firing engine's output, so the 3D model becomes a live readout of which canals are excited or inhibited for the current head motion. A separate "micro fluid view" zooms the camera onto an individual ampulla to demonstrate cupular deflection and endolymph flow directly, and a neural firing-rate plot mode shows the same signals numerically alongside the 3D view.
This model is the same reasoning clinicians use at the bedside: a rotation is decomposed onto the six canal axes, cupular dynamics determine how briskly each canal responds, firing-rate asymmetry (bounded below by zero per Ewald's Second Law) explains why some maneuvers produce strong nystagmus and others don't, and the resulting slow/fast-phase eye movement pattern is exactly what's observed during Dix-Hallpike testing, caloric testing, and head-impulse testing. The simulator exists to make that normally invisible chain — from a millisecond of angular velocity to a visible beat of nystagmus — something you can see happen in real time.