前言
紧接前面的 Shader 基础框架 和 CG的基本数据类型。这里要讲解基本的CG编写语法,包括函数的声明,定义。
变量的声明
在 CGPROGRAM 中我们想要使用 Properties 中的属性来进行运算等操作,一般只需要使得变量名与属性相同即可,但是也要确保数据类型的相对应。
示例:
1 | Properties{ |
可见大部分的值类型属性都可以使用 float 来声明。
函数的声明和定义
函数的定义与 C语言 定义完全相同。而这里要说的是比较特殊的 Vertex 函数 和 Fragment 函数的声明。
一般比较完整的 shader,我们需用声明 Vertex/Fragment 来作为渲染 顶点和片元 的入口函数。
例如:
1 |
|
语义的使用
往往顶点/片元函数要搭配语义来使用。
语义一般在函数的参数与返回中使用。
如:
1 |
|
而作为顶点 shader 入口,我们希望传入模型的顶点作为参数。这里就可以使用参数的语义 POSITION 。
1
2
3
4// 由系统传入(或者说是从系统中获取到顶点坐标)顶点坐标向量
float4 myvert(float4 v : POSITION){
}而我们的返回的值(剪裁空间坐标系的顶点向量)要告诉给系统,才能被渲染出来,因此可以给函数增加语义 SV_POSITION 。
1 |
|
使用结构体
在 Shader CG编程基础数据类型 写了结构体的定义方法,一般来说,尽量不要在结构体中定义函数。
由上面的例子可以看出,有时候往往我们需要传入多个值,甚至需要返回多个值。这里就可以使用结构体。
1 | /** |
- 可见,使用结构体后,函数的定义会变得十分清晰。
- 在结构体中,必须所有的属性都要加上语义
- 要注意 有些语义只能在特定的函数中使用。 例如 POSITION 只能在顶点函数中使用。
顶点函数和片元函数间的参数传递
有时候我们可能需要从顶点函数中获取到数据传递到片元函数中,这就涉及到顶点函数与片元函数的参数传递。
例子:
1 | struct a2v{ |
- 这样就完成了两函数的参数传递。
- 基本思路是使用一个 COLOR0 语义作为中间桥梁,COLOR0 是一个顶点颜色的存储空间。
结语
需要提一下的,shader 中必须要有一个入口,就像 C 语言的 main 函数,往往 vertex 与 fragment 必须两个同时具备。
着色程序分为顶点程序和片断程序,两者对应着图形流水线上的不同阶段,所以这两个程序都各有一个入口函数。