GLSL 内置函数
smoothstep()
x 小于 edge0 时返回 0.0,大于 edge1 时返回 1.0,中间是一条平滑的 S 形曲线。
函数签名
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)参数
- edge0
- 过渡开始的位置(结果为 0.0)。
- edge1
- 过渡结束的位置(结果为 1.0),应大于 edge0。
- x
- 要计算的值。
返回值
0.0 到 1.0 之间的值,计算方式为 t * t * (3.0 - 2.0 * t),其中 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)。
在线示例
修改右侧代码,左侧预览会实时更新。
工作原理
smoothstep(edge0, edge1, x) 是柔和版的 step。它不是从 0 突变到 1,而是缓入缓出:
- x 小于等于
edge0:0.0 - x 大于等于
edge1:1.0 - 两者之间:一条平滑的 S 形曲线,两端慢、中间快
它内部先把 x 换算成从 edge0 到 edge1 走了百分之多少(0 到 1),再用 t * t * (3.0 - 2.0 * t) 把这条直线弯成 S 形。
示例画了一个圆,边缘是 smoothstep(0.6 - width, 0.6, d)。width 很小时边缘清晰但没有锯齿;width 很大时,圆就变成一团柔和的光晕。
常见用法
- 抗锯齿图形:
1.0 - smoothstep(r - 0.01, r, d)得到边缘干净的圆。 - 柔和遮罩和暗角:
1.0 - smoothstep(0.2, 0.8, length(p))让四角变暗。 - 动画缓动:
smoothstep(0.0, 1.0, t)让线性的 0 到 1 进度平缓地开始和结束。
常见错误
edge0大于等于edge1。GLSL ES 规范规定这种情况结果未定义。很多 GPU 会返回反向曲线,但想保证兼容,应写1.0 - smoothstep(a, b, x),而不是smoothstep(b, a, x)。- 过渡宽度无意中依赖了分辨率。uv 空间里
0.01的宽度,在 300 像素的画布上约 3 像素,在 1000 像素的画布上就是 10 像素。