Two clocks, one contract
Everything else lives inside this split.
Sound needs two speeds at once. The world changes slowly — you walk, a door swings — so a simulation tick every 50 ms (20 Hz, in a Web Worker or a native thread) is plenty. The waveform changes 48,000 times a second and tolerates zero lateness, so an AudioWorklet renders it sample by sample on the browser's real-time thread.
The only thing that crosses between them is a tap table: each acoustic path, of any origin, is one tap — key · delay · direction · gains[3]. Gains come in three bands (below 250 Hz, 250–2500, above 2500) because every physical effect in this engine is frequency-dependent. The key is a stable identity: as long as a path keeps its key across ticks, the renderer glides its delay — which is physically exact Doppler for free — and when a key vanishes, its tap fades out instead of clicking. Engines can be swapped live because they all speak tap.
Image sources
The exact solution for an empty box — the engine everything is measured against.
Reflect the source across a wall and the echo behaves exactly like a second source standing in the mirror room. Reflect the mirrors again for second-order bounces. For a shoebox room this is closed-form and exact: order 3 yields precisely 63 image sources, each with a machine-perfect delay, direction, and per-band wall loss.
Its weakness is its assumption: an empty box. Furniture breaks it, and other rooms are invisible to it — so the classic build routes sound between rooms through authored portals: virtual sources standing in doorways, blend zones while you cross, aperture re-radiation. That machinery worked, and it is still selectable as early = ism — but it is bookkeeping about geometry rather than geometry, and it made every doorway cost 2.5× a normal tick. The rest of this page is, in part, the story of deleting it.
One world, made of surfaces with names
The mesh is the acoustic truth — and every plane keeps its identity.
The whole map — every wall, slab, roof, and the ground — is one triangle mesh under one BVH (a bounding-volume tree, so a ray finds its nearest hit in logarithmic time). Door and window holes are simply absent triangles. Each authored plane carries a stable surface id: a wall keeps one identity no matter how its door holes fracture it into patches, and each material carries per-band absorption, scattering, and transmission.
Identity is what makes paths durable. A reflection path is a chain of surface ids — [hall-east-wall], [floor, north-wall] — and a chain survives your movement even as its geometry glides underneath. That single property is what the next layer exploits.
Path-traced early reflections
Rays discover that a path exists; geometry then supplies it exactly.
The traced engine splits the problem in a way most engines don't. A rotating golden fan of rays leaves the listener each tick and bounces over the world mesh, recording which surface chains it crosses — that is discovery, and it is cheap, statistical, and shared by every source (rays from your ears don't care what they're listening for). Each discovered chain enters a cache with a time-to-live.
Then, for every source, every cached chain is solved exactly: mirror the source across the chain's planes, draw the straight line, validate that each bounce lands on real mesh — a bounce that would land inside a door hole is refused. The solve is a handful of mirror operations, cheaper than one traced ray, and its delay and direction are machine-exact — so the sound is as stable as image sources, in geometry image sources could never handle. Every leg of the path also crosses the mesh honestly: a leg through a doorway hole passes free, a leg through masonry pays mass law (amplitude ∝ 1/thickness, bass surviving treble). Doorways stopped being a special case; they are just places where the wall isn't.
Sound bends
Rays travel straight; hearing does not.
Step just past a doorway and the voice inside doesn't vanish — it dulls and seems to come from the door frame. That is knife-edge diffraction, and mirrors can't produce it. The engine prices it with the Kurze–Anderson approximation: the loss depends on the detour — how much longer the path over the edge is than the blocked straight line — measured in wavelengths, which is why shadows are bass-light and treble-dark.
The edges themselves are not authored. Door jambs, building corners and roof lines are auto-extracted from the world mesh as sharp creases, so a jamb and a skyline are the same object. Each shadowed source gets one tap from its dominant edge (summing four near-equal edges overcounts by ~10 dB — a measured mistake), scaled by the complement of the solved direct path so a clear sight line never double-counts. This layer is a live switch in the quality panel: turn it off and you get the hard shadows most game audio ships with.
Furniture has ears-side consequences
The room isn't empty, so the engine stopped pretending it is.
Sofas, seminar tables, cathedral pillars, the club's bar — each is an acoustic box with a full material: per-band transmission, absorption, scattering. Every solved path leg checks what it passes through: a soft sofa eats treble and lets bass through, a bookshelf is nearly a wall. Significant pieces are also reflectors — their faces enter the surface table, discovery bounces off them, and a table-top slap is solved with the same machine-exact mirror as a wall bounce. And they shape the late field: reverb rays bounce off furniture with its absorption, so a furnished room measurably decays faster and more diffusely than the empty shell.
This is precisely where image sources broke and tracing wins on principle: the ray budget is constant no matter how cluttered the room is, while mirror enumeration explodes. It's also the second live switch — furniture: off makes every object acoustically transparent, which is the empty-shoebox assumption you can now hear as an absence.
The reverberant tail is a statistic
Thousands of rays, measured — never authored.
After the first reflections, a room's response stops being individual paths and becomes a texture: thousands of overlapping arrivals decaying together. The engine measures it stochastically. Rays carry three-band energy from the source, bounce with material absorption and scattering (Lambert or specular, chosen per hit), and every crossing of a half-meter sphere around the listener deposits energy into a 10 ms-binned echogram. Schroeder backward integration over the echogram, fitted between −5 and −25 dB, yields the RT60 per band; energy after 80 ms yields the diffuse level. Those two numbers drive the renderer's reverb network.
Two disciplines keep it honest. No Russian roulette — stochastically killing rays corrupts the decay fit in stone rooms (measured, not theorized), so the honest budget lever is ray count, whose noise a running average absorbs. And a trace gate refuses to re-measure a scene that hasn't changed: motion, door swings and level changes re-trace instantly; stillness coasts on the average.
The wet field is measured, with a direction
Stand in the corridor: the living room's reverb reaches you through the door — because the rays did.
Since the late tracer runs on the world mesh, coupled rooms emerge instead of being routed. A source's rays leave its room through the doorway hole, decay in your room, and the echogram at your head simply contains it all: the coupled decay time, the level — and, because each energy deposit remembers its arrival direction, the tail's anisotropy. A reverberant room heard through a doorway reports a tail that mostly arrives from the doorway; the engine plays that share on a directional wet bus and the diffuse remainder in the reverb network. The last piece of portal bookkeeping — Lambert radiators, aperture routing — was deleted the day this measurement replaced it.
Doors themselves are panel overlays on the geometry: a leaf at 40% open covers 60% of its hole as a wood box that solved paths transmit through (mass law) and late rays bounce off. Swing it and every filter sweeps continuously.
The ambient dome
An audio skybox, sampled through real geometry.
Rain, wind and city rumble are not sources standing anywhere — they are a field arriving from the sky. Every tick, a fan of rays leaves your head and asks the world: which directions reach open sky, and through what? A ray escaping through a window carries the outdoor field from that window's direction, attenuated by the panes it crossed; a ray dying in masonry carries nothing. Binned by direction and smoothed over time, this produces the ambient image — walk from the field into the hall and the sky narrows to the doorway behind you, continuously, with no authored transition.
A parallel power balance handles what rays can't: through-shell seep (the storm as a bass presence inside a closed building), an enclosure factor that is geometric rather than reverberant, and roof exposure. Rain additionally anchors drop sounds on the glass panes themselves.
Things that move, including you
Every moving thing is just a source; the layers above do the rest.
Your footsteps are a source in the world, at your feet. Steps fire on distance travelled (~1.5 m of stride, jittered so your feet aren't a metronome, gated to human cadence), pick their sample by the room's floor — wood, carpet, concrete, gravel — and then propagate like any other source: your steps echo in the cathedral and dull behind the bar, for free. Thrown balls and passing cars are dynamic sources with live positions; crouch, jump and sprint move the listener's actual ears, so ducking behind the club bar physically changes the solved paths. Face tracking, when enabled, steers the binaural head directly.
Rendering for two ears
Where taps become the feeling that the sound is *there*.
Every tap is binaural. All of them encode, at their arrival direction, into second-order ambisonics — a compact directional sound field — decoded through twenty virtual loudspeakers, each convolved with its measured KEMAR head-related response. That gives the full field correct interaural time and level differences, slightly blurred in angle. On top, the strongest N paths get a dedicated nearest-neighbor HRIR from a 710-direction grid: pin-sharp localization exactly where the precedence effect says hearing takes its bearings — from the loudest, earliest arrivals. The weak tail reads as envelopment either way.
Each tap runs through a per-sample fractional delay line (whose glide is the Doppler from layer I), per-band gain smoothing, and the diffuse and directional wet buses join at the end, before a slow AGC that protects your ears, not the mix. This is the one workload the GPU can never help with — it must produce the next sample now — which is why the governors of the next layer exist.
Shedding the right work first
Every quality lever trades variance or staleness — never a different sound.
Two governors watch two clocks. The sim governor starts every session at the lowest tier and earns its way up only after sustained calm, sheds instantly when a tick blows 40 ms or audio pressure persists. The audio governor watches render load per quantum: above 80% of realtime it sheds tap ceilings and point-HRIR count feed-forward — before the miss, because a missed audio deadline is the one failure you can hear. Every lever was chosen so that turning it down adds statistical noise (fewer rays), staleness (slower refresh), or spatial blur (fewer point HRIRs) — perceptually graceful degradations — and never bias.
The quality panel exposes all of it: pin any lever, or hand them back to the governors. The engine-module switches — ism/traced, cpu/gpu, diffraction, furniture — are the A/B instruments this page's claims can be checked with, live.
The same physics, on the GPU
Four WGSL kernels, one rule: silent fallback, parity-tested against the CPU.
The ray workloads are embarrassingly parallel, so they run as WebGPU compute — the same WGSL kernels on native wgpu and in the browser. K1 traces shoebox reverb; the PT kernel discovers box chains; K2 traces the world mesh (the BVH uploads once, ~9 MB; door leaves travel per-dispatch as 48-byte panel boxes); K3 runs chain discovery over the same buffers. The CPU implementations never leave: they are the fallback for machines without adapters and the oracle every kernel is statistically parity-tested against. A version handshake guards each bridge — on any mismatch the driver refuses and the sim keeps computing on CPU, because decoding garbage is worse than being slower.
What the GPU buys is density, not different sound: the same tick budget carries 8–16× the rays, so estimates are steadier — pure variance reduction, which is the only kind of free lunch this engine believes in.