GLSL built-in function
smoothstep()
Returns 0.0 below edge0, 1.0 above edge1, and a smooth S-shaped curve in between.
Demo version: GLSL ES 1.00 / WebGL 1Demo stage: Fragment
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.