【Unity Shader 】CG语法
1、Cg基本数据类型
2、数组
数组数据类型在Cg中的作用:作为函数的形参,用于大量数据的传递,例如:顶点参数数组、光照参数数据等。
一维数组:
float a[10];//声明了一个数组,包含 10 个 float 类型数据
float a[4] = {1.0, 2.0, 3.0, 4.0}; //初始化一个数组
int length = a.length;//获取数组长度
多维数组:
float b[2][3] = {{0.0, 0.0, 0.0},{1.0, 1.0, 1.0}};
int length1 = b.length; // length1 值为 2
int length2 = b[0].length; // length2 值为 3
3、Cg语言操作符----Swizzle 操作符
可以使用 Cg 语言中的 swizzle 操作符( . )将一个向量的成员取出组成一个新的向量。 swizzle 操作符被 GPU 硬件高效支持。 swizzle 操作符后接 x 、 y 、 z 、 w ,分别表示原始向量的第一个、第二个、第三个、第四个元素; swizzle操作符后接 r 、 g 、 b 和 a 的含义与前者等同。不过为了程序的易读性,建议对于表示颜色值的向量,使用 swizzle 操作符后接 r 、 g 、 b 和 a 的方式。
举例如下:
float4(a, b, c, d).xyz 等价于 float3(a, b, c)
float4(a, b, c, d).xyy 等价于 float3(a, b, b)
float4(a, b, c, d).wzyx 等价于 float4(d, c, b, a)
float4(a, b, c, d).w 等价于 float d
值得注意的是, Cg 语言中 float a 和 float1 a 是基本等价的,两者可以进行类型转换; float 、 bool 、 half 等基本类型声明的变量也可以使用 swizzle 操作符。例如:
float a = 1.0;
float4 b = a.xxxx;
注意: swizzle 操作符只能对结构体和向量使用,不能对数组使用,如果对数组使用 swizzle 操作符则会出现错误信息: error C1010: expression left of . ” x ” is not a struct or array (其实个人觉得,提示的错误信息中 array 换成vector 更加合适)。
要从数组中取值必须使用 [] 符号。例如:
float a[3] = {1.0,1.0,0.0};
float b = a[0]; // 正确
float c = a.x; // 编译会提示错误信息
4、Cg标准函数库
数学函数
abs(x)
返回输入参数的绝对值
acos(x)
反余切函数,输入参数范围为[-1,1], 返回[0,π]区间的角度值
all(x)
如果输入参数均不为0,则返回ture; 否则返回flase。&&运算
any(x)
输入参数只要有其中一个不为0,则返回true。
asin(x)
反正弦函数,输入参数取值区间为[−1,1],返回角度值范围为, [−π2,π2]
atan(x)
反正切函数,返回角度值范围为[−π2,π2]
atan2(y,x)
计算y/x的反正切值。实际上和atan(x)函数功能完全一样,至少输入参数不同。atan(x) = atan2(x, float(1))。
ceil(x)
对输入参数向上取整。例如: ceil(float(1.3)) ,其返回值为2.0
clamp(x,a,b)
如果x值小于a,则返回a;如果x值大于b,返回b;否则,返回x。
cos(x)
返回弧度x的余弦值。返回值范围为[−1,1]
cosh(x)
双曲余弦(hyperbolic cosine)函数,计算x的双曲余弦值。
cross(A,B)
返回两个三元向量的叉积(cross product)。注意,输入参数必须是三元向量!
degrees(x)
输入参数为弧度值(radians),函数将其转换为角度值(degrees)
determinant(m)
计算矩阵的行列式因子。
dot(A,B)
返回A和B的点积(dot product)。参数A和B可以是标量,也可以是向量(输入参数方面,点积和叉积函数有很大不同)。
exp(x)
计算ex的值,e=2.71828182845904523536
exp2(x)
计算2x的值
floor(x)
对输入参数向下取整。例如floor(float(1.3))返回的值为1.0;但是floor(float(-1.3))返回的值为-2.0。该函数与ceil(x)函数相对应。
fmod(x,y)
返回x/y的余数。如果y为0,结果不可预料。
frac(x)
返回标量或矢量的小数
frexp(x, out i)
将浮点数x分解为尾数和指数,即x=m∗2i, 返回m,并将指数存入i中;如果x为0,则尾数和指数都返回0
isfinite(x)
判断标量或者向量中的每个数据是否是有限数,如果是返回true;否则返回false;
isinf(x)
判断标量或者向量中的每个数据是否是无限,如果是返回true;否则返回false;
isnan(x)
判断标量或者向量中的每个数据是否是非数据(not-a-number NaN),如果是返回true;否则返回false;
ldexp(x, n)
计算x∗2n的值
lerp(a, b, f)
计算(1−f)∗a+b∗f或者a+f∗(b−a)的值。即在下限a和上限b之间进行插值,f表示权值。注意,如果a和b是向量,则权值f必须是标量或者等长的向量。
lit(NdotL, NdotH, m)
N表示法向量;L表示入射光向量;H表示半角向量;m表示高光系数。 函数计算环境光、散射光、镜面光的贡献,返回的4元向量。
X位表示环境光的贡献,总是1.0;
Y位代表散射光的贡献,如果 N∙L<0,则为0;否则为N∙L
Z位代表镜面光的贡献,如果N∙L<0 或者N∙H<0,则位0;否则为(N∙L)m;
W位始终位1.0
log(x)
计算ln(x)的值,x必须大于0
log2(x)
计算log(x)