作者:YOLO_TO_GAME
来源:优快云
原文:https://blog.youkuaiyun.com/weixin_39706943/article/details/81485758
一、Cg基本数据类型
float 32位浮点数
half 16位浮点数
int 32位整型
fixed 12位定点数
bool 布尔数据
simpler* 纹理对象的句柄( the handle to a texture object ) ,分为 6 类:
sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT
string 字符类型(几乎不使用)
例如float4,bool4等
向量数据类型,向量长度不能超过4元,可以有float1,float2,float3,float4,没有float5及以上
例如float4x4,float2x3等
矩阵数据类型,最大维数不超过4*4阶矩阵
二、类型转换:
Cg 中的类型转换和 C 语言中的类型转换很类似。 C 语言中类型转换可以是强制类型转换,也可以是隐式转换,如果是后者,则数据类型从低精度向高精度转换。在 Cg 语言中也是如此。
float a = 1.0;
half b = 2.0;
float c = a+b; //等价于 float c = a + (float)b;
当有类型变量和无类型常量数据进行运算时,该常量数据不做类型转换,例如:
float a = 1.0;
float b = a + 2.0; //2.0 为无类型常量数据,编译时作为 float 类型
Cg 语言中对于常量数据可以加上类型后缀,表示该数据的类型,例如:
float a = 1.0;
float b = a + 2.0h; //2.0h 为 half 类型常量数据,运算是需要做类型转换
常量的类型后缀有3种:
f:表示float
h:表示half
x:表示fixed
三、数组
数组数据类型在Cg中的作用:作为函数的形参,用于大量数据的传递,例如:顶点参数数组、光照参数数据等。
四、结构体
结构体的声明以关键字 struct 开始,然后紧跟结构体的名字,接下来是一个大括号,并以分号结尾(不要忘了分号) 。大括号中是结构体的定义,分为两大类:成员变量和成员函数。
struct myAdd
{
float val;
float add(float x)
{
return val + x;
}
};
myAdd s;
使用符号“.”引用结构体的成员变量和成员函数:
float a = s.value;
float b = s.add(a);
一般来说 ,Cg 的源代码都会在文件首部定义二个结构体,分别用于定义输人和输出的类型,这二个结构体定义与普通的 C 结构定义不同,除了定义结构体成员的数据类型外,还定义了该成员的绑定语义类型( Binding Semantics) ,所谓绑定语义类型是为了与宿主环境进行数据交换的时候识别不同数据类型的。 目前Cg 支持的绑定语义类型包括 POSTION 位置 ) , COLOR( 颜色 ) , NORMAL( 法向量 ) , Texcoord( 纹理坐标 ) 等类型。
五、Cg语言操作符
1.关系操作符:<、<=、==、>=、>、!=
2.逻辑操作符:&&、||、!
3.数学操作符:+、-、~、*、/、%、++、--、+=、-=、*=、/=
4.移位操作符
Cg 语言中的移位操作符,功能和 C 语言中的一样,也可以作用在向量上,但是向量类型必须是 int 类型。例如:
int2 a = int2(0.0,0.0);
int2 b = a>>1;
5.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 。
要从数组中取值必须使用 [] 符号。例如:
float a[3] = {1.0,1.0,0.0};
float b = a[0]; // 正确
float c = a.x; // 编译会提示错误信息
六、控制流语句
条件语句有: if 、 if-else ;循环语句有: while 、 for 。 break 语句可以和在 for 语句中使用。
七、函数
1、入口函数
由于着色程序分为顶点程序和片段程序,两者对应的图形流水线上的不同阶段,所以这两个程序都各有一个入口函数。
struct C2E1v_Output {
float4 position : POSITION;
float3 color : COLOR;
};
C2E1v_Output C2E1v_green(float2 position : POSITION)
{
C2E1v_Output OUT;
OUT.position = float4(position,0,1);
OUT.color = float3(0,1,0);
return OUT;
}
2、Cg标准函数库
数学函数
几何函数
关于几何函数需要注意以下两点:
1、着色程序中的向量最好进行归一化之后再使用,否则会出现难以预料的 错误;
2、reflect 函数和 refract 函数都存在以“入射光方向向量”作为输入参数, 注意这两个函数中使用的入射光方向向量,是从外指向几何顶点的;平时我 们在着色程序中都是将入射光方向向量作为从顶点出发的。
纹理映射函数
所有这些函数返回四元向量值
s:一元、二元、三元纹理坐标
z:使用深度比较的值
q:一个透视值(其实就是透视投影后得到的齐次坐标的最后一位),这个值被用来除以纹理坐标(s),得到新的纹理坐标(已归一化)然后用于纹理查询
偏导函数
-
函数 ddx和ddy用于求取相邻像素间 属性的差值;
-
函数 ddx和ddy的输入参数通常是纹理坐标;
-
函数 ddx和ddy返回相邻像素键的属性差值;
调试函数