Lerp
rachsmith.com
rachsmith.com
x'(t) = 0.2(b - x(t))
where b is the final position, x is the current position as a function of time, and t is time.
Solving this linear differential equation gives us:
x(t) = b + e^(-0.2t)
which up to a change in constants is what easings.net would call easeOutExpo [1]. So the usual way you would describe this "lerp" in computer graphics would be "exponential ease-out". This solved version of the ODE also gives us a function that isn't dependent on the framerate, so in practice the direct form with the exponential function is preferable for implementation (unless you're in a very constrained environment).
Your final equation will guarantee that you will end up at (a given closeness to) the target at a given time, wherever that target might be, and however fast it might be moving away.
Using the (poorly-named) approach in the article gives you a subtly different behavior, where the easing is essentially "reset" each frame. If you "run away" from the easing object at the right speed, you can delay it reaching you for an arbitrarily long amount of time, which has a different feel, and different practical consequences depending on the context. This is demonstrated in the "Follow the mouse" example in the article.
Lerp, on the other hand, is linear; the interpolation speed should not change:
Lerp(int A, int B, float t) { return (1.f-t)A + (tB); }
In the example implementation I present, it's assumed that t is pre-modulated by the framerate delta time, and within the bounds (0.f, 1.f)
You can easily make a PD controller out of a lerp, but (without a lot of gymnastics) you can't create a lerp out of a PDC.. at least as far as I know.
(targetPosition.x - position.x)0.2 == ekP
A derivative term would be applied to the difference between the previous and current error, usually in order temper the rate of change. D terms can be a proper headache in practice, especially if you have any noise in your system...
Much to my surprise, steering a car in proportion to how far off track it is turns into an oscillation, and the more you damp the proportional term, the more unstable and divergent the oscillation gets! Well I’d had differential equations in college, but when someone told me that me PID controllers were the solution to my driving AI, I was very surprised I’d never heard of them before.
PID controllers are neat, they’re almost like a suspension shock with an adjustable spring that has damping and rebound controls, but unitless and you can plug them into anything.
I've written that exact function in multiple languages for probably a dozen projects or more.
Where lerp would be great is showing indirect results of some actions: a non-obvious effect shown as a slower animation may give a better idea of what is happening, when you were not tracking the value previously. The scrolling demo gives a glimpse of it, but it's still a bit too direct to benefit seriously.
But as you hint, in many situations a gradual change of the presentation will allow a user a lot more awareness of the presentation and it's interconnections as a whole.
With scrolling, the idea is usually you're looking at a massive block of text with some images. Why are you scrolling?
Sometimes, you may know exactly where on the page you're trying to go -- in which case lerp will interfere with the interaction.
But in most cases, your using the scroll feature to skim and find the correct place, in which case an animated scroll will serve the user better since the content will have a predictable location throughout the presentation.
I wouldn't want it for an object I was directly controlling (what's needed is faster sampling rate), but likely great for less controlled objects. Or maybe just change the parameters to make it track more closely (adjustible)?
I think the examples are made this way specifically for you to notice the effect. Animations can, and should be employed sparingly and made fast. However, there are quite a few places where adding just a little touch of animation helps immensely: buttons that react to the touch, slight dampening of the scroll when you jump to an anchor link (so that the eye adjusts to the new page position), state changes etc.
Personal gripe: Older versions of iOS were quite good with that, but then they've made a ton of animations, and made them slow.
But yeah, please don't call this lerping, as others have mentioned.
Real lerp is one of a a whole constellation of easing functions[1][2], and indeed playing with variations of "how does f(t) vary from 0–1 as t varies from 0–1" is super useful in all sorts of contexts.
But "get X% closer to the (moving) target every frame" is a more complicated thing. It is not just a f(t) easing function, even if the math overlaps.
In fact, this confusion has already had articles written about it[3] so I swear it's not just me!
I don't think the approach mentioned in TFA is wrong per-se. Situations vary, and it can be useful. But there is enough terminology confusion in CS already.
One downside of the approach: you never know _when_ you'll reach your target. Also, especially with the slider example, the feedback feels much more "sloppy." I much prefer the tighter-feeling simple version. But in some cases, like when an enemy is chasing you in a video game, it can be a useful simple-to-implement technique. Be sure to cap your min/max velocities, though.
[1] https://github.com/Michaelangel007/easing
[2] https://easings.net/ (CSS-centric)
[3] https://medium.com/swlh/youre-using-lerp-wrong-73579052a3c3
The article titled Lerp is hosted on a site where it appears that Rach Smith is the author.
The author in GP's [3] You’re Using Lerp Wrong is Matt Harzewski.
What did I miss that makes "the person who posted this article on lerp also posted the article you linked"?
The irony I saw is that article [3] linked above directly addresses the shortcomings of the article discussed here.
Anytime you see an interpolation that does not use a time-component, that interpolation will be (wildly) different on different devices.
Though there are cases like iOS cross-origin frames where it's throttled to 30fps [2] for power-saving reasons.
[1] https://developer.mozilla.org/en-US/docs/Web/API/window/requ...
Every time you call it, it moves by the same amount.
This is how people did animations back when PCs were always the same speed, so you didn't need to worry about frame rate changes. And it's why they had to add a "turbo" button to the next generation of PCs...because many games weren't playable when the clock rate was nearly 2x the previous generation.
So it's an example that can't be used. The details aren't irrelevant. They're crucial.
So unless the goal is a fluff article that isn't actually useful for anything, it's deceptive. Run these animations on a 200FPS screen and they'll look very different than at 60FPS.
That being said, there's a place for everything! And I like the author's simple implementation.
The user agent developers realised that over time the relative amount of users that will bother to customise their user agent has been out-grown by the amount of users that won't to such a great degree that the number of people in the former group can now be considered a rounding error.
In other words, people in general just don't care. And therefore, neither will the software.
https://upload.wikimedia.org/wikipedia/commons/7/71/StatCoun...
1: itself a dreadful and laggy interface compared to just opening the file in a functional native viewer.
When a website is loading dynamically, and the UI is being reshaped on the fly with unpredictable delays, so you move your mouse to the widget you want to interact with and, by the time you actually do something with it, enough of the page has loaded that your interaction hits a completely different widget! Fun!
Yes, I use the Internet Archive's Firefox add-on, why do you ask?
Changing it to linear (I'm assuming it's 1:1 with my input now, it feels that way) was a game changer! I don't understand why companies seem so bad at the most basic things. Just let me input, interpolation just adds lag and unresponsiveness.
Of course having nice dials and ways of configuring that is best overall, because everyone's different and there's also motion sickness to be had when things don't align with your input!
A more serious treatment of the subject would've touched upon this. It would also not call this "lerp" because that name is already taken for the general form.
For example, you can fix the laggy feel of a single exponential average by repeating it. This creates a two pole lowpass filter with a steeper transient.
Z transforms from DSP provide a more formal treatment of the subject.
On another note - is it true that this would mean the animation frame function will run infinitely (even though the render will not re-render under a certain threshold)?
In some contexts, yes using Lerp to go half way to a target can lead to running forever which can cause timing bugs. If you lerp halfway to a specific point each frame and trigger an event when you reach that point then it runs infinitely. In practice it just runs until the rounding error goes to zero, but the timing for this can be weird and it adds an unwanted delay. I once spent ~2 days changing all the animations in a program to switch from using this type of smoothing to using lerp on an animation curve with a definite time duration. Exponential filters are good for smoothing a continuous parameter, but they should not be used on a bounded interval where the end point matters.
https://en.wikipedia.org/wiki/Moving_average#Exponential_mov...
https://en.wikipedia.org/wiki/EWMA_chart (note the formula for z_i)
This feels like nuking a mosquito.
I was working on a problem with a friend, where I implemented a solution as a Kalman filter, with the models "TBD", just leaving them as constant. He implemented it in parallel as EWMA, and it was a bit of a shock to me when the behavior was identical. I did a little reading after, and there seems to be a closer relationship between the two filters than I previously had thought:
https://stats.stackexchange.com/questions/16458/what-is-the-...
Could you shed some light on the specific reason this does not qualify as a PD controller, and maybe what you'd change to make it into one?
This has one error term, and one parameter. If you think of the position as the variable being controlled, then it's just a "D" controller. If you think of the velocity as the variable being controlled, then it's just a "P" controller. But unless I'm experiencing some massive confusion, you can't think of it as a PD controller.
Edit: I think I can see why you might think this is a PD controller. You can see that there's no overshoot or ringing, so you think to yourself that there must be a damping term. But the difference is that there is no plant process here! We can just decrease the error. That's why you will never get overshoot or ringing. In summary, it's a one pole filter on an error function, not a controller.
In my mind, a strictly 'P' controller should produce an oscillation, which the example did not. I then surmised it 'hides' the 'D' part of the equation by modulating the error down each step. Strictly speaking, it seems like your summary is more accurate, and I'm still not quite sure if my way of looking at it is skewed, or completely broken.
Call lerp on a linear interval, get a linear transition. Call it on a non-linear interval, get a non-linear transition. Both computed using linear interpolation. It's not lerp affecting the transition, it's how and when you call it.
Lerp be simpl.
No, we don't, lerp is just lerp. If you want to do more complex things, go do more complex things, but that doesn't change what lerp is, and it doesn't turn it into "an object in a framework".
The text explains that, but the visual illustration with the mouse chasing circle completely misses the point by not showing non -lerp animation.
This is the reason Apple animations look better than Windows and Linux animations.
The fundamental truth is that a float can disguise itself readily as a bool, but the opposite is not true. A bool cannot pull off the float's mustache.
A digraph(*) of candy coated floats can simulate the universe, forward and backwards. With rewind and seeking to any point.
Shameless plug: https://github.com/titoasty/zmooth I just published a JS library to easily make smooth interpolations, just by setting a "to" value (after doing it by hand for years) I hope you'll find it useful!
And, to be fair, self promotion in an HN comment thread about a topic is bad form too. I know you're not the OC but the point seems fair.
(IMHO "lerp" scrolling is a truly horrible experience)
Also, using a fixed portion every frame means you are now framerate-dependant, slow computers will take longer to catch up than a fast computer at 240Hz or whatever.
This is a great way of fucking up the user experience and throwing the low performance in the face of the users, instead of trying to feel responsive.
https://www.youtube.com/watch?v=L41oIvre9K0
How useful it is, is debatable, since it inherently adds lag to user input.
What is described in this blog post is not lerp.
Lerp is also not worth a blog post.
https://www.gdcvault.com/play/1027059/Math-In-Game-Developme...
To be fair, it does go all the way to a PD controller and covers the basics along the way. I can see that as a quick talk. Also, the book in slide 2 is from the speaker himself, so the presentation must have been promotional as well.
> I acknowledge the Gubbi Gubbi people, the Traditional Owners of the land and waterways where I live. I would like to pay my respects to Elders past, present and emerging.
What on earth has this got to do with linear interpolation? Odd punchline to a decent article.