# The math behind easing functions

**URL:** <https://discourse.threejs.org/t/the-math-behind-easing-functions/76358>\
**Category:** Resources\
**Tags:** easing, animation\
**Created:** [January 11, 2025, 1:21pm UTC](https://discourse.threejs.org/t/the-math-behind-easing-functions/76358 "2025-01-11T13:21:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![vielzutun.ch](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vielzutun.ch/32/21366_2.png) [@vielzutun.ch](https://discourse.threejs.org/u/vielzutun.ch)\
**Post date:** [January 11, 2025, 1:21pm UTC](https://discourse.threejs.org/t/the-math-behind-easing-functions/76358/1 "2025-01-11T13:21:01Z")

</div>

**[Edit:]** fixed bottom diagram legend

Inspired by [this thread](https://discourse.threejs.org/t/how-to-use-easing-functions-to-improve-lerp-slerp/40766), particularly by this illustration:

[![](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/5/f/5fd770f65fa8da2a43ec88dc3623c2641ae035a3.png) ](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/5/f/5fd770f65fa8da2a43ec88dc3623c2641ae035a3.png)

it occurred to me, that using a **quadratic** easing function you have to decide between **either** “smooth departure” **or** “smooth arrival”.

The smoothness of the movement is intuitively recognizable by the horizontal tangent at departure- or -arrival point.

What if you wanted both smooth departure **and** smooth arrival at both ends of a movement? You’d obviously need horizontal tangents at both ends, with a continuous (albeit not constant!) slope in between.

A **Cosine** function can give you just that: scaled by 0.5 in order to map the initial value range of [-1.0 … +1.0] to [-0.5 … +0.5], then vertically shifted by 0.5 gives you a value range of [0.0 … 1.0] already. Then map the input range of [-π/2 … π/2] to [0.0 … 1.0] and you’ll be set.

In case you’re wary of the performance impact of computing a trig function on every frame: a **polynome of 3rd degree** gives you very similar results. Someone made a [quite nifty](https://www.geogebra.org/m/XMXrGmeP) interactive cubic polynome grapher, where you can modify the A, B, C, D values of the generic cubic polynome

`A * x^^3 + B * x^^2 + C * x + D = 0`

via interactive sliders and immediately see the result of any change.

Turns out (after a little algebra), that a cubic polynome having A = -2, B = 3, C = 0, D = 0 satisfies the four boundary conditions:

- input = 0, output value = 0
- input = 1, output value = 1
- input = 0, output slope = 0
- input = 1, output slope = 0

 ![easing](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/d/3/d3b5d199a1679abd5d0a392f1c591247fe41f269.png)

[easing.xlsx](https://discourse.threejs.org/uploads/short-url/zCRif47ApgINkXOeUhpqyuoD9F6.xlsx) (18.4 KB)

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [January 13, 2025, 11:52am UTC](https://discourse.threejs.org/t/the-math-behind-easing-functions/76358/2 "2025-01-13T11:52:48Z")

</div>

you might dig this: [https://www.youtube.com/watch?v=mr5xkf6zSzk](https://www.youtube.com/watch?v=mr5xkf6zSzk)

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [January 13, 2025, 6:58pm UTC](https://discourse.threejs.org/t/the-math-behind-easing-functions/76358/3 "2025-01-13T18:58:29Z")

</div>

This **y(x)=–2x3+3x2** is exactly how `smoothstep` in OpenGL/WebGL is being calculated.

[https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml)

---

<div class="post-metadata">

**Author:** ![vielzutun.ch](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vielzutun.ch/32/21366_2.png) [@vielzutun.ch](https://discourse.threejs.org/u/vielzutun.ch)\
**Post date:** [January 14, 2025, 5:55am UTC](https://discourse.threejs.org/t/the-math-behind-easing-functions/76358/4 "2025-01-14T05:55:06Z")

</div>

I didn’t know that. But it shouldn’t come as a surprise that, given the identical set of boundary conditions as the aforementioned, different people would arrive at the identical solution. How did they (or I, for that matter) do that?

1st, it takes a faint or better memory of which functions will give you both a minimum (having slope = 0) at a low value (0) and a maximum (also having a slope = 0) at a higher value (1). A cubic polynome will do. Writing their equations down:

 ![Bildschirmfoto 2025-01-14 um 06.31.03](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/5/4/54701ca458d9c8fc429430d9f562039eab0a88af.png)

and plugging in the respective (x, y) value pairs results in a set of four equations having the four variables A, B, C and D:

 ![Bildschirmfoto 2025-01-14 um 06.33.55](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/a/a/aa80065fa738f5dda31e60ad439c9156ecb05fdf.png)

The 1st and 3rd equations give you D = 0 and C = 0, respectively. Which leaves you with a set of two equations dealing in two variables A and B:

 ![Bildschirmfoto 2025-01-14 um 06.39.31](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/9/1/91f14fa2f77bfc7244e66ccf067039bd007f77e9.png)

Solving the 1st for A and inserting into the 2nd:

 ![Bildschirmfoto 2025-01-14 um 06.47.06](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/9/b91a5a34d10d9f4f13079569f4813969d9b807a9.png)

results in B = 3 and A = -2 .

Voilà!
