post

Blog: Expressing values on a logarithmic scale

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.


Linear interpolation is incredibly useful, but sometime values are better expressed on a logarithmic scale. A good example is zooming in with a camera. Say you zoom in by 2x, then zoom in by 2x again, then once more. Visually you want to treat all of these zoom changes the same even though the last one is a change from 4x – 8x compared to the original zoom amount. While the following code will work, it won’t quite look right. The lower the zoom is, the faster the zoom rate will change. If you need some Google Earth style 100,000:1 zooming, it will definitely look wrong!

// Not-quite-constant rate zooming. :(
zoom = lerp(zoom, targetZoom, deltaTime/duration)

[embedded content]

Compare the two sides. Notice how the left side seems to speed up and slow down even though it starts and ends on the correct zoom level. That’s what regular linear interpolation looks like for the camera zoom. The right side keeps the same zoom speed the whole time. So how do you do that?

What you want to do, is convert the zoom values to a logarithmic scale, then convert them back to linear afterwards. No matter what your endpoints are, the zooming will always look smooth.

// Constant rate zooming!
zoom = exp(lerp(log(zoom), log(targetZoom), deltaTime/duration)

If you dust off that old sheet of power rules from your algebra class, you can simplify it a bit to this:

// Slightly simpler constant rate zooming!
zoom = zoom*pow(targetZoom/zoom, deltaTime/duration)

// ..or as a function:
float logerp(float a, float b, float t){
  return a*pow(b/a, t);
}

If your camera’s zoom is always changing to meet a target zoom level, you can combine it with the lerp() smoothing trick I posted about a few days ago. We did this in an old space game that we worked on to make the zooming extra smooth.

[embedded content]

Cheers, and happy zooming!

Leave a Reply