Posts for the month of May 2015

# Damping with delta-time

Just a quick tip on how to convert usual damping code to something framerate-independent.

Most of us have probably, at some point, written code resembling this:

```// Perform velocity damping
velocity -= velocity * 0.01f;
```

… or probably the more correct:

```// Per-second damping coefficient
float const D = 10.0f;

// Damp velocity according to timestep
velocity -= velocity * D * delta_time;
```

Yet this is not fully framerate-independent; results are slightly different at 30fps and 60fps, and more importantly, spikes in the framerate cause lots of weird artifacts, causing developers to attempt to fix the situation by clamping `delta_time`, which is not ideal.

## The exponentiation method

Here is one way to fix it: assume that the code works correctly at 60 fps. This means that each frame, `velocity` is effectively multiplied by `1 - D / 60`.

After one second, i.e. 60 frames, `velocity` has been multiplied by `(1 - D / 60) ^ 60`.

After two seconds, it has been multiplied by `(1 - D / 60) ^ (60 * 2)`.

After `N` seconds, it has been multiplied by `(1 - D / 60) ^ (60 * N)`.

So, there, we have a formula that tells us what happens after `N` seconds, and it’s a continuous function. We can therefore choose `N` as we like, and especially `N = delta_time`:

```// Per-second damping coefficient
float const D = 10.0f;

// Damp velocity (framerate-independent)
velocity *= pow(1.f - D / 60.f, 60.f * delta_time);
```

Which can be conveniently rewritten as:

```// Per-second damping coefficient
float const D = 10.0f;
// Exponentiation base for velocity damping
float const D2 = pow(1.f - D / 60.f, 60.f);

// Damp velocity (framerate-independent)
velocity *= pow(D2, delta_time);
```

## Use with lerp

The same method can be adapted to uses of linear interpolation such as this one:

```// Perform velocity damping
velocity = lerp(velocity, target_velocity, K * delta_time);
```

Which we replace with:

```// Damp velocity (framerate-independent)
velocity = lerp(velocity, target_velocity,
1.f - pow(1.f - K / 60.f, 60.f * delta_time));
```