Skip to content

Reflections and Reverb

Three Steam Audio can simulate how sound reflects off surrounding geometry. This produces two renderable effects:

  • Per-source reflections — indirect sound that reaches the listener from a specific source.
  • Listener reverb — ambient reverberation at the listener position.

Both effects use Steam Audio’s parametric reflection effect. Convolution or hybrid reflection effects are not supported in this version because their IR handles cannot cross independent WASM runtimes.

Reflections must be enabled when the world is created. Choose upper bounds for rays, duration, and Ambisonic order; these reserve native memory.

import {
const createWorld: (options: WorldOptions) => Promise<World>
createWorld
} from 'three-steam-audio'
const
const audioContext: AudioContext
audioContext
= new
var AudioContext: new (contextOptions?: AudioContextOptions) => AudioContext

The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode.

MDN Reference

AudioContext
()
const
const world: World
world
= await
function createWorld(options: WorldOptions): Promise<World>
createWorld
({
WorldOptions.audioContext: AudioContext
audioContext
,
WorldOptions.reflections?: false | {
diffuseSamples?: number;
maxDuration?: number;
maxOrder?: number;
maxRays?: number;
} | undefined
reflections
: {
maxRays?: number | undefined
maxRays
: 4096,
maxDuration?: number | undefined
maxDuration
: 2,
maxOrder?: number | undefined
maxOrder
: 1,
diffuseSamples?: number | undefined
diffuseSamples
: 32,
},
})

A ReflectionBusNode renders per-source reflections. Create one from the world, connect it to the audio destination, then connect each source to it.

import {
const createWorld: (options: WorldOptions) => Promise<World>
createWorld
} from 'three-steam-audio'
const
const audioContext: AudioContext
audioContext
= new
var AudioContext: new (contextOptions?: AudioContextOptions) => AudioContext

The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode.

MDN Reference

AudioContext
()
const
const world: World
world
= await
function createWorld(options: WorldOptions): Promise<World>
createWorld
({
WorldOptions.audioContext: AudioContext
audioContext
,
WorldOptions.reflections?: false | {
diffuseSamples?: number;
maxDuration?: number;
maxOrder?: number;
maxRays?: number;
} | undefined
reflections
: {
maxRays?: number | undefined
maxRays
: 4096,
maxDuration?: number | undefined
maxDuration
: 2,
maxOrder?: number | undefined
maxOrder
: 1,
diffuseSamples?: number | undefined
diffuseSamples
: 32,
},
})
const
const reflections: ReflectionBusNode
reflections
=
const world: World
world
.
function createReflectionBus(settings?: ReflectionBusSettings): ReflectionBusNode
createReflectionBus
({
ReflectionBusSettings.wet?: number | undefined
wet
: 1 })
const reflections: ReflectionBusNode
reflections
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const audioContext: AudioContext
audioContext
.
BaseAudioContext.destination: AudioDestinationNode

The destination property of the BaseAudioContext interface returns an AudioDestinationNode representing the final destination of all audio in the context. It often represents an actual audio-rendering device such as your device's speakers.

MDN Reference

destination
)
const
const source: Source
source
=
const world: World
world
.
function createSource(settings?: SourceSettings): Source
createSource
({
SourceSettings.reflections?: boolean | ReflectionSettings | undefined
reflections
: {
ReflectionSettings.wet?: number | undefined
wet
: 0.7 } })
const
const node: SteamAudioNode
node
=
const world: World
world
.
function createNode(sourceValue: Source): SteamAudioNode
createNode
(
const source: Source
source
)
const
const oscillator: OscillatorNode
oscillator
= new
var OscillatorNode: new (context: BaseAudioContext, options?: OscillatorOptions) => OscillatorNode

The OscillatorNode interface represents a periodic waveform, such as a sine wave. It is an AudioScheduledSourceNode audio-processing module that causes a specified frequency of a given wave to be created—in effect, a constant tone.

MDN Reference

OscillatorNode
(
const audioContext: AudioContext
audioContext
, {
OscillatorOptions.frequency?: number | undefined
frequency
: 440 })
const oscillator: OscillatorNode
oscillator
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const node: SteamAudioNode
node
)
const node: SteamAudioNode
node
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const audioContext: AudioContext
audioContext
.
BaseAudioContext.destination: AudioDestinationNode

The destination property of the BaseAudioContext interface returns an AudioDestinationNode representing the final destination of all audio in the context. It often represents an actual audio-rendering device such as your device's speakers.

MDN Reference

destination
)
const oscillator: OscillatorNode
oscillator
.
AudioScheduledSourceNode.start(when?: number): void

The start() method on AudioScheduledSourceNode schedules a sound to begin playback at the specified time. If no time is specified, then the sound begins playing immediately.

MDN Reference

start
()
const
const connection: ReflectionConnection
connection
=
const node: SteamAudioNode
node
.
SteamAudioNode.connectReflections(bus: ReflectionBusNode, options?: {
gain?: number;
}): ReflectionConnection
connectReflections
(
const reflections: ReflectionBusNode
reflections
, {
gain?: number | undefined
gain
: 1 })
// Later, change the send level:
const connection: ReflectionConnection
connection
.
ReflectionConnection.setGain: (gain: number) => void
setGain
(0.5)
// To disconnect:
// connection.disconnect()

A ReverbBusNode renders listener-centric reverb. Enable listener reverb, create a reverb bus, and connect sources to it.

import {
const createWorld: (options: WorldOptions) => Promise<World>
createWorld
} from 'three-steam-audio'
const
const audioContext: AudioContext
audioContext
= new
var AudioContext: new (contextOptions?: AudioContextOptions) => AudioContext

The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode.

MDN Reference

AudioContext
()
const
const world: World
world
= await
function createWorld(options: WorldOptions): Promise<World>
createWorld
({
WorldOptions.audioContext: AudioContext
audioContext
,
WorldOptions.reflections?: false | {
diffuseSamples?: number;
maxDuration?: number;
maxOrder?: number;
maxRays?: number;
} | undefined
reflections
: {
maxRays?: number | undefined
maxRays
: 4096 },
})
const world: World
world
.
listener: Listener
listener
.
Listener.setReverb: (settings: false | ReverbSettings) => void
setReverb
({
ReverbSettings.reverbScale?: ThreeBand | undefined
reverbScale
: [1.8, 1.6, 1.3],
})
const
const reverb: ReverbBusNode
reverb
=
const world: World
world
.
function createReverbBus(settings?: ReverbBusSettings): ReverbBusNode
createReverbBus
({
ReverbBusSettings.wet?: number | undefined
wet
: 1 })
const reverb: ReverbBusNode
reverb
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const audioContext: AudioContext
audioContext
.
BaseAudioContext.destination: AudioDestinationNode

The destination property of the BaseAudioContext interface returns an AudioDestinationNode representing the final destination of all audio in the context. It often represents an actual audio-rendering device such as your device's speakers.

MDN Reference

destination
)
const
const source: Source
source
=
const world: World
world
.
function createSource(settings?: SourceSettings): Source
createSource
()
const
const node: SteamAudioNode
node
=
const world: World
world
.
function createNode(sourceValue: Source): SteamAudioNode
createNode
(
const source: Source
source
)
const
const oscillator: OscillatorNode
oscillator
= new
var OscillatorNode: new (context: BaseAudioContext, options?: OscillatorOptions) => OscillatorNode

The OscillatorNode interface represents a periodic waveform, such as a sine wave. It is an AudioScheduledSourceNode audio-processing module that causes a specified frequency of a given wave to be created—in effect, a constant tone.

MDN Reference

OscillatorNode
(
const audioContext: AudioContext
audioContext
, {
OscillatorOptions.frequency?: number | undefined
frequency
: 440 })
const oscillator: OscillatorNode
oscillator
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const node: SteamAudioNode
node
)
const node: SteamAudioNode
node
.
AudioNode.connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode (+1 overload)

The connect() method of the AudioNode interface lets you connect one of the node's outputs to a target, which may be either another AudioNode (thereby directing the sound data to the specified node) or an AudioParam, so that the node's output data is automatically used to change the value of that parameter over time.

MDN Reference

connect
(
const audioContext: AudioContext
audioContext
.
BaseAudioContext.destination: AudioDestinationNode

The destination property of the BaseAudioContext interface returns an AudioDestinationNode representing the final destination of all audio in the context. It often represents an actual audio-rendering device such as your device's speakers.

MDN Reference

destination
)
const oscillator: OscillatorNode
oscillator
.
AudioScheduledSourceNode.start(when?: number): void

The start() method on AudioScheduledSourceNode schedules a sound to begin playback at the specified time. If no time is specified, then the sound begins playing immediately.

MDN Reference

start
()
const node: SteamAudioNode
node
.
SteamAudioNode.connectReverb(bus: ReverbBusNode, options?: {
gain?: number;
}): ReverbConnection
connectReverb
(
const reverb: ReverbBusNode
reverb
, {
gain?: number | undefined
gain
: 0.4 })

Reflection simulation is expensive. Three Steam Audio runs reflection tracing in a dedicated Worker when Worker is available and reflections are enabled. If the worker cannot be created, the simulation falls back to the main thread.

You can reduce CPU usage at runtime without recreating the world:

import {
const createWorld: (options: WorldOptions) => Promise<World>
createWorld
} from 'three-steam-audio'
const world: World
world
.
function setReflectionSettings(settings: RuntimeSimulationSettings): void
setReflectionSettings
({
RuntimeSimulationSettings.rays?: number | undefined
rays
: 1024,
RuntimeSimulationSettings.bounces?: number | undefined
bounces
: 4,
RuntimeSimulationSettings.duration?: number | undefined
duration
: 1,
RuntimeSimulationSettings.order?: number | undefined
order
: 0,
})

Values are clamped to the maximums declared when the world was created.