之前在学习HLSL常用函数时就有涉及到范围相关的函数,但是最近做的东西发现step,lerp和smoothstep这三个函数总是一直在用,总是会在用的时候突然忘记他们分别是干啥的,这里就记录一下方便查看吧,形式大部分参考Unity Shader 极简实践3——step,lerp 和 smoothstep 应用
1 step
// x <a,返回0
// x>=0,返回1
step(a,x);
通常用来代替if else。
shader中的表现
要么是0要么是1,非此即彼的感觉,所以如果写进shader中与颜色挂钩,表现出的颜色变化效果很“硬”,颜色变化突兀,没有过渡感。
fixed4 frag (v2f i) : SV_Target
{
// step
fixed4 col = step(_Amount, length(i.uv - 0.5)) * _Color;
return col;
}
ENDCG
2 lerp
// w是一个百分比,表示从a到b之间按照w来取值
// w = 0,返回a
// w = 1,返回b
lerp(a, b, w);
例如lerp(0, 100, 0.2),返回20
shader中的表现
// lerp
fixed4 col = lerp(0, 1, length(i.uv - 0.5)) * _Color;
return col;
与step相比,lerp是有个过渡的。代码中的i.uv - 0.5表示的是着色点与中心的距离,也就是从中心向外出发,距离越远这个百分比越大,意味着lerp的结果越接近1,从而实现了颜色从中心向外由黑色--> _Color(白色)的效果。
3 smoothstep
这是稍微复杂一点的范围函数,用来生成0到1的平滑过渡值,如下:如果x在[a,b]范围内,则返回介于0和1之间的平滑插值,使用smoothstep在两个值之间创建平滑过渡。
smoothstep(a, b, x);
这是之前我在HLSL函数那篇文章展示的一个函数图,最下面两条就是smoothstep()
如果两个smoothstep作减法还会有一些波形图效果。
shader中的表现
fixed4 singleSmoothStep(float _Start, float _End, v2f i) {
return smoothstep(_Start, _End, length(i.uv - 0.5));
}
fixed4 doubleSmoothStep(float _Start, float _End, float _Inner, float _Outer, v2f i) {
float res = smoothstep(_Start, _Inner, length(i.uv - 0.5));
float res2 = smoothstep(_Outer, _End, length(i.uv - 0.5));
return res - res2;
}
fixed4 frag (v2f i) : SV_Target
{
// step
//fixed4 col = step(_Amount, length(i.uv - 0.5)) * _Color;
// lerp
//fixed4 col = lerp(0, 1, length(i.uv - 0.5)) * _Color;
// smoothstep
//fixed4 col = singleSmoothStep(_End, _Start, i) * _Color;
fixed4 col = doubleSmoothStep(_Start, _End, _Inner, _Outer, i) * _Color;
return col;
}
波形图和shader中的着色效果一起来看:
singleSmoothStep(0.1,0.35, i)
singleSmoothStep(0.35,0.1, i)
doubleSmoothStep(0.1, 0.5, 0.2, 0.3, i)