Smoothstep
Smoothstep is an interpolation function commonly used in computer graphics[1][2] and video game engines.[3]
The function depends on two parameters, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function takes a real number x as input and outputs 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 between 0 and 1 otherwise. The slope of the smoothstep function is zero at both edges. This makes it easy to create a sequence of transitions using smoothstep to interpolate each segment rather than using a more sophisticated or expensive interpolation technique.
As pointed out in MSDN and OpenGL documentation, smoothstep implements cubic Hermite interpolation after doing a clamp:
where we assume that the left edge is 0, the right edge is 1, and 0 ≤ x ≤ 1.
A C/C++ example implementation provided by AMD[4] follows.
float smoothstep(float edge0, float edge1, float x)
{
// Scale, bias and saturate x to 0..1 range
x = clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x*x*(3 - 2*x);
}
Variations
Ken Perlin suggests[5] an improved version of the smoothstep function which has zero 1st and 2nd order derivatives at x=0 and x=1:
C/C++ reference implementation:
float smootherstep(float edge0, float edge1, float x)
{
// Scale, and clamp x to 0..1 range
x = clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x*x*x*(x*(x*6 - 15) + 10);
}
Origin
3rd order equation
We start with a generic third order polynomial function and its first derivative:
Applying the desired values for the function at both endpoints we get:
Applying the desired values for the first derivative of the function at both endpoints we get:
Solving the system of 4 unknowns formed by the last 4 equations we obtain the values of the polynomial coefficients:
Introducing these coefficients back into the first equation gives the third order smoothstep function:
5th order equation
We start with a generic fifth order polynomial function, its first derivative and its second derivative:
Applying the desired values for the function at both endpoints we get:
Applying the desired values for the first derivative of the function at both endpoints we get:
Applying the desired values for the second derivative of the function at both endpoints we get:
Solving the system of 6 unknowns formed by the last 6 equations we obtain the values of the polynomial coefficients:
Introducing these coefficients back into the first equation gives the fifth order smootherstep function:
7th order equation
Also called "smootheststep", the 7th order equation was derived by Kyle McDonald and first posted to Twitter[6] with a derivation on GitHub:[7]
Generalization of higher-order equations
All smoothstep equations can be generalized as:
where a determines the order of the resulting polynomial equation, with the order being calculated as 2a - 1. Evaluating this function for different values of a gives:
For any value a where a > 0, this generalization will smoothly interpolate from 0 to 1 for any value x on the interval 0 ≤ x ≤ 1 while retaining the property Sa(0.5) = 0.5.
References
- ↑ Smoothstep at Microsoft Developer Network
- ↑ GLSL Language Specification, Version 1.40
- ↑ Unity game engine SmoothStep documentation
- ↑ ATI R3x0 Pixel Shaders
- ↑ Texturing and Modeling, Third Edition: A Procedural Approach
- ↑ kcimc (25 March 2015). "smootheststep(t)=-20*t^7+70*t^6-84*t^5+35*t^4 // when smootherstep's second derivative isn't enough" (Tweet) – via Twitter.
- ↑ Kyle McDonald (27 March 2015). "Derivation of 7th-order smoothstep function with zeros in third derivative.". Github.com. Retrieved 20 December 2015.
External links
- Using smoothstep (in the RenderMan Shading Language) by Prof. Malcolm Kesson.
- Interpolation tricks by Jari Komppa
- Swift Interpolation Playground demonstrates smoothStep(), smootherStep() and smoothestStep() in a Swift playground by Simon Gladman