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.

Season 9 · Article 02

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.