Three.js From Zero · Article s9-02
Spatial Audio
Spatial Audio is Article s9-02 of Three.js From Zero, a MasterAllArts free interactive lesson for artists learning creative 3D on the web.
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.