Smoothstep is a family of sigmoid-like interpolation and clamping functions commonly used in computer graphics,[1] [2] video game engines,[3] and machine learning.[4]
The function depends on three parameters, the input x, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function receives a real number x as an argument and returns 0 if x is less than or equal to the left edge, 1 if x is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, between 0 and 1 otherwise. The gradient of the smoothstep function is zero at both edges. This is convenient for creating a sequence of transitions using smoothstep to interpolate each segment as an alternative to using more sophisticated or expensive interpolation techniques.
In HLSL and GLSL, smoothstep implements the
\operatorname{S}1(x)
\operatorname{smoothstep}(x)=S1(x)=\begin{cases} 0,&x\le0\\ 3x2-2x3,&0\lex\le1\\ 1,&1\lex\\ \end{cases}
Assuming that the left edge is 0, the right edge is 1, with the transition between edges taking place where 0 ≤ x ≤ 1.
A modified C/C++ example implementation provided by AMD[5] follows.
float clamp(float x, float lowerlimit = 0.0f, float upperlimit = 1.0f) The general form for smoothstep, again assuming the left edge is 0 and right edge is 1, is
\operatorname{S}n(x)=\begin{cases} 0,&ifx\le0\\ xn+1
n | |
\sum | |
k=0 |
\binom{n+k}{k}\binom{2n+1}{n-k}(-x)k,&if0\lex\le1\\ 1,&if1\lex\\ \end{cases}
\operatorname{S}0(x)
\operatorname{S}0(x)=\begin{cases} 0,&ifx\le0\\ x,&if0\lex\le1\\ 1,&if1\lex\\ \end{cases}
The characteristic S-shaped sigmoid curve is obtained with
\operatorname{S}n(x)
Ken Perlin suggested[6] an improved version of the commonly used first-order smoothstep function, equivalent to the second order of its general form. It has zero 1st- and 2nd-order derivatives at x = 0 and x = 1:
\operatorname{smootherstep}(x)=S2(x)=\begin{cases} 0,&x\le0\\ 6x5-15x4+10x3,&0\lex\le1\\ 1,&1\lex\\ \end{cases}
C/C++ reference implementation:
float clamp(float x, float lowerlimit = 0.0f, float upperlimit = 1.0f)
Starting with a generic third-order polynomial function and its first derivative:
\begin{alignat}{9} \operatorname{S}1(x)&& = &&a3x3&& + &&a2x2&& + &&a1x&& + &&a0,&\\ \operatorname{S}1'(x)&& = &&3a3x2&& + &&2a2x&& + &&a1.& \end{alignat}
Applying the desired values for the function at both endpoints:
\begin{alignat}{13} \operatorname{S}1(0)&& = &&0 && ⇒ && 0 &&+&& 0 &&+&& 0 &&+&& a0&& = &&0,&\\ \operatorname{S}1(1)&& = &&1 && ⇒ && a3 &&+&& a2 &&+&& a1 &&+&& a0&& = &&1.& \end{alignat}
Applying the desired values for the first derivative of the function at both endpoints:
\begin{alignat}{11} \operatorname{S}1'(0)&& = &&0 && ⇒ && 0 &&+&& 0 &&+&& a1 &&= &&0,&\\ \operatorname{S}1'(1)&& = &&0 && ⇒ && 3a3 &&+&& 2a2 &&+&& a1 &&= &&0.& \end{alignat}
Solving the system of 4 unknowns formed by the last 4 equations result in the values of the polynomial coefficients:
a0=0, a1=0, a2=3, a3=-2.
This results in the third-order "smoothstep" function:
\operatorname{S}1(x)=-2x3+3x2.
Starting with a generic fifth-order polynomial function, its first derivative and its second derivative:
\begin{alignat}{13} \operatorname{S}2(x)&& = &&a5x5&& + &&a4x4&& + &&a3x3&& + &&a2x2&& + &&a1x&& + &&a0,&\\ \operatorname{S}2'(x)&& = &&5a5x4&& + &&4a4x3&& + &&3a3x2&& + &&2a2x&& + &&a1,&\\ \operatorname{S}2''(x)&& = &&20a5x3&& + &&12a4x2&& + &&6a3x&& + &&2a2.& \end{alignat}
Applying the desired values for the function at both endpoints:
\begin{alignat}{17} \operatorname{S}2(0)&& = &&0 && ⇒ && 0 &&+&& 0 &&+&& 0 &&+&& 0 &&+&& 0 &&+&& a0&& = &&0,&\\ \operatorname{S}2(1)&& = &&1 && ⇒ && a5 &&+&& a4 &&+&& a3 &&+&& a2 &&+&& a1 &&+&& a0&& = &&1.& \end{alignat}
Applying the desired values for the first derivative of the function at both endpoints:
\begin{alignat}{15} \operatorname{S}2'(0)&& = &&0 && ⇒ && 0 &&+&& 0 &&+&& 0 &&+&& 0 &&+&& a1 &&= &&0,&\\ \operatorname{S}2'(1)&& = &&0 && ⇒ && 5a5 &&+&& 4a4 &&+&& 3a3 &&+&& 2a2 &&+&& a1 &&= &&0.& \end{alignat}
Applying the desired values for the second derivative of the function at both endpoints:
\begin{alignat}{15} \operatorname{S}2''(0)&& = &&0 && ⇒ && 0 &&+&& 0 &&+&& 0 &&+&& 2a2 &&= &&0,&\\ \operatorname{S}2''(1)&& = &&0 && ⇒ && 20a5 &&+&& 12a4 &&+&& 6a3 &&+&& 2a2 &&= &&0.& \end{alignat}
Solving the system of 6 unknowns formed by the last 6 equations result in the values of the polynomial coefficients:
a0=0, a1=0, a2=0, a3=10, a4=-15, a5=6.
This results in the fifth-order "smootherstep" function:
\operatorname{S}2(x)=6x5-15x4+10x3.
Applying similar techniques, the 7th-order equation is found to be:
\operatorname{S}3(x)=-20x7+70x6-84x5+35x4.
Smoothstep polynomials are generalized, with 0 ≤ x ≤ 1 as
\begin{align} \operatorname{S}N(x)&=xN+1
N | |
\sum | |
n=0 |
\binom{N+n}{n}\binom{2N+1}{N-n}(-x)n N\inN\\ &=
N | |
\sum | |
n=0 |
(-1)n\binom{N+n}{n}\binom{2N+1}{N-n}xN+n+1\\ &=
N | |
\sum | |
n=0 |
\binom{-N-1}{n}\binom{2N+1}{N-n}xN+n+1,\\ \end{align}
where N determines the order of the resulting polynomial function, which is 2N + 1. The first seven smoothstep polynomials, with 0 ≤ x ≤ 1, are
\begin{align} \operatorname{S}0(x)&=x,\\ \operatorname{S}1(x)&=-2x3+3x2,\\ \operatorname{S}2(x)&=6x5-15x4+10x3,\\ \operatorname{S}3(x)&=-20x7+70x6-84x5+35x4,\\ \operatorname{S}4(x)&=70x9-315x8+540x7-420x6+126x5,\\ \operatorname{S}5(x)&=-252x11+1386x10-3080x9+3465x8-1980x7+462x6,\\ \operatorname{S}6(x)&=924x13-6006x12+16380x11-24024x10+20020x9-9009x8+1716x7.\\ \end{align}
The differential of
\operatorname{S}N(x)
\begin{align} \operatorname{d\overdx}{S}N(x)&=(2N+1)\binom{2N}{N}(x-x2)N.\\ \end{align}
It can be shown that the smoothstep polynomials
\operatorname{S}N(x)
\operatorname{R}N(x)=
1 | |
\left(\int | |
0 |
(1-u2)Ndu\right)-1
x | |
\int | |
0 |
(1-u2)Ndu,
where
\operatorname{S}N(x)=\tfrac12\operatorname{R}N(2x-1)+\tfrac12
\operatorname{R}N(-x)=-\operatorname{R}N(x).
The argument of RN(x) is −1 ≤ x ≤ 1 and is appended to the constant −1 on the left and +1 at the right.
An implementation of
\operatorname{S}N(x)
// Returns binomial coefficient without explicit use of factorials,// which can't be used with negative integersfunction pascalTriangle(a, b)
function clamp(x, lowerlimit, upperlimit)
The inverse of smoothstep can be useful when doing certain operations in computer graphics when its effect needs to be reversed or compensated for. In the case of the 3rd-order equation there exists an analytical solution for the inverse, which is:
\operatorname{InvS}1(x)=1/2-\sin(\operatorname{asin}(1-2x)/3)
This arises as the inverse of
\operatorname{f}(x)=1/2-\sin(3\operatorname{asin}(0.5-x))/2
3x2-2x
3=S | |
1(x) |
\operatorname{f}
\operatorname{S}1
In GLSL: