找回密码
 立即注册
查看: 278|回复: 0

【unity Shader 菜鸡教程】3-2 常用内置函数

[复制链接]
发表于 2022-9-16 19:42 | 显示全部楼层 |阅读模式
unity中内置了许多的功能函数来方便开发时的使用,这里列举一些常用的函数。
函数使用
abs(x)取绝对值
frac(x)取小数部分
floor(x)向下取整
ceil(x)向上取整
max(a,b)比较两个标量或等长向量元素,返回最大值
min (a,b)比较两个标量或等长向量元素,返回最小值
pow(a,b)返回x的y次方  即 x^y
rap(x)返回x的倒数,相当于 1/x  即 x^-1
exp(x)计算e^x 的值,e=2.71828182845904523536
exp2(x)计算 2^x 的值
fmod (x,y)返回x/y的余数。如果y为0,结果不可预料
saturate(x)把x限制到[0,1]之间
clamp(x,a,b)如果x值小于a,则返回a;如果x值大于b,返回b;否则,返回x。
sqrt (x)求x的平方根,,x必须大于0
rsqrt (x)x的平方根的倒数,x必须大于0
lerp(a, b, f)在下限a和上限b之间进行插值,f表示权值。注意,如果a和b是向量,则权值f必须是标量或者等长的向量。
sin(x)输入参数为弧度,计算正弦值,返回值范围 为[-1,1]
cos(x)返回弧度x的余弦值。返回值范围为[-1,1]
distance(a,b)返回a,b  两点间的距离.
length(v)返回一个向量的模,即sqrt(dot(v,v))
step (a,b)如果a<=b返回1,否则返回0,常用来替换 判断语句
smoothstep (min,max,x)如果 x 比min 小,返回 0;如果 x 比max 大,返回 1;如果 x 处于范围 [min,max]中,则返回 0 和 1 之间的值(按值在min和max间的比例);如果只想要线性过渡,并不需要平滑的话,可以直接使用saturate((x - min)/(max - min))
参考:UnityShader常用函数(UnityShader内置函数、CG和GLSL内置函数等)_LST329的博客-CSDN博客_unityshader函数
函数很多,不用根本记不住,没事也不会去背这个东西。理解和熟悉使用,才可能记得,反正不记得的时候都是上网搜的。
这里补充一个内置的参数 _Time,表示时间。
// Time (t = time since current level load) values from Unity
float4 _Time; // (t/20, t, t*2, t*3)这是一个float4类型的参数,t 表示从游戏启动到当前的时间。
简单讲一下uv
float2 uv : TEXCOORD0;
......
o.uv = TRANSFORM_TEX(v.uv, _MainTex);uv 指的是模型贴图的uv值,u是横轴,v是纵轴。


如果是一个正方形,那获取它的uv时,左下角是(0,0),右上角是(1,1)


举一些例子,来使用这些函数。
1、ceil 的使用
return ceil(i.uv.x *5)/5;

单纯只是看代码,大概是想不出结果是怎样的。可以借助一些数学图形工具,来显示。比如 GeoGebra。



2、distance/step 的使用,画一个圆
fixed4 frag (v2f i) : SV_Target
{
      fixed2 p = fixed2(0.5,0.5);
      fixed circular = distance(i.uv,p);
      return step(circular,0.4) * _Color;
}


图1                                                   图2

取一个中心点 fixed2(0.5,0.5),用distance(i.uv,p),算出每个uv点到中心点的位置,得到图1。然后使用setp,当两点间的距离小于0.4时,返回1,就得到想要的效果。
单画圆好像很鸡肋,如果这是一个点,很多点连起来就会变成线,线就会变成图,当点比较小,足够多的时候,似乎可以用来画画,然后颜色也可以自己定义,脑海顿时想到了你画我猜,应该可以通过这样的方式处理。

3、sin/_Time 的使用,绘制波浪


sin正弦函数,在表现上是一个波浪,通过修改a 值来修改波浪频率(振频),修改b 值来修改振幅。
那么,如果在这里添加一个时间变化,应该会得到一个波浪的效果
fixed4 frag (v2f i) : SV_Target
{
        fixed s = i.uv.y + sin((i.uv.x + _Time.y) * _Frequency) * _Amplitude;
        fixed val = step(s,_Height);
        return val * _Color;
}

// 先看简单的内部  sin 内 uv.x + _Time..y  随着时间的变化,水平方向上会发生变化
sin(i.uv.x + _Time.y)
//接着乘以 _Frequency  修改波动的频率  
sin((i.uv.x + _Time.y) * _Frequency)

这个时候发现只有水平的移动变化,那在竖直方向上也需要修改
// 把 uv.y  纵向添加进来,就会发现有波浪的上下起伏效果
fixed s = i.uv.y + sin((i.uv.x + _Time.y) * _Frequency) * _Amplitude;
暂时想到这点例子,后续想到再补充下。
到这里其实可以发现,虽然讲的东西好像不多,但是实际上算是可以写一些小东西了,虽然没什么用。效果这些东西,算是要时间积累才能做出好的效果,不然也不知道什么东西能拼凑出来。这些简单的小知识,在自己实践操作和瞎折腾的结合下,说不定都会有新的发现和想法。
具体代码提交到了gitee上:LZJian/UnityShaderCourse

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-7-2 08:40 , Processed in 0.113944 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表