数据类型
基本数据类型
Cg 中向量、矩阵与数组是完全不同,向量和矩阵是内置的数据类型(矩阵基于向量),而数组则是一种数据结构,不是内置数据类型。
常量的类型后缀( type suffix)有 3 种:
- f :表示 float;
- h: 表示 half;
- x: 表示 fixed
float
float, 32 位浮点数据,一个符号位。浮点数据类型被所有的 profile 支持(但是 DirectX8 pixel profiles 在一些操作中降低了浮点数的精度和范围);
half
half, 16 为浮点数据;
int
int, 32 位整形数据,有些 profile 会将 int 类型作为 float 类型使用;
fixed
fixed, 12 位定点数,被所有的 fragment profiles 所支持;
bool
bool,布尔数据,通常用于 if 和条件操作符( ?:),布尔数据类型被所有的profiles 支持;
sampler*
sampler*,纹理对象的句柄( the handle to a texture object),分为 6 类:sampler, sampler1D, sampler2D, sampler3D, samplerCUBE,和 samplerRECT。DirectX profiles 不支持 samplerRECT 类型, 除此之外这些类型被所有的 pixelprofiles 和 NV40 vertex program profile 所支持。
string
string,字符类型,该类型不被当前存在的 profile 所支持,实际上也没有必要在 Cg 程序中用到字符类型,但是你可以通过 Cg runtime API 声明该类型变量,并赋值;因此,该类型变量可以保存 Cg 文件的信息。
向量
向量最长不能超过 4 元。
1 | float float2 float3 float4 |
矩阵
矩阵最大的维数不能超过 4*4 阶
1 | float1x1 matrix1; // 表示 1*1 阶矩阵,包含 1 个 float 类型数据 |
数组类型
在着色程序中,数组通常的使用目的是:作为从外部应用程序传入大量参数到 Cg 的顶点程序中的形参接口,例如与皮肤形变相关的矩阵数组,或者光照参数数组等。简而言之,数组数据类型在 Cg 程序中的作用是:作为函数的形参,用于大量数据的转递。
1 | float a[10]; // 声明了一个数组,包含 10 个 float 类型数据 |
结构类型
结构体的声明以关键字 struct 开始,然后紧跟结构体的名字,接下来是一个大括号,并以分号结尾(不要忘了分号)。大括号中是结构体的定义,分为两大类:成员变量和成员函数。
1 | struct myAdd |
关键字
Uniform
uniform 修辞的变量的值是从外部传入的,所以在 Cg 程序(顶点程序和片段程序)中通常使用 uniform 参数修辞函数形参,不容许声明一个用 uniform 修辞的局部变量!
const
const 所修辞的变量在初始化之后不能再去改变它的值。
const 修辞符与 uniform 修辞符是相互独立的,对一个变量既可以单独使用const 或者 uniform,也可以同时使用。
in
修辞一个形参只是用于输入,进入函数体时被初始化,且该形参值的改变不会影响实参值,这是典型的值传递方式。
1 | void myFunction(in float x); // 形参 x,只是用于输入 |
out
修辞一个形参只是用于输出的,进入函数体时并没有被初始化,这种类型的形参一般是一个函数的运行结果;
1 | void myFunction(out float x); // 形参 x,只是用于输出 |
inout
修辞一个形参既用于输入也用于输出,这是典型的引用传递。
1 | void myFunction(inout float x); // 形参 x,即用于输入时初始化,也用于输出数据 |
语义
语义词,表示输入图元的数据含义(是位置信息,还是法向量信息),也表明这些图元数据存放的硬件资源(寄存器或者纹理缓冲区)。顶点着色程序和片段着色程序中 Varying inputs 类型的输入,必须和一个语义词相绑定,这称之为绑定语义( binding semantics)。
语义,是两个处理阶段(顶点程序、片段程序)之间的输入\输出数据和寄存器之间的桥梁,同时语义通常也表示数据的含义,如 POSITION一般表示参数种存放的数据是顶点位置。
语义,只对两个处理阶段的输入\输出数据有意义,也就是说,语义只有在入口函数中才有效,在内部函数(一个阶段的内部处理函数,和下一个阶段没有数据传递关系)的无效。
语义,分为输入语义和输入语义;输入语义和输出语义是有区别的。虽然一些参数经常会使用相同的绑定语义词, 例如: 顶点 Shader 的输入参数, POSITION72指应用程序传入的顶点位置, 而输出参数使用 POSITION 语义就表示要反馈给硬件光栅器的裁剪空间位置,光栅器把 POSITION 当成一个位置信息。虽然两个语义都命名为 POSITION,但却对应着图形流水线上不同的寄存器。
顶点着色程序的输入语义
POSITION
表示该参数中的数据是的顶点位置坐标(通常位于模型空间),属于输入参数,语义词 POSITION 是输入语义,如果在 OpenGL 中则对应为接受应用程序传递的顶点数据的寄存器(图形硬件上)。
顶点位置坐标传入顶点着色程序中转化为四元向量 float4,最后一元数据为 1
NORMAL
float4类型,表示该参数中的数据是顶点法向量坐标(通常位于模型空间),属于输入参数,语义词 NORMAL 是输入语义,如果在 OpenGL 中则对应为接受应用程序传递的顶点法向量的寄存器(图形硬件上)。
顶点法向量传入顶点着色程序中转化为四元向量float4,最后一元数据为 0
BLENDWEIGHT
TANGENT
BINORMAL
PSIZE
BLENDINDICES
TEXCOORD0—TEXCOORD7
顶点着色程序的输出语义
顶点程序的输出数据被传入到片断程序中,所以顶点着色程序的输出语义词,通常也是片段程序的输入语义词。
顶点着色程序必须声明一个输出变量,并绑定POSITION语义词,该变量中的数据将被用于,且只被用于光栅化。
如果需要从顶点着色程序向片段程序传递数据,例如顶点投影坐标、光照信息等,则可以声明另外的参数,绑定到TEXCOORD系列的语义词进行数据传递,实际上TEXCOORD系列的语义词通常都被用于从顶点程序向片段程序之间传递数据。也可以选择不使用struct结构,而直接在函数形参中进行语义绑定。无论使用何种方式,都要记住vertex program中的绑定语义( POSITION除外)的输出形参中的数据会传递到fragment program中绑定相同语义的输入形参中。
POSITION
PSIZE
FOG
COLOR0-COLOR1
TEXCOORD0-TEXCOORD7
片段着色程序的输出语义
片段着色程序的输出语义词较少,通常是COLOR。这是因为片段着色程序运行完毕后,就基本到了GPU流水线的末端了。 片段程序必须声明一个out向量(三元或四元),绑定语义词COLOR,这个值将被用作该片断的最终颜色值。