前言
上一篇:Unity Shader 学习(二):初识ShaderLab – 以“Unlit Shader”模板为例 02
只提到了向量类型的构造函数,本篇继续学习更多在shader开发中用到的Cg/HLSL函数,只列举出一些常用的函数,并不会一一列举,想要了解更多请直接看官方文档。
主要参考:
一、值的范围与比较
函数 | 解释(部分) | 类比 UnityEngine 函数 |
---|---|---|
abs(x) | 返回 x 的绝对值; | Mathf.Abs |
min(x, y) | 返回 x、y 两个值中较小的那个; | Mathf.Min |
max(x, y) | 返回 x、y 两个值中较大的那个; | Mathf.Max |
clamp(x, a, b) | 将 x 的值限制在 [a, b] 范围中; | Mathf.Clamp |
saturate(x) | 将 x 的值限制在 [0, 1] 范围中; | Mathf.Clamp01 |
lerp(a, b, x) | 根据 x 的值(x ∈ [0, 1])返回 a 到 b 之间的线性插值; | Mathf.Lerp |
smoothstep(a, b, x) | 若 x ∈ [a, b],返回 a 到 b 之间的平滑插值(介于 0 到 1 之间) ;若 x <= a,返回 0;若 x > = b,返回 1 ; | |
step(x, y) | 若 x>= y,返回 1 ;否则,返回 0; | x >= y ? 1 : 0 |
-
lerp(a, b, x)
以a = 0,b = 3为例,函数图像:
-
smoothstep(a, b, x)
以a = 0,b = 3为例,函数图像:
注:以上只解释了上述函数在参数是标量类型的情况;实际上,函数的参数还可以是向量、矩阵类型
参考:Shader实验室: smoothstep函数
拓展:可能在Unity中,你一直用错了Lerp线性插值
二、三角函数
函数 | 解释(部分) | 类比 UnityEngine 函数 |
---|---|---|
sin(x) | 返回弧度 x 的正弦值; | Mathf.Sin |
cos(x) | 返回弧度 x 的余弦值; | Mathf.Cos |
sincos(x, out s, out c) | 得出弧度 x 的正弦值 s 和余弦值 c ; | |
radians(x) | 将角度 x 的值转换为弧度; | Mathf.Deg2Rad |
degrees(x) | 将弧度 x 的值转换为角度; | Mathf.Rad2Deg |
弧度与角度的转换:
- 1° = π / 180 ≈ 0.01745弧度
- 1弧度 = 180 / π ≈ 57.29578°
三、向量相关
函数 | 解释 | 类比 UnityEngine 函数 |
---|---|---|
length(x) | 返回 x 向量的长度,为标量; | Vector3.Magnitude |
normalize(x) | 返回 x 向量归一化后的向量,即 x / length(x); | Vector3.Normalize |
distance(x, y) | 返回 x 向量/坐标 和 y 向量/坐标 之间的距离,为标量; | Vector3.Distance |
dot(x, y) | 返回向量 x 和向量 y 点积的结果,为标量; | Vector3.Dot |
cross(x, y) | 返回三维向量 x 和三维向量 y 叉积的结果,为矢量; | Vector3.Cross |
四、常规计算
函数 | 解释 | 类比 UnityEngine 函数 |
---|---|---|
mul(x, y) | 返回 x 矩阵/行向量 和 y 矩阵/列向量 (x 的列数与 y 的行数必须相同)做矩阵乘法的结果,为 x 行 y 列矩阵; | 运算符( * ) |
sqrt(x) | 返回 x 开方后的值; | Mathf.Sqrt |
pow(x, y) | 返回 x 的 y 次方; | Mathf.Pow |
fmod(x, y) | 返回 x 除以 y 的余数; | x % y |
-
mul(x, y)
矩阵乘法中左乘右乘是不同的,Shader中一般多用于一个向量/坐标与矩阵相乘做矩阵变换,例如:
- 行向量左乘矩阵(行向量 × 矩阵);
- 列向量右乘矩阵(矩阵 × 列向量)。
从CGInclude文件中可以看出:Unity中的顶点变换是将顶点坐标作为列向量右乘矩阵;
但并不是全部矩阵变换都是右乘(参考:法线变换需要左乘矩阵,顶点变换需要右乘矩阵)。
拓展:
- HLSL中以列向量存储矩阵(列主序);
- Unity内置矩阵 是列主序的;
以上两点的行主序或列主序影响的是矩阵数据在内存中的分布与读取方式,与计算中构造的矩阵是行主序或列主序无关(关于这一点,强烈建议看看这篇:HLSL mul() variables clarification 中 Nathan Reed 的回答)。
参考:
数学运算 - HLSL
DirectX11–HLSL中矩阵的内存布局和mul函数探讨
本篇完。主要学习了一些最常用的Cg/HLSL内置函数,下一篇将回到 “Unlit Shader” 模板看看剩下的东西。