GLSL built-in function
smoothstep()
Returns 0.0 below edge0, 1.0 above edge1, and a smooth S-shaped curve in between.
Syntax
float smoothstep(float edge0, float edge1, float x)
vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x)
vec2 smoothstep(float edge0, float edge1, vec2 x)
vec3 smoothstep(float edge0, float edge1, vec3 x)Parameters
- edge0
- Where the transition starts (result 0.0).
- edge1
- Where the transition ends (result 1.0). Should be greater than edge0.
- x
- The value to evaluate.
Return value
A value between 0.0 and 1.0, computed as t * t * (3.0 - 2.0 * t) with t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0).
Live example
Edit the code and the preview updates as you type.
How it works
smoothstep(edge0, edge1, x) is a soft version of step. Instead of jumping from 0 to 1, it eases in and out:
- x at or below
edge0:0.0 - x at or above
edge1:1.0 - in between: a smooth S-curve, slow at both ends and fastest in the middle
Inside, it first converts x to a 0..1 percentage of the way from edge0 to edge1, then bends that line with t * t * (3.0 - 2.0 * t).
The example draws a circle whose edge is smoothstep(0.6 - width, 0.6, d). When width is tiny the edge is crisp but not jagged; when it is large the circle becomes a soft glow.
Typical uses
- Anti-aliased shapes:
1.0 - smoothstep(r - 0.01, r, d)gives a circle with a clean edge. - Soft masks and vignettes:
1.0 - smoothstep(0.2, 0.8, length(p))darkens the corners. - Easing animations:
smoothstep(0.0, 1.0, t)makes a linear 0..1 progress start and stop gently.
Common mistakes
- Setting
edge0greater than or equal toedge1. The GLSL ES spec says the result is undefined in that case. Many GPUs still return a reversed curve, but for portable code write1.0 - smoothstep(a, b, x)instead ofsmoothstep(b, a, x). - Making the transition width depend on resolution by accident. A width of
0.01in uv space is about 3 pixels on a 300 px canvas but 10 pixels on a 1000 px one.
Related functions
step()
Returns 0.0 if x is less than edge, otherwise 1.0. A hard on/off switch at a threshold.
fwidth()
Returns how much a value changes between neighboring pixels. Using it as the smoothstep width gives edges exactly one pixel soft at any zoom level.
mix()
Linearly interpolates between x and y: returns x when a is 0.0, y when a is 1.0, and a blend in between.
Tutorials that use smoothstep()
- Smooth BandCreate a soft horizontal band using smoothstep().
- Circle OutlineDraw a ring by using abs(distance - radius) and smoothstep().
- Vignette (Edge Darkening)Use distance to center and smoothstep() to darken edges.
- Aspect-Ratio Corrected UVLearn to correct UV aspect ratio with u_resolution so circles stay round on non-square canvases.
- SDF RingDraw a ring using a distance field: abs(length(p) - r) and smoothstep for smooth edges.
- Smooth EdgesLearn to create smooth edge transition effects using the smoothstep function, contrasting with the hard edges of the step function.