Yesterday I watched Freya's new video about
lerp smoothing and it reminded me of the damping implementation of
Cinemachine to control camera motion smoothly. In this blog post, I will
give you more perspectives to understand the framerate-independent
interpolation other than the ones deduced from Freya's video.
Frame-Dependent
Interpolation
Let's first recap the frame-dependent interpolation. Let be the source position, the target position, and is a fixed value representing
the ratio will go through towards
, and be the current position after iterations (frames). The update
equation is:
with being the original
source position. We can recursively expand this equation:
It is obvious that is
dependent on , which generally
represents the frames per second (FPS). and produce significantly different
results.
Frame-Independent
Interpolation
The naive interpolation is frame-dependent because it's updated based
on the unit of frames, rather than seconds. We would like the
interpolation function , if
is generalized to , is only dependent
on the elapsed time rather than
the frame rate.
Freya has given an interpretation to solve in her video. In the following
sections I will give three more perspectives of understanding and
solving .
Perspective #1:
Solving the Function Equation
What we need is: for any
and any , the
following equation holds:
This equation means that at any timestamp , no matter how many pieces we segment
into, the accumulated
interpolation result is always equal to the one without segmentation.
is the number of segments and
is applying sequentially times.
We can derive
explicitly:
Having it equal to :
Let's prove that must be an
exponential function, assuming .
First, we rewrite the above funciton equation to:
This means that the original equation also holds for .
We also have:
This means that the original equation also holds for . We can prove it further
holds for by
leveraging the property that
is continuous. In ,
we take and get:
is therefore an exponential
function subtracted by , which can
be represented by . Substituting this form into :
and this is why we choose a negative power: we would like to value to
lie within . At each frame, we
update the value of using where is elapsed time during this
frame. As long as the FPS is stable, the result is definitely
frame-independent.
Perspective #2:
Solving the Differential Equation
From another perspective, we can view as a function of , i.e., where is the initial value. For any we can compute its value at :
which can be simplified to:
Solving this differential equation we have where is to be determined. Substituting
we solve . Hence the final equation for is where . This aligns with the result
from the first perspective.
Perspective #3:
Rewriting the Naive Lerp
Actually, we can even produce the same result of from the naive interpolation
formula. Starting from the naive update equation for the -th frame:
assuming is the frames per
second, e.g., , or . It should be particularly noticed
that the unit of is percent per
frame, or . We would
like to transform the unit of to
percent per second, or
representing how many percentages
will go through towards per second rather than per frame. To this end, we need
to first view in the unit of
and multiply it with
some value with unit so
that it can be used at each frame to update the input value.
The question is, what value has the unit . Recall that the unit of is , and its inverse, which
represents the elapsed time per frame, has unit . Therefore, we just need to
multiply with the inverse of
, and this becomes:
where has unit instead of . Well, will definitely remind you of
the following limit:
If we take limits for ,
the update equation now will be:
Note that the is the update formula for one second.
For one frame, we need to multiply with , the elapsed time per frame:
This is exactly what we've derived from the second perspective!
You may wonder why you cannot directly use as the update formula, i.e. . Of course you can do this! It's much simpler and is more
performant (not involving the exponential function), and it's a pretty
good approximation to . But if you want a more accurate frame-independent
interpolation formula, you should use the version.
Conclusion
In this short post, I introduced three perspectives to understand the
frame-independent interpolation. Don't get stuck with the details, just
use the very neat and clean form of interpolation: the exponential
function. If you want to know what we can do to mitigate when FPS is
unstable, you can read this post. Thanks for
reading!