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:

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.