图形 2.3 常用函数介绍

常用函数介绍


基本数学运算

 

max(a,b) 返回最大的数
min(a,b) 返回最小的数
mul(a,b) 两变量相乘,常用于矩阵计算
abs(a,b) 返回x的绝对值
round(x) 返回与x最近的整数(四舍五入)
sqrt(x) 返回x的平方根
rsqrt(x) 返回x的平方根的倒数
degrees(x) 将弧度转换成角度
redians(x) 将角度转换成弧度
noise(x) 噪声函数

 

 

 

 

 

 

 

 

 

 

 

 


 

幂指对函数

 

pow(x,y) 返回x的y次幂
exp(x) 返回以e为底的指数函数
exp2(x) 返回以2为底的指数函数
ldexp(x,y) 返回x与2的y次方的乘积
log(x) 返回x以e为底的对数
log10(x) 返回x以10为底的对数
log2(x) 返回x以2为底的对数

frexp(x,out exp)

把浮点数x分解为尾数和指数x = ret * 2 ^exp的形式,返回尾数,并把指数传到exp中,如果x是0,两个返回值都是0

 

 

 

 

 

 

 

 

 

 

 


 

三角函数与双曲函数

 

sin(x),cos(x),tan(x) 返回正弦值、余弦值、正切值
sincos(x,out s,out c) 返回x的正弦值和余弦值
tan(y,x) 返回y/x的正切值
asin(x) 返回x的反正弦值
acos(x) 返回x的反余弦值
atan(x) 返回x的反正切值
atan2(y,x) 返回y/x的反正切值
sinh(x) 返回x的双曲正弦值
(e^x - e^-x)/ 2
cosh(x) 返回x的双曲余弦值
(e^x + e^-x)/ 2
tanh(x) 返回x的双曲正弦值

(e^x - e^-x)/ (e^x + e^-x)

以上传进去的x值均为弧度值,即rad。1rad = 180°/PI

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

关于双曲函数:知乎链接-可能是最好的讲解双曲函数的文章


 

数据范围类

 

ceil(x) 返回大于x的最小整数,向上取整
floor(x) 返回小于x的最小整数,向下取整
step(x,y) 若y大于x返回1,否则返回0
saturate(x) 返回将x钳制到0-1之间的值
clamp(x,min,max) 把x限制在[min,max]范围内,小于返回min,大于返回max
fmod(x,y) 返回x对y取余的余数
frac(x) 返回x的小数部分
modf(x,out ip)

将值x分为小数和整数部分,整数部分传到ip,函数返回小数部分。

lerp(x,y,s) 常用插值函数,按照s在x到y之间插值,s在0-1之间
smoothstep(min,max,x) 如果x在[min,max]范围内,则返回介于0 - 1之间的平滑Hermite插值。这个差值不是线性的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

类型判断类

 

all(x) x的所有分量均为非零则返回true,反之则返回false(浮点型,整型,布尔型数据定义的标量,向量或者是矩阵)。
clip(x) 如果输入值小于零,则丢弃当前像素,可以代替AlphaTest
sign(x) x小于0返回-1,等于0返回0,大于0返回1
isinf(x) x为INF值返回true,否则返回false(无论正负)
isfinite(x) x为INF值返回false,否则返回true(无论正负)
isnan(x) x为非数字返回true,否则返回false

 

 

 

 

 

 

 

 

 


 

向量与矩阵类

 

关于这个Vector类型,我不知道从哪看到的说法,说是没有必要再用额外的一个类型去区分点,因为点和向量的计算大部分都是相通的,只是所代表的意义不一样。Vector这个类型既可以是点,也可以是向量,隐约好像记得是庄懂的课。

length(v) 返回向量的模
normalize(v) 向量归一化
distance(a,b) 返回两个点的距离
dot(a,b) 返回两个向量的点积
cross(a,b) 返回两个向量的叉积
determinant(m) 返回矩阵m用行列式方式计算的值
transpose(m) 返回矩阵m的转置矩阵

 

 

 

 

 

 

 

 


 

光线运算类

 

reflect(i,n) 返回以i为入射向量n为法线方向的反射光
refract(i,n,ri) 返回以i为入射向量n为法线向量,ri为折射率的折射光
lit(n_dot_l,n_dot_h,m) 输入标量normal与light的点积,normal与半角向量h的点积,镜面反射系数m,返回一个光照向量float4(环境光,漫反射光,镜面高光反射,1)
faceforward(n,i,ng) 得到面向视图方向的曲面法向量输入输出为同元向量,返回-n*sign(dot(i,ng))(normal,light,normal)

 

 

 

 

 

 

 

 

 


 

1D纹理查找

 

罕见。

tex1D(s,t)
普通一维纹理查找 返回纹理采样器s在标量t位置的color4
tex1D(s,t,ddx,ddy)
使用微分查询一维纹理 t和ddxy均为vector
tex1Dlod(s,t)
使用LOD查找纹理s在t.w位置的color4
tex1Dbias(s,t)
将t.w决定的某个MIP层偏置后的一维纹理查找
tex1Dgrad(s,t,ddx,ddy)
使用微分并指定MIP层的一维纹理查找 
tex1Dproj(s,t)
把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术需要计算出投影纹理坐标t(坐标t.w除以透视值),然后使用投影纹理坐标进行查询

 

 

 

 

 

 

 

 

 

 

 


 

2D纹理查找

 

常用,倒不如说几乎很少有不用到的场合。

tex2D(s,t)
普通二维纹理查找,返回纹理采样器s在vector t位置的颜色
tex2D(s,t,ddx,ddy)
使用微分查询二维纹理,t和ddxy均为vector
tex2Dlod(s,t)
使用LOD查找纹理s在t.w位置的color4
tex2Dbias(s,t)
将t.w决定的某个MIP层偏置后的二维纹理查找
tex2Dgrad(s,t,ddx,ddy)
使用微分并指定MIP层的二维纹理查找
tex2Dproj(s,t)
把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术需要计算出投影纹理坐标t(坐标t.w除以透视值),然后使用投影纹理坐标进行查询

 

 

 

 

 

 

 

 

 

 

 


 

3D纹理查找

 

纹理查找大多都相差不大

tex3D(s,t)
普通三维纹理查找 返回纹理采样器s在vector t位置的颜色
tex3D(s,t,ddx,ddy)
使用微分查询三维纹理 tddxy均为vector
tex3Dlod(s,t)
使用LOD查找纹理s在t.w位置的color4
tex3Dbias(s,t)
将t.w决定的某个MIP层偏置后的三维纹理查找
tex3Dgrad(s,t)
使用微分并指定MIP层的三维纹理查找 
tex3Dproj(s,t)
把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术需要计算出投影纹理坐标t(坐标t.w除以透视值),然后使用投影纹理坐标进行查询

 

 

 

 

 

 

 

 

 

 


 

立方纹理查找

 

texCUBE(s,t)
返回纹理采样器s在vector t位置的颜色
texCUBE(s,t,ddx,ddy)
使用微分查询立方体维纹理 tddxy均为vector
texCUBEDload(s,t)
使用LOD查找纹理s在t.w位置的color4
texCUBEbias(s,t)
将t.w决定的某个MIP层偏置后的立方体纹理查找
texCUBEgrad(s,t,ddx,ddy)
使用微分并指定MIP层的立方体纹理查找
texCUBEproj(s,t)
使用投影方式的立方体纹理查找

 

 

 

 

 

 

 

 

 

 


 

扩展作业

 

——写出你觉得最常用的5个函数

 三件套,mul,dot,normalize

tex2D肯定少不了

剩下的我觉得都差不多,max可能稍微高点。

 

——ddx ddy的实际使用测试

模糊

预先绘制一张模糊位置的遮罩图 RGB分别代表不同的模糊遮罩

 

  然后调整出不同的模糊效果。最开始只有远处的楼房是模糊化的,之后两侧的楼房也变得模糊,最后只剩下神社鸟居和地面反光等部分没有被模糊化,可以用这种方法来强调画面主体。值得注意的并不一定要按远近关系进行模糊,事实上距离画面近的一些部分也被模糊化了,模糊遮罩根据自己的想法来绘制,不一定非要去模拟远近效果。

 

shader的面板很简单,两张贴图,模糊系数的乘算因子,以及模糊插值。

这里粗略的把[0, 0.5]这段区间来对遮罩图中红色部分进行模糊,[0.5, 0.75]则开始对蓝色部分进行模糊,[0.75,1]则对绿色部分进行模糊,这三段区间均被映射到[0,1]这个区间上,这意味着蓝色和绿色部分对模糊插值会更加敏感。

 

重要代码部分

Properties
{
        _MainTex ("Texture", 2D) = "white" {}

        _MaskTex("模糊遮罩", 2D) = "white" {}
        //这个范围不宜设置过大 否则得不到比较好的效果
        _ddxPower("ddx(横向模糊)", Range(-0.02,0.02)) = 0
        _ddyPower("ddy(纵向模糊)", Range(-0.02,0.02)) = 0

        _MaskPower("模糊插值", Range(0,1)) = 0
}

fixed4 frag (v2f i) : SV_Target
{
        //模糊部分
        fixed4 mask = tex2D(_MaskTex, i.uv); 

        float maskPower1 = mask.r *_MaskPower;
        float maskPower2 = mask.g * max(0, (_MaskPower - 0.5)) / 0.5;
        float maskPower3 = mask.b * max(0, (_MaskPower - 0.75)) / 0.25;

        float ddx_R = maskPower1 * _ddxPower;
        float ddx_G = maskPower2 * _ddxPower;
        float ddx_B = maskPower3 * _ddxPower;
        float ddx = ddx_R + ddx_G + ddx_B;

        float ddy_R = maskPower1 * _ddyPower;
        float ddy_G = maskPower2 * _ddyPower;
        float ddy_B = maskPower3 * _ddyPower;
        float ddy = ddy_R + ddy_G + ddy_B;

        fixed4 col = tex2D(_MainTex, i.uv, ddx, ddy);

        return col;
}

 

锐化

 

随便找了个Cube套上了贴图,然后对其进行锐化,锐化后的Cube看起来“战痕累累”

 

面板没有太多的变换,也去掉了Mask贴图,只做了简单的锐化,没有什么特别的想法。

 

代码部分

fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    col += ddx(col) * _ddxPower + ddy(col) * _ddyPower;

    return col;
}

 


 

参考

 

【技术美术百人计划】图形 2.3 常用函数介绍

 

跳转回百人合集

 

posted @ 2022-01-09 23:31  anesu  阅读(154)  评论(0编辑  收藏  举报