Lerp & Remap

If you had to keep just one function from all of game programming, it would be this one. Linear interpolationlerp for short — blends smoothly from a start value a to an end value b as a parameter t slides from 0 to 1. Health bars, camera dollies, fading audio, colour gradients, loading-screen progress — under the hood it is almost always a lerp.

From a straight line to remap, line by line

Step 1 — write the blend. Start at a and walk a fraction t of the way toward b. The gap to cover is (b - a), so:

\operatorname{lerp}(a, b, t) = a + (b - a)\,t.

Step 2 — check the endpoints. At t = 0 the second term vanishes and we get a; at t = 1 we get a + (b - a) = b. Exactly the start and exactly the end — no rounding drift, ever.

Step 3 — the symmetric "weighted average" form. Expand and regroup the same expression:

a + (b - a)\,t = a - a\,t + b\,t = (1 - t)\,a + t\,b.

This is lerp as a weighted average: weight (1 - t) on the start, weight t on the end, and the two weights always sum to 1. Both forms are identical; engines tend to ship the first (one multiply) and mathematicians prefer the second (the symmetry is obvious).

Step 4 — run it backwards: inverse lerp. Forward lerp asks "given t, what value?". The reverse asks "given a value v, what fraction of the way is it?". Solve v = a + (b - a)\,t for t:

\operatorname{invlerp}(a, b, v) = \frac{v - a}{\,b - a\,}.

At v = a this is 0, at v = b it is 1 — the perfect undo of Step 1. (It needs a \ne b, or you would divide by a zero-width range.)

Step 5 — chain them into remap. To move a value v from one range [a, b] into another [c, d], first find its fraction in the source with inverse lerp, then play that fraction forward in the destination with lerp:

\operatorname{remap}(a, b, c, d, v) = \operatorname{lerp}\big(c,\, d,\, \operatorname{invlerp}(a, b, v)\big) = c + (d - c)\,\frac{v - a}{\,b - a\,}.

That single line maps a joystick's [-1, 1] to a turret's [0^\circ, 90^\circ], or a noise value's [0, 1] to a terrain height — it is inverse-lerp composed with lerp, nothing more.

Step 6 — clamp so you don't overshoot. Nothing in the algebra stops t from leaving [0, 1]: a t = 1.4 extrapolates past b, which can push a health bar past full or a colour out of gamut. Pin t to the legal range first:

\operatorname{clamp}(t) = \min\big(1,\, \max(0,\, t)\big),

then lerp with the clamped value. Want the smooth-start, smooth-stop version? Reshape that clamped t before blending — that is the very next page, smoothstep & easing.

For a parameter t and values a, b, c, d, v:

Lerp blends anything you can scale and add — and a position qualifies, so lerping the point on a segment from A to B just lerps each coordinate. But an orientation does not live in a flat space: blending two rotations by straight component lerp drifts off the unit sphere and changes speed mid-turn. The fix is SLERP, spherical linear interpolation, which walks the great-circle arc at constant angular speed. Same idea — a steady blend from one thing to another — but on a curved space rather than a line. Lerp is the flat-world special case; SLERP is what you reach for the moment "the thing" is a rotation.

Lerp moves at constant speed — equal steps in t always give equal steps in the blended value, from the very first instant to the very last. That is exactly right for, say, dragging a slider. It is exactly wrong for anything meant to feel natural, like a camera easing to a stop or a menu sliding into place: a plain lerp snaps from stationary to full speed the moment it starts, and from full speed to a dead stop the moment it ends — a visible little jerk at both ends that reads as mechanical, not smooth.

The fix isn't a different blend formula — it's a different input. Reshape t itself so it starts and ends slowly and only moves fastest in the middle, then feed that reshaped value into the same lerp. That reshaping is exactly what smoothstep and easing does — the next page in this chain.

Slide t and watch the point blend

Point A (blue) and B (green) sit on a line; the orange dot is \operatorname{lerp}(A, B, t). Drag t from 0 to 1 and the dot slides exactly from A to B, equal steps in t giving equal steps in distance. The readout shows the blended x-value and its remap into a health range [0, 100] — the same t, replayed in a different range.