shader 案例学习笔记之smoothstep函数

参考:smoothstep

用来生成0-1的平滑过渡值

smoothstep函数源码实现: 

float smoothstep(float t1, float t2, float x) {
  // Scale, bias and saturate x to 0..1 range
  x = clamp((x - t1) / (t2 - t1), 0.0, 1.0); 
  // Evaluate polynomial
  return x * x * (3 - 2 * x);
}

先理解clamp函数:

用于将一个值限制在给定的范围之内。其语法为clamp(x, minVal, maxVal),它接受三个参数:

  • x:要被限制的值。
  • minVal:范围的最小值。
  • maxVal:范围的最大值。
#ifdef GL_ES
precision mediump float;
#endif

uniform 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;
#endif

uniform 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;
#endif

uniform 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越大,影响越大

SmoothStep函数是一个用于生成平滑过渡的函数。它接受三个参数:t1,t2和x。首先,x的值会被标准化到0到1的范围内,公式为(x-t1)/(t2-t1)。然后,这个标准化后的值会通过一个三次多项式函数进行平滑处理,公式为x*x*(3-2*x)。最后,函数返回处理后的值。 SmoothStep函数的作用是在给定的范围内生成平滑的过渡效果。当x的值在t1和t2之间时,函数的返回值会在0到1之间变化。当x小于t1时,返回值为0;当x大于t2时,返回值为1。在t1和t2之间的过渡区域内,返回值会平滑地从0过渡到1。 SmoothStep函数可以用于各种应用,比如在图形渲染中实现平滑的颜色过渡效果,或者在动画中实现平滑的运动效果。 引用\[1\]中给出了SmoothStep函数的具体实现代码,而引用\[2\]中提到了一个类似于SmoothStep函数的公式,它也可以用于生成平滑过渡效果。这个公式是saturate((x-0.5)/max(0.001,a)+0.5),它将x的值在某一范围内进行缩放,并将结果限定在0到1之间。 总结来说,SmoothStep函数是一个用于生成平滑过渡效果的函数,它可以通过调整参数t1和t2来控制过渡的范围,而函数的返回值会在0到1之间平滑地变化。 #### 引用[.reference_title] - *1* [【Shader Graph】SmoothStep节点详解及其应用](https://blog.csdn.net/weixin_61427881/article/details/127839417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Unity Shader中常用函数及其几何意义--持续更新ing](https://blog.csdn.net/u010778229/article/details/107285163)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superTiger_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值