• # A Brief Introduction to Lerp

General and Gameplay Programming

Linear interpolation (sometimes called 'lerp' or 'mix') is a really handy function for creative coding, game development and generative art.

The function interpolates within the range [start..end] based on a 't' parameter, where 't' is typically within a [0..1] range.

For example, divide 'loop time' by 'loop duration' and you get a 't' value between 0.0 and 1.0.

Now you can map this 't' value to a new range, such as lerp(20, 50, t) to gradually increase a circle's radius, or lerp(20, 10, t) to gradually decrease its line thickness.

Another example: you can use linear interpolation to smoothly animate from one coordinate to another. Define a start point (x1, y1) and end point (x2, y2), then interpolate the 'x' and 'y' dimensions separately to find the computed point in between.

Or use linear interpolation to spring toward a moving target. Each frame, interpolate from the current value to the target value with a small 't' parameter, such as 0.05.

It's like saying: walk 5% toward the target each frame.

A more advanced example, but built on the same concept, is interpolating from one color (red) to another (blue).

To do this, we interpolate the (R, G, B) or (H, S, L) channels of the color individually, just like we would with a 2D or 3D coordinate.

Another quick example is to choose a random point along a line segment.

There are lots of ways to use linear interpolation, and lots more types of interpolation (cubic, bilinear, etc). These concepts also lead nicely into areas like: curves, splines and parametric equations.

Source code for each of these examples is available here: https://gist.github.com/mattdesl/3675c85a72075557dbb6b9e3e04a53d9

Matt DesLauriers is a creative coder and generative artist based in London. He combines code and emergent systems to make art for the web, print media, and physical installations.

Note:
This brief introduction to lerp was originally published as a Twitter thread and is republished here with the kind permission of the original author.

Report Article

## User Feedback

Very cool article!  I use linear interpolation to smooth out visual movement, it works very nicely with variable render rates. It's also nice for visual effects like shown above.

Thanks for sharing!

##### Share on other sites

Nice article! I loved the visual examples.

I can't say how many times lerp has been the tool of choice to achieve zillions of nice looking effects using shaders, plus is the basis of rasterization!

Keep the good work

##### Share on other sites

Note that your "springing toward" example (lerping a fraction of the remaining distance each time) is highly frame-rate dependent.  So if your game isn't frame-rate locked (i.e. web-games running on machines with different monitor refresh rates, or even a locked 60 fps game running on a machine too slow to support it) different people may see different behaviors.  The spaceship rotation in George Prosser's DRILL_BIT, for instance, is much harder to use on a slow machine.

And the way you're doing it, scaling by the deltaTime, will only partly correct for that.  For instance, if your framerate is twice as fast (deltaTime is half the length) then you actually need the square root of the rate (you lerp twice in the same time, essentially multiplying by the factor twice, i.e. squaring it).  In the general case you need Math.pow:

// Return a lerp factor for the given frame time which will result in
// the value getting convergenceFraction of the way to the target in
// smoothTime time units.  I usually just use 0.9 or 0.95 for the fraction
// and vary the smoothTime to get the effect I want.
function smoothOver(dt, smoothTime, convergenceFraction) {
return 1 - Math.pow(1 - convergenceFraction, dt / smoothTime)
}

For further adventures in non-linear interpolation things, Squirrel Eiserloh's Fast and Funky 1D Non-linear Transformations GDC talk is well worth a watch.  Although note that with his later (curved) functions, he only mumbles once that he's "normalizing" them (meaning scaling them up so they are exactly one unit tall).  Without knowing that, if you try to use some of the formulas he gives as written, you'll end up with something very flat that does almost nothing.  But he gives a good intuitive introduction to how to think about constructing some of these things.

## Create an account

Register a new account

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 2
• 0
• 0
• 0
• 43

• 15
• 14
• 46
• 22
• 27
• ### Similar Content

• By achiga
I am new to shader programming. I was learning how to detect edges using shaders these days. And I found the UnityChan toon shader project. But I found it difficulty to understand when I read its implementation of sobel filter.
Especially for these s few lines:(From Line166)
depthsDiag -= centerDepth;
depthsAxis /= centerDepth;
It seems to try to get the diagonal and axial depth values. But I don't know why we need to substract centerDepth from depthsDiag and divide depthsAxis by centerDepth?

Another confusion comes from these a few lines when it tries to return the final color from fragment shader:(From line 191)

float SobelX = dot(SobelH, float4(1,1,1,1));
float SobelY = dot(SobelV, float4(1,1,1,1));   float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);       Sobel = 1.0-pow(saturate(Sobel), _Exponent);   //NK   float4 Col = tex2D(_MainTex, i.uv[0].xy);   Col = _EdgesColor * Col * (1.0 - Sobel) + Sobel;   return Col * lerp(tex2D(_MainTex, i.uv[0].xy), _TestColor, _BgFade);
What does Sobel = 1.0-pow(saturate(Sobel), _Exponent) do? And what dose Col = _EdgesColor * Col * (1.0 - Sobel) + Sobel mean?
Sorry for my bad English and hope anyone could help me understand this.
• By NikiTo
I am having an argument about this with a buddy now, and we don't believe each other.

• Hello everyone, it's my first time posting on this forum. I'm very excited to meet you.
Anyways, my first question is about procedurally generating a world. I'm seeing how to implement a procedural generated world, and placing objects after that seem to be a big challenge.
Let's say I have a big object that doesn't fit inside a chunk or that it is spawned in the frontier of a chunk. How would you go about generating the whole thing using the nearby chunks? With terrain it's pretty easy because the terrain is not hardcoded, so the algorithm is entirely free. But when I want to place hardcoded objects like castles or trees, I can't just cut the castle in half - or can I?
What's a way to approach this problem?
I'm using LWJGL/OpenGL in Java for a 2D game.

• I'm very interested in the snow physics in Red Dead Redemption 2.
Here is a demo video from YouTube.
Does anyone know the techniques behind this snow physics?
For example,
What is the shading model of the snow? How do they create snow deformation?

• I'm writing a little game for visual deficient people, but I'm having a hard time getting the mouse position. Let me explain :
I need to know where in the table the mouse cursor is, without having a click, and then I want to play a sound. That sound would be different for every position. Any thoughts? Thanks, in advance!
e.g., when the mouse is on the 1st box would be played the audio "a1", when it's on the 2nd box, "a2", and so on.
I tried with:
mouse_x, mouse_y = get_Position() if mouse_x and mouse_y == map[x][y] then if map[x][y] == 0.1 then Audio:play() But it makes a loop and the sound keeps playing forever!
×