# SmoothStep: Looking for a continuous family of interpolation functions

Background:

SmoothStep is a simple sigmoid-like function defined as S(x) = 3x^2 - 2x^3. It is monotonically increasing from (0, 0) to (1, 1), is rotationally symmetric over that interval, and has flat tangents at both endpoints. This function is useful for generating an interpolation parameter when you would like to ease in and out between an initial and final value.

S(S(x)) will yield a function that has a longer ease-in/ease-out with a sharper transition in the middle, and S(S(S(x))) makes the middle steeper still. The more times the function is nested, the more protracted the ease is and the steeper the tangent at the midpoint becomes.

Question:

I would like to be able to drive this curve from shallow to steep continuously using some kind of 'steepness' parameter, but repeated iteration only allows discrete curves to be evaluated. Additionally, the cost of evaluating the function grows with the number of nested iterations. Is there any similar function which could be tuned continuously in this manner?

## 3 Answers

If you are willing to go with parametric representation for your curve, then this is pretty easy to achieve with the following:

$\begin{cases}x(t)=(t^3-2t^2+t)m_0+(-2t^3+3t^2)+(t^3-t^2)m_1 \\y(t)=-2t^3+3t^2 \end{cases}$

You can use $m_0$ and $m_1$ to separately control how strong the curve will go out of $(0,0)$ and into $(1,1)$. The following are two sample pictures: first one with $m_0=m_1=1,2,3$ and second one with $m_0=1,2,3$ and $m_1=1$.

The permalinks for generating these pictures are below:

• That does look useful and I like that the ease in and out can be controlled independently. Unfortunately I do still need a mapping from a single variable, which in this case means solving for t in terms of x. It's a cubic, so it should be possible to subtract x from both sides and then find the roots... I'll give it a shot later, no idea how messy it will get though. – Jason Apr 19 '16 at 20:58
• As expected, when you ask wolfram alpha to solve for t in terms of x the closed form is a wall of text. This would require either using a dedicated cubic solver or searching the curve, and both of these options are likely to be too expensive to perform for each curve evaluation. – Jason Apr 21 '16 at 2:23

This graph exposes two parameters which allow the curve to be tuned continuously: https://www.desmos.com/calculator/3zhzwbfrxd

• Can this be modified to add a variable to set the Y position of the fulcrum? – troy_s Feb 13 '17 at 23:14
• Given the symmetry of the construction I'm not sure there is an easy way to make that change. The blue and red graphs are uniformly scaled and rotated copies of each other, which forces the location where they meet to be on the y=x line. While you could scale each non-uniformly, doing so would break the tangent and create a discontinuity at the fulcrum. – Jason Hise Feb 14 '17 at 23:59
• Actually maybe you can... there is already a parameter to control the slope, so you might be able to add an amount that the slopes are split and then undo that split with the scaling. I'll have to look again when I have a bit more time. – Jason Hise Feb 15 '17 at 0:55

How about $S(f_c(x))$ where $f_c(x)=(1-c)x+cS(x)$, $c\ge 0$?

• I just tried plugging that into google, replacing c with y, as: z = 3((1-y)*x + y*(3x^2 - 2x^3))^2 - 2((1-y)*x + y*(3x^2 - 2x^3))^3 It looks like you get nice curves from c = 0 to c = 1, but after that you get additional undesirable folds and begin to hit both 0 and 1 twice, rather than just at the endpoints. – Jason Apr 19 '16 at 7:01
• Looking more closely at your answer, it looks like you are advocating a linear interpolation between S(S(x)) and S(x). I guess it is reasonable to lerp between adjacent curves, so you could use the floor of c to choose the number of nested iterations of S, and the fractional part to control the linear blend. I can implement it this way and it will probably work, but I was hoping to avoid iterating an unbounded number of times as c increases. – Jason Apr 19 '16 at 17:18