SmoothStep
该函数用于求解两个值之间的样条插值。
函数用法
float smoothstep(float edge0, float edge1, float x)
vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x)
vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x)
vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x)
vec2 smoothstep(float edge0, float edge1, vec2 x)
vec3 smoothstep(float edge0, float edge1, vec3 x)
vec4 smoothstep(float edge0, float edge1, vec4 x)
解析
函数接受的输入有三个。其中:
edge0 代表样条插值函数的下界;
edge1 代表样条插值函数的上界;
x 代表用于插值的源输入。
该函数的输出值是界于0到1之间的数。一般情况下,如果我们想要创建一个能够输出平滑过渡的阈值函数,smoothstep就是很好的选择。
背后计算介绍
smoothstep函数的背后计算等同于如下计算:
genType t;
t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return (3.0 - 2.0 * t) * t * t;
即先按照给定的上界和下界对给定的源输入进行归一化,使输出值在0到1之间。之后将该值运用到样条插值函数中。这里选用的插值函数为 (3.0 - 2.0 * t) * t * t。
当edge0=0, edge1=1时,横轴为源输入,纵轴为输出(y = smoothstep(0.000, 1.0, x);。则如下图:
我们用shader脚本将线条画出来看一下(片段着色器):
varying vec2 v_texCoord;
const float line_width = 3.0; // 线宽
vec3 line_color = vec3(1.0, 0.4, 0.0); // 线的颜色
vec3 background_color = vec3(0.0); // 背景的颜色
void main()
{
float delta = line_width * 0.001;
float x = v_texCoord.x;
float y = 1.0 - v_texCoord.y;
float line_y = smoothstep(0.0, 1.0, x);
if (abs(y - line_y) <= delta){
gl_FragColor = vec4(line_color, 1.0);
}
else{
gl_FragColor = vec4(background_color, 1.0);
}
}
结果如下图: