flutter3d
Showcase Changelog 38 packages API reference

Distance rolloff

since 0.1.0 Simulation, audio and XR

Attenuation is how a sound gets quieter with distance, and it is a hierarchy rather than a single formula: a footstep and a siren do not fade the same way, and a game can write its own curve alongside the three built in ones.

Step 1: Three curves #

InverseRolloff falls off as one over distance, which is closest to how sound actually behaves. LinearRolloff runs straight from full to silent. ExponentialRolloff is steep near the source and trails off slowly after.

static const curves = <String, Attenuation>{
  'inverse': InverseRolloff(),
  'linear': LinearRolloff(),
  'exponential': ExponentialRolloff(),
};

Step 2: Sample each one #

Every curve answers gainAt the same way: a number from 0 to 1 at a given distance.

const distances = <double>[1.0, 5.0, 10.0, 20.0];
final lines = <String>[
  for (final entry in curves.entries)
    '${entry.key}: ${[for (final d in distances) entry.value.gainAt(d).toStringAsFixed(2)].join(', ')}',
];

Step 3: Check the shape #

const inverse = InverseRolloff();
const linear = LinearRolloff();
final closer = inverse.gainAt(5.0) > inverse.gainAt(10.0);
final silentPastMaximum = linear.gainAt(linear.maximum + 1.0) <= 0.0;

Every curve gets quieter as distance grows, and none of them has anything left to say beyond its own maximum.

Step 4: Draw the curves #

The page plots all three against distance, thirty metres wide. Slide Distance and the marker sweeps along them, each curve's dot reading off what that curve answers there. The inverse curve drops fast and then lingers; the linear one falls in a straight line to nothing at its maximum; the exponential one sits between them. The same gainAt call draws the whole plot, for the same three curves as before.

static const curves = <String, Attenuation>{
  'inverse': InverseRolloff(),
  'linear': LinearRolloff(),
  'exponential': ExponentialRolloff(),
};