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

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

  • 函数汇总
    • smoothstep
    • pow(x,a)
    • radio(x,a)
    • fmod(x,y)
    • frac
    • clip(x)

函数汇总

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

函数名 备注
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
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));
}
返回值 条件
0 x < a < b 或 x > a > b
1 x < b < a 或 x > b > a
[0,1]间数值 根据x在域 [a, b] (或者[b, a])中的位置, 返回某个在 [0, 1] 内的值

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

pow(x,a)

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

1.当00的部分曲线,如果a化为分数的分母为偶数分子为基数,则x<0部分有数值,如果为基数则没有有效值,假设a=0.1,此时我们求一个负数的十分之一次方,就是给这个负数开偶数次方,当然是无效的。所以我们再使用时需要特别注意。
Unity Shader中常用函数及其几何意义--持续更新ing_第4张图片
2.a>1时,从曲线可以看出与a<1时的增长率不同。
Unity Shader中常用函数及其几何意义--持续更新ing_第5张图片
3.a<0时,看一下变化情况即可。
Unity Shader中常用函数及其几何意义--持续更新ing_第6张图片
Unity Shader中常用函数及其几何意义--持续更新ing_第7张图片
Unity Shader中常用函数及其几何意义--持续更新ing_第8张图片
所以啊~这个函数我们使用的时候要额外注意,可能一个不小心就会造成开n次方,造成极大的计算。同时暴露给美术调控的参数,也应该限定范围。

radio(x,a)

saturate((x-0.5)/max(0.001,a)+0.5),这个公式其实和smoothsetp有点类似,是将x的某一范围的值进行了一次系数比例为a的缩放锁定,同时将结果限定在[0,1]之间。
Unity Shader中常用函数及其几何意义--持续更新ing_第9张图片
从图中可以看出,当0 我们看当k>1时:
Unity Shader中常用函数及其几何意义--持续更新ing_第10张图片
从图中可以看出,当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;
}

你可能感兴趣的:(Unity-日常)