Unity Shader中常用函数及其几何意义--持续更新ing

常用函数--打死都记不住的小知识点的兄弟篇

函数汇总

这里提供所有涉及到的函数,详解在下面。。

函数名备注
dot(A,B)AB为向量,求B在A方向上的投影长度,返回float。
saturate(x)if (x<=0) return 0;else if(x>=1) return 1;else return x;将x限定在[0,1]
smoothstep(a,b,x)生成0-1的平滑过渡,abx为float类型
pow(x,a)范围x的a次幂
radio(x,a)自创函数,saturate((x-0.5)/max(0.001,a)+0.5)
step(a, x)如果 x<a ,返回 0 ;否则,返回 1 。
fmod(x,y)返回 x/y 的余数。如果 y 为 0 ,结果不可预料。
floor(x)对输入参数向下取整。例如 floor(float(1.5)) 返回的值为 1.0 ;但是 floor(float(-1.5)) 返回的值为 -2.0
ceil(x)对输入参数向上取整。例如: ceil(float(1.5)) ,其返回值为 2.0
clip(x)如果x<0,裁剪改片元。注意x可以是float,float2,float3,float4类型

smoothstep

代码:

float smoothstep(float a, float b, float x)
{
   //saturate限定t在[0,1]中。
    float t = saturate((x - a)/(b - a));
    return t*t*(3.0 - (2.0*t));
}
返回值条件
0x < a < b 或 x > a > b
1x < b < a 或 x > b > a
[0,1]间数值根据x在域 [a, b] (或者[b, a])中的位置, 返回某个在 [0, 1] 内的值

那么这个东西用来干嘛呢?参数a,b怎么去界定呢?
我们来看下这个函数的图,当a=0.3.b=1.5时,(b>a时):
在这里插入图片描述
a=0.1.b=0.4时:
在这里插入图片描述
当a>b时,a=0.7,b=0.1:
在这里插入图片描述
由此可见,当a<b时,是一个x在[a,b]区间内的递增函数,a>b时,是一个x在[a,b]区间内的递减函数。此函数即完成由a到b的转换,同时在转换区间内有平滑处理。比如我们再计算阴影时,通过法线和灯光方向的夹角判读该片元是否在灯光内,夹角大于90度,认为是阴影,小于90则不是。这样处理,理论是没问题的,可是由于精度以及分辨率还有光栅化的问题,显示到屏幕上的时候就会出现锯齿,此时如果给一个过渡,则会缓解这种情况。

pow(x,a)

指数曲线,上学的时候应该有讲过,不过老了记性就不好,就只记得三角函数,二元一次基本曲线了。

1.当0<a<1时,x>0的部分曲线,如果a化为分数的分母为偶数分子为基数,则x<0部分有数值,如果为基数则没有有效值,假设a=0.1,此时我们求一个负数的十分之一次方,就是给这个负数开偶数次方,当然是无效的。所以我们再使用时需要特别注意。
在这里插入图片描述
2.a>1时,从曲线可以看出与a<1时的增长率不同。
在这里插入图片描述
3.a<0时,看一下变化情况即可。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以啊~这个函数我们使用的时候要额外注意,可能一个不小心就会造成开n次方,造成极大的计算。同时暴露给美术调控的参数,也应该限定范围。

radio(x,a)

saturate((x-0.5)/max(0.001,a)+0.5),这个公式其实和smoothsetp有点类似,是将x的某一范围的值进行了一次系数比例为a的缩放锁定,同时将结果限定在[0,1]之间。
在这里插入图片描述
从图中可以看出,当0<k<1时,在[0,1]区间对应的y的取值范围,我们把y数值限定在[0.1]时发现,只有当x[0.45,0.55]时,y值对应的为[0,1]。所以某种意义上和smoothstep是不是很相似呢,只不过在过度区域的变化率不同。
我们看当k>1时:
在这里插入图片描述
从图中可以看出,当k越来越大,y值就逐渐趋近为0.5。所以我们可以看出,随着k从0到正无穷变化的过程中,其实是x=0.5,到y=0.5变化的过程。

fmod(x,y)

获取x/y的余数。为什么frac(abs(a/b))abs(b)这个可以求余,a/b结果可以写生y=nb+(一个小于b的数),那么这个小于b的设定位x,那么0<=abs(x)<1,也就是a/b的小数部分,乘以b就是余数了。好像是小学数学的知识点吧,我居然一开始没反应过来。。。。

float2 fmod(float2 a, float2 b)
{
  float2 c = frac(abs(a/b))*abs(b);
  return (a < 0) ? -c : c;   /* if ( a < 0 ) c = 0-c */
}

frac

floor是向下取整,所以frac就是获取小数部分

float frac(float v)
{
  return v - floor(v);
}

clip(x)

这里注意坑,如果x是float2,3,4类型的,只有任意分量小于0都会被裁剪掉的,比如clip(0.5-float(0,1,0))这个片元,需要注意的是0.5-float(0,1,0)返回值是float还是float3类型,结果是float3类型的,所以也会被裁剪掉。

void clip(float4 x)
{
  if (any(x < 0))
    discard;
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘培玉--大王

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

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

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

打赏作者

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

抵扣说明:

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

余额充值