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