2.3HLSL常用函数
2.3.1 基本数学运算
max(a,b) min(a,b) mul(a,b) abs(a) round(x)
sqrt(x) 返回x的平方根
rsqrt(x) 返回x的平方根的倒数
degrees(x) 将弧度转换成角度
redians(x) 将角度转换成弧度
noise(x) 噪声函数
2.3.2 幂指对函数
pow(x,y) x的y次幂(x和y均可为自变量或具体的数)
exp(x) 返回以e为底的指数函数
exp2(value x) 返回以2为底,x为指数的幂
ldexp(x,exp) 返回x与2的exp次方的乘积
log(x)
log10(x)
log2(x)
frexp(x,out exp) 把浮点数 x 分解成尾数和指数 x = ret*2^exp,返回值是尾数,exp参数返回的值是指数
(如果x参数为0,则此函数的尾数和指数均返回0)
2.3.3 三角函数与双曲函数
sin(x) cos(x) tan(x)
sincos(x, out s, out c) 返回x的正弦值和余弦值
tan(y,x) asin(x) acos(x) atan(x) atan2(y,x) 返回y/x的反正切值
上述的x值均为弧度表示
sinh(x) 返回x的双曲正弦值 即 (ex-e-x) / 2
cosh(x) 返回x的双曲余弦值 即 (ex+e-x) / 2
tanh(x) 返回x的双曲正弦值 即 (ex-e-x) / (ex+e-x)
2.3.4 数据范围类
ceil(x) 返回>=x的最小整数
floor(x) 返回<=x的最大整数
step(x,y) x<=y为1,否则为0
saturate(x) 返回将x钳制到0和1之间的值
clamp(x,min,max) 把x限制在[min,max]范围内,即判断x是否在这个区间范围内,若在则返回原值,若不在则返回上限或下限
fmod(x,y) 返回x对y取余的余数
frac(x) 返回x的小数部分
modf(x, out ip) 将值x分为小数和整数部分(各部分符号与x相同)
ip返回整数部分,整体返回小数部分
插值函数
lerp(x,y,s) 按照s在x到y之间插值,即返回x*(1-s)+y*s;
smoothstep(min,max,x) 如果x在[min, max]范围内,则返回介于0与1之间的平滑Hermite插值,使用smoothstep在两个值之间创建平滑过渡。例如可以平滑地混合两种颜色。
2.3.5 类型判断类
all(x) 确定指定量的所有分量是否均为非零,若均为非零则返回True,否则false(标量、矢量或者矩阵都可以)
clip(x) 如果输入值小于零,则丢弃当前像素 常用于判定范围(不仅仅针对0,返回值为void),或者测试alpha,如果每个分量代表到平面的距离,还可以用来模拟剪切平面
sign(x) 返回x的正负性 如果x小于零返回-1,如果x等于零返回0,如果x大于零返回1
isinf(x) 判断是否为无穷大或无穷小
isfinite(x) 判断x参数是否有限
isnan(x) 判断是否为NAN
2.3.6 向量与矩阵类
length(v)
normalize(v)
distance(a,b) 表示:两个矢量,返回根号下各个分量之差的平方和(不就是 终点的距离么)
dot(a,b) 点积
cross(a,b) 叉积
determinant(m) 返回矩阵m按行列式方式计算的值
transpose(m) 返回矩阵m的转置矩阵
2.3.7 光线运算类
reflect(i,n) 返回以i为入射方向,n为法线方向的反射光
refract(i,n,ri) 返回以i为入射向量,n为法线方向,ri为折射率的折射光
lit(n_dot_I, n_dot_h, m) 分别对应(normallight,normal半角向量h,镜面反射系数m)返回一个光照向量(环境光,漫反射光,镜面高光反射,1)
faceforward(n,i,ng)得到面向视图方向的曲面法向量输入输出为同元向量,返回-n*sign(dot(i,ng))(normal,light,normal)
光照向量
光照向量(环境光,漫反射光,镜面高光反射,1)(Blinn模型)
2.3.8 纹理查找
GPU在片元处理(PixelShader)阶段是在屏幕空间XY坐标系中对每一个像素去对应的纹理中查找对应的纹素来确定像素的颜色(名字好理解)
1D
方法不太常用,很少有按照这种方式来存储数据的,对应一维的数组
2D
对应二维的数组,也就是矩阵
3D纹理查找
对三维的数据进行查找,由多层的二维数组进行组合。
tex(s,t)在给定纹理采样器(s,指的就是被采样的图片)的情况下,通过t(1D下为标量,2D、3D为矢量,也就是位置坐标)来确定纹素数据。
投影纹理相关(讲的不太清楚 再看一下)
tex1Dproj(s, t)把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术计算出投影纹理的坐标(由于投影光线和投影面的角度存在变化,所以投影纹理的坐标不是简单的缩放,还会发生斜切等其他问题,另外投影面的不规则也是需要解决的问题),最后使用投影纹理坐标进行纹素查询。
ddx、ddy重点自己查一下
mipmap
好图,更好的用于理解为什么内存空间只多占用了1/3
立体纹理查找
与三维查找不同的是,需要指定特定的面,且性能耗费更高。
总结
写出你觉得最常用的5个函数?
- 在看入门精要的时候发现有关矩阵和向量的运算较多,其中 mul(x,y)作为高频应用点肯定必不可少;
- 归一化的运算应该也比较常见,所以saturate(x)应该也比较常用;
- 插值函数;
- 光线运算类应该是重点和难点,一般物体都会受到光照,应该是常用函数;
- 纹理查找中的mipmap相关函数是整个渲染过程中无法避免的问题,所以是常用函数;
ddx、ddy和Mipmap
看了Games101 P9,开始理解了。
- 在Mipmap中,ddx和ddy的主要用途就是用于计算屏幕像素在纹素中的覆盖长度,由
L = MAX(sqrt(ddx(u, v)2, ddy(u, v)2))可以得到近似的覆盖纹素矩形的边长; - 再利用D=Log2(L)获得需要取的Mipmap的层数,取Log2(L)是因为,Mipmap的每一层都缩小到上一层的1/2,只要找到Log2(L)层, 此时L在该层上就是单位长度,从而节省了再次采样的过程;
- 并且,Log2(L)一般情况下为非整数,此时利用两侧的Mipmap层再进行一次线性插值,可以使得结果更加准确,因此Mipmap方法也被称为三次线性插值法。