Three.js From Zero · Article s9-02
S9-02 Spatial Audio
Season 9 · Article 02
Spatial Audio
Sounds come from specific points in 3D. PannerNode + HRTF: close your eyes, turn your head, the audio turns with you. Headphones essential.
1. PannerNode
const panner = ctx.createPanner();
panner.panningModel = 'HRTF'; // or 'equalpower' for cheaper
panner.distanceModel = 'inverse'; // or 'linear' or 'exponential'
panner.refDistance = 1; // at 1m unit, full volume
panner.maxDistance = 10; // above 10m, nothing
panner.rolloffFactor = 1; // attenuation rate
// Set position in 3D
panner.positionX.value = 2;
panner.positionY.value = 0;
panner.positionZ.value = -1;
// Orientation (cone direction)
panner.orientationX.value = -1;
source.connect(panner).connect(ctx.destination);
2. AudioListener position
// The "ears" — usually matches camera
ctx.listener.positionX.value = cam.x;
ctx.listener.positionY.value = cam.y;
ctx.listener.positionZ.value = cam.z;
// forward + up vectors
ctx.listener.forwardX.value = -sin(yaw);
ctx.listener.forwardZ.value = -cos(yaw);
ctx.listener.upY.value = 1;
3. Three.js PositionalAudio
const listener = new THREE.AudioListener();
camera.add(listener);
const sound = new THREE.PositionalAudio(listener);
sound.setBuffer(buffer);
sound.setRefDistance(1);
sound.setMaxDistance(10);
sound.setDistanceModel('inverse');
sound.setLoop(true);
sound.play();
// Attach to a mesh — audio follows it
mesh.add(sound);
Three.js wires position/orientation automatically as camera and objects move.
4. HRTF explained
Head-Related Transfer Function. How your head shape filters sound differently by direction. Convolves incoming audio with an HRIR (impulse response) matching the direction.
Result with headphones: brain localizes the sound in 3D space. Even front/back.
5. Distance model
- Linear: gain = 1 - (dist - refDistance) / (maxDistance - refDistance). Simple.
- Inverse: gain = refDistance / (refDistance + rolloff * (dist - refDistance)). Physically plausible.
- Exponential: gain = pow(dist / refDistance, -rolloff). Dramatic falloff.
6. Live demo — orbit a sound around camera
–
7. Doppler (deprecated but mentionable)
Web Audio removed Doppler in 2018. Roll your own by adjusting playbackRate based on relative velocity. Or use Resonance Audio (Google library).
8. Resonance Audio / Omnitone
Advanced spatial libraries:
- Resonance Audio: ambisonic rendering, room models.
- Omnitone: ambisonic decoder.
- Meta's XR audio SDK for VR.
9. Tips
- Headphones required for HRTF to work. Speakers kill most of the effect.
- Keep sounds above AudioContext.listener by ≥0.3m — very close sounds thrash.
- Limit simultaneous panners. Each is a convolution. 20 max on mobile.
- Sound FX: use HRTF. Music beds: stay 2D (mono or stereo), cheaper.
10. Takeaways
- PannerNode + HRTF = 3D sound via headphones.
- Listener matches camera. Panners match sound-emitting objects.
- Distance model controls falloff.
- Three.js PositionalAudio wires everything automatically.
- Resonance Audio for advanced room simulation.