GLSL Learning

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 edge0 greater than or equal to edge1. The GLSL ES spec says the result is undefined in that case. Many GPUs still return a reversed curve, but for portable code write 1.0 - smoothstep(a, b, x) instead of smoothstep(b, a, x).
  • Making the transition width depend on resolution by accident. A width of 0.01 in uv space is about 3 pixels on a 300 px canvas but 10 pixels on a 1000 px one.

Related functions

Tutorials that use smoothstep()