参考:smoothstep
用来生成0-1的平滑过渡值
smoothstep函数源码实现:
float smoothstep(float t1, float t2, float x) {// Scale, bias and saturate x to 0..1 rangex = clamp((x - t1) / (t2 - t1), 0.0, 1.0); // Evaluate polynomialreturn x * x * (3 - 2 * x);
}
先理解clamp函数:
用于将一个值限制在给定的范围之内。其语法为clamp(x, minVal, maxVal)
,它接受三个参数:
x
:要被限制的值。minVal
:范围的最小值。maxVal
:范围的最大值。
#ifdef GL_ES
precision mediump float;
#endifuniform vec2 u_resolution;
uniform float u_time;void main(){vec2 st = gl_FragCoord.xy/u_resolution.xy;st.x *= u_resolution.x/u_resolution.y;float maxValue = abs(sin(u_time)) * 0.5;float f = clamp(st.y, 0.0, maxValue);gl_FragColor = vec4(f,f,f, 1.0);
}
- float maxValue = abs(sin(u_time));
- sin(u_time)返回[-1,1]的值,abs(sin(u_time)) 取绝对值将该值限制在了[0,1],再乘以0.5返回[0,0.5]
-
float f = clamp(st.y, 0.0, maxValue);
-
maxValue的区间为[0,0.5]
-
clamp(st.y, 0.0, maxValue)将屏幕的Y值限制在[0,0.5]之间
-
-
x = clamp((x - t1) / (t2 - t1), 0.0, 1.0);
- x的值被限制在0-1之间。
绘制圆环:
#ifdef GL_ES
precision mediump float;
#endifuniform vec2 u_resolution;void main(){vec2 st = gl_FragCoord.xy/u_resolution.xy;st -=0.5;st.x *= u_resolution.x/u_resolution.y;float r = length(st);float r1 = smoothstep(0.2,0.3 ,r );float r2 = smoothstep(0.3,0.4 ,r );float color = r1- r2;gl_FragColor = vec4(vec3(color),1.0);
}
r1-r2的函数图像
绘制结果
另一种实践
#ifdef GL_ES
precision mediump float;
#endifuniform vec2 u_resolution;float plot(vec2 st,float pct ){return smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y);
}void main(){vec2 st = gl_FragCoord.xy/u_resolution;float y = step(0.5,st.x);vec3 color = vec3(y);float pct = plot(st,y);color = (1.0-pct) * color + pct * vec3(0.0,1.0,0.0);gl_FragColor = vec4(color,1.0);}
绘制结果
代码解析:
- vec2 st = gl_FragCoord.xy/u_resolution;
- 坐标归一化,将屏幕坐标映射到[0,1]
-
float y = step(0.5,st.x);
-
step函数。根据st的x分量,当x大于等于0.5时,返回1.0,否则返回0.
-
所以y的值只有两种:0或者1
-
-
vec3 color = vec3(y); 以y的值构建三维向量,那么color也只有两个情况:(1.0,1.0,1.0)或者(0.0,0.0,0,0)
-
当st.x分量值小于0.5对应颜色为(0.0,0.0,0,0)
-
当st.x分量值大于等于0.5对应颜色为(1.0,1.0,1.0)
-
所以屏幕以0.5为分界线左侧是黑色,右侧为白色
-
-
float pct = plot(st,y);
- float plot(vec2 st,float pct ){
-
return smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y);
}
-
调用函数plot,plot接收两个参数,一个是二维向量st,另一个是浮点数pct。根据输入的参数计算并返回一个浮点数结果
-
分析函数图像:
-
-
那么可以得出结论,当st.y接近pct(0或者1时),返回1.所以能看到st.y=0和st.y=1时,图像会高亮
-
color = (1.0-pct) * color + pct * vec3(0.0,1.0,0.0);
-
pct * vec3(0.0,1.0,0.0) 是将原来的白色变成了绿色
-
(1.0-pct) * color 通过pct的值来影响原来的颜色,pct越大,影响越大
-