Wednesday, June 26, 2013

Framerate Independent Damping

View / download this post as a pdf

It's been a really long time since I last posted here. Now that I'm working on starting a game company (Controlled Panic), I'm back to working on interesting problems while building our engine. This post is the first in a series exploring ways to drive a value toward a goal in a way that's easily controllable and framerate independent.

It's often the case that you find yourself wanting to take a value and decay it to zero over a short amount of time. The most obvious way to do this is to simply multiply the value by a fixed scalar every frame



The problem with this is that after one second, the amount of decay will depend on the number of frames that have occured. If you only had 1 frame, then you will have decayed by s, but if you were running at a solid 60fps, then it will have decayed by s60, which is quite different.

If we want to make the amount of decay over 1 second constant, we'll need to scale by a function of the frame duration every time instead of using a fixed scalar. Let's say that we want to decay by the scalar d every second, so our per-frame scalar becomes a function of the change in time from the last frame s(Δt)

If we look at all the frames in a second (we'll call them frame 0 through frame n) then the durations should add up to one



and the product of all s(Δti) should be d, or



Let's consider the case where we have 1 frame that lasts 1 second. Obviously in that case s(1.0) should be d. And if we had two frames (both 0.5 seconds) then we can see that s(0.5) should be the square root of d or d0.5. It's fairly intuitive to see for any fixed frame rate n that



Then if we suppose that s(Δt) = dΔt in the general case with frames of arbitrary duration, and we plug it into (2) we get



And substituting (1)



So we can see that the formula s(Δt) = dΔt has the desired effect of decaying our value by the scalar d every second.

This approach is fairly limited in its usefulness, so next time we'll look at using a critically damped spring model to do something similar.

No comments:

Post a Comment