声明:
- 本文章是个人在学习B站“百人计划”时的学习笔记。如有不足之处,烦请批评指正。
- 视频链接:https://www.bilibili.com/video/BV1q64y1m7Ev/?vd_source=8a07825248c35f3d990cde21e751b476
笔记:
API库参考:https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions?redirectedfrom=MSDN
函数介绍
-
基本数学运算
- max(a,b) 返回较大的那个
- min(a,b) 返回较小的那个
- mul(a,b) 两数相乘,常用于矩阵运算
- abs(a) 返回输入值的绝对值
- round(x) 返回与x最近的整数
- sqrt(x) 返回指定值的平方根
- rsqrt(x) 返回指定值的平方根的倒数
- degrees(x) 转换成弧度
- redians(x) 将角度转为弧度制
- noise(x) 噪声函数
-
幂指对与偏导数
- pow(x,y) x的y次幂(x和y均可为自变量或具体的数) 即x^yxyx^yxy
- ldexp(x,exp) 返回x与2的exp次方的乘积 即x*2^{exp}x∗2expx*2^{exp}x∗2exp
- exp(x) 返回以e为底的指数函数 即e^xexe^xex
- exp2(value x) 返回以2为底,x为幂的指数 即2^x2x2^x2x
- log(x) 返回指定值的以e为底的对数 即ln xlnxln xlnx
- log10(x) 求以10为底的对数 即log_{10}xlog10xlog_{10}xlog10x
- log2(x) 求以2为底的对数 即log_2xlog2xlog_2xlog2x
- frexp(x,out exp) 把浮点数 x 分解成尾数和指数
- 返回值是尾数,exp参数返回的值是指数 (如果x参数为0,则此函数的尾数和指数均返回0)
- 只输入 x 一个浮点值,输出frexp和out exp
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-frexp
-
三角函数与双曲线函数
- asin(x) 返回输入值的反正弦值
- acos(x) 返回输入值反余弦值
- atan(x) 返回输入值的反正切值
- atan2(y,x) 返回y/x的反正切值
- sin(x)、cos(x)、tan(x)、tan(y,x)
- sincos(x,out s ,out c) 返回x的正弦值和余弦值
- sinh(x) 返回x的双曲正弦值 即(e^x-e^{-x})/2(ex−e−x)/2(e^x-e^{-x})/2(ex−e−x)/2
- cosh(x) 返回x的双曲余弦值 即(e^x+e^{-x})/2(ex+e−x)/2(e^x+e^{-x})/2(ex+e−x)/2
- tanh(x) 返回x双曲正切值 即(e^x-e^{-x})/(e^x+e^{-x})(ex−e−x)/(ex+e−x)(e^x-e^{-x})/(e^x+e^{-x})(ex−e−x)/(ex+e−x)
- 双曲函数解析:https://zhuanlan.zhihu.com/p/20042215
-
数据范围类


- ceil(x) 返回>=x的最小整数
- step(x,y)x<=y为1,否则为0
- floor(x) 返回小于或等于x的最大整数
- saturate(x) 返回将x钳制到0和1之间的值
- clamp(x,min,max) 把x限制在[min, max]范围内,小于返回min,大于返回max
- frac(x) 返回x部分的小数
- fmord(a,b) 返回a/b的浮点部分
- modf(x,out ip) 将值x分为小数和整数部分(各部分符号与x相同)
- ip返回整数部分,函数整体返回小数部分
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-modf
- lerp(a,b,s) 按照s在a到b之间插值
- s 一般是个变量。可以输入一个线性变换的值
- 线性内插基于以下公式:x*(1 + s) + y*s,可等效地编写为 x + s (y – x) 。
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp
- smoothstep(min,max,x) 如果x在[ min,max ]范围内,则返回介于0和1
- 之间的平滑Hermite插值;使用smoothstep HLSL内在函数在两个值之间创建平滑过渡。例如,使用此功能平滑地混合两种颜色
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-smoothstep
-
类型判断类
- all(x) 确定指定量的所有分量是否均为非零,均非零则返回true,否则返回false
- (处理由浮点型、整型、布尔型数据定义的标量、向量或者矩阵)
- clip(x) 如果输入值小于零(不一定要是零),则丢弃当前像素
- 常用于判定范围(不仅仅针对0,返回值为void)
- 常用于测试alpha,如果每个分量代表到平面的距离,还可以用来模拟剪切平面
- sign(x) 返回x的正负性 如果x小于零返回-1,如果x等于零返回0,如果x大于零返回1
- isinf(x) 如果x参数为+ INF或-INF(无穷+无穷仍无穷,0x3f3f3f3f),返回true,否则返回False
- isfinite(x) 判断x参数是有限,即有界的,与isinf(x)相反xiang'fa
- isnan(x) 如果x参数为NAN(非数字),返回true,否则返回false
- all(x) 确定指定量的所有分量是否均为非零,均非零则返回true,否则返回false
-
向量与矩阵类
- length(v) 返回向量的长度
- normalize(v) 向量归一化,x/length(x) 。方向向量归一化
- distance(a,b) 返回两个向量之间的距离,按理说应该为0,此处表示为根号下各分量之差的平方和
- dot(a,b) 返回a和b这两个向量的标积/内积/数量积/点积 (a在b上的投影长,a·b=|a||b|·cosθ)
- cross(a,b) 返回a和b这两个向量的矢积/外积/向量积/叉积
- (返回值是个向量,而且与a、b都垂直,大小上| a x b | = |a| * |b| * sinθ )
- determinant(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,半角向量h,镜面反射系数m)
- 返回光照向量(环境光,漫反射光,镜面高光反射,1)
- faceforward(n,i,ng) 得到面向视图方向的曲面法向量
- 输入输出为同元向量,返回 -n*sign(dot(i,ng))(normal,light,normal)
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-faceforward
-
1D纹理查找
- GPU在PS阶段是在屏幕空间XY坐标系中对每一个像素去对应的纹理中查找对应的纹素来确定像素的颜色
- 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层的一维纹理查找
- 偏导数是指相邻像素颜色差值,传入tex1D(s, t, ddx, ddy)时,ddx和ddy越大就越只能取到差值较大的相邻像素,一般图片的相邻像素都不会太大,因此取得ddx和ddy越大会导致图片越来越模糊。
- 使用渐变对一维纹理采样,以选择 mip 级别。
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-tex1dgrad
- tex1Dproj(s, t) 把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术需要计算出投影纹理坐标t(坐标t.w除以透视值),然后使用投影纹理坐标进行查询
- 使用投影除法对一维纹理进行采样;在查找之前,纹理坐标除以 t.w
- https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-tex1dproj
- Cg(C for Graphic)语言标准函数库之纹理映射函数,偏导函数,与调试函数:https://blog.csdn.net/liu_lin_xm/article/details/4810266
-
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) 使用微分查询三维纹理 t和ddxy均为vector
- tex3Dlod(s, t) 使用LOD查找纹理s在t.w位置的color4
- tex3Dbias(s, t) 将t.w决定的某个MIP层偏置后的三维纹理查找
- tex3Dgrad(s,t,ddx,ddy) 使用微分并指定MIP层的三维纹理查找
- tex3Dproj(s, t) 把纹理当做一张幻灯片投影到场景中,先使用投影纹理技术需要计算出投影纹理坐标t(坐标t.w除以透视值),然后使用投影纹理坐标进行查询
-
立体纹理查找
- texCUBE(s,t) 返回纹理采样器s在vector t位置的颜色
- texCUBE(s,t,ddx,ddy)使用微分查询立方体维纹理 t和ddxy均为vector
- texCUBEDload(s,t) 使用LOD查找纹理s在t.w位置的color4
- texCUBEbias(s,t) 将t.w决定的某个MIP层偏置后的立方体纹理查找
- texCUBEgrad(s,t,ddx,ddy) 使用微分并指定MIP层的立方体纹理查找
- texCUBEproj(s,t) 使用投影方式的立方体纹理查找
个人认为最常用的五个函数
- tex2D
- dot
- normalize
- saturate
- lerp
ddxddy的实际使用和测试结果
-
锐化
原图

效果图

关键代码
col += (ddx(col) + ddy(col)) * _A; // 计算当前像素的梯度,并将其与 _A 相乘,最后将结果添加到原始颜色中
当 col = (ddx(col) + ddy(col)) 时




