Ambience Overview
Like how emitters can cast occlusion and permeation rays towards other emitters to determine how muffled they are, emitters can also cast ambient rays that determine how muffled ambient sounds like rain and wind should be.
To enable this, set these four settings on an Emitter to a value greater than 0:
var listener = new Emitter()
{
AmbientOcclusionRayCount = 1024,
AmbientOcclusionBounceCount = 8,
AmbientPermeationRayCount = 128,
AmbientPermeationBounceCount = 3,
};
Ambient occlusion rays bounce around the environment and when they hit the edge of the world (defined by context.WorldPosition and context.WorldSize), they will be marked as 'outdoor' rays (i.e. rays that reached the edge of the world).
Ambient permeation rays also bounce around the environment, and on each bounce cast another ray in a random direction. These rays travel through the entire world, losing energy based on the material and thickness of the primitives they pass through.
The total energy in across all ambient occlusion and ambient permeation rays is passed to the listener.AmbientGainFormula function, to convert them to gain values:
listener = new Emitter()
{
AmbientGainFormula = (
bool lowFrequency,
int occlusionRayCount,
int permeationRayCount,
int permeationBounceCount,
float occlusionEnergy,
float permeationEnergy
) =>
{
float gain = 0.0f;
if (occlusionRayCount > 0)
{
// 10% energy required to be at max volume
float rayThreshold = 0.1f * occlusionRayCount;
gain += occlusionEnergy / rayThreshold;
}
if (permeationRayCount > 0 && permeationBounceCount > 0)
{
// 10% energy required to be at max volume
float rayThreshold = 0.1f * (permeationRayCount * permeationBounceCount);
gain += permeationEnergy / rayThreshold;
}
return MathF.Min(1, gain);
}
}
Note this formula is optional. If left untouched or set to null, it will default to the above 10% thresholds for both occlusion and permeation energy. Read more: Ambient Gain Formula.
The result of this function is stored in the AmbientFilter object on the emitter, which is null until raytracing is performed at least once:
// Wait for raytracing to complete
if (listener.AmbientFilter != null)
{
var gainLF = listener.AmbientFilter.GainLF;
var gainHF = listener.AmbientFilter.GainHF;
}