# 三元运算符
(a<0) ?(b=a):(c=a); 正常来说是这样的,但是因为 CG 中向量也经常用到,所以三元运算符又多了一层含义 如下:
1 | float3 h = float3(-1.0,1.0,1.0); |
三元向量 h 与 float3 (0.0, 0.0, 0.0) 做比较运算后结果为(true, false, false), 所以 i 的第一个数据赋值给 K 的第一个数据,g 的第二个和第三个数据赋值给 k 的第二个和第三个数据,K 的值为 (1.0, 1.0, 0.0)。
# 函数的递归是被禁止的
RT 循环也不推荐使用
# 接下来产生的问题
- 从应用程序传递到 GPU 的数据,分为图元信息数据 (在 GPU 处理的基本数据如顶点信息等) 和其他的离散数据 (在 GPU 运行流程中不会发生变化,如材质对光的反射、折射信息),这两种输入数据如何区分?
- 从应用程序传递到 GPU 中的图元信息如何区分类型,即,顶点程序怎么知道一个数据是位置数据,而不是法向量数据。
- 顶点着色程序与片元着色程序之间的数据传递如何进行。
# CG 关键字
基本数据变量,in/out/inout 用于表示数据的传递方式。
# uniform
CG 语言将数据流分为两类,
- Varing inputs, 即数据输入图元信息的各种组成要素。・从应用程序输入到 GPU 的数据・如顶点数据,顶点的法向量数据,纹理坐标数据等。
- Uniform inputs,表示一些与三维渲染有关的离散信息数据,这些数据通常由应用程序传入,并通常不会随着图元信息的变化而变化,如材质对光的反射信息,运动矩阵等,同 OpenGL 的 uniform
故 uniform 只允许修饰全局变量
# const
CG 也提供 const 修辞符,与 C/C++ 中含义一样,被 const 所修辞的变量在初始化后不能再去改变它的值。
# 输入 / 输出修饰符 (in\out\inout)
CG 语言同 C++ 一样使用值传递与引用传递,但是不会使用指针来实现引用传递
-
in: 修辞一个形参只是用于输入,进入函数体时被初始化,该形参不会影响实参
-
out: 秀是一个形参只用于输出,进入函数体时并未被初始化,这种类型的形参一般是一个函数的运行结果.
-
inout: 修辞一个形参即用于输入也用于输出,典型的引用
也可以用 return 来代替 out
# 语义词 (Semantic) 与语义绑定 (Binding Semantic)
语义词,表示输入图元的数据含义 (是位置信息,还是法向量) GPU 不支持指针,所以 CG 语言通过将输入 / 输出数据和寄存器做一个映射关系。根据语义,CG 从对应的寄存器中取出数据,处理好数据后,再将数据放回寄存器中. Tag, 重点: 语义: 是两个处理阶段(顶点程序,片段程序)之间的输入\输出数据和寄存器之间的桥梁
同时,语义通常也表示数据的含义,如 POSITION
一般表示参数种存放的数据是顶点位置。 语义,只在两个处理阶段 (顶点 \ 片元) 有意义,也就是说,语义只有在入口函数中才有效。在内部函数中无效。
# 顶点着色器的输入语义
- POSITION
- BLENDWEIGHT
- NORMAL
- TANGENT
- BINORMAL
- PSIZE
- BLENDINDICES
- TEXCOORD0-TEXCOORD7
语义词 POSITION0 等价于 POSITION
1 | in float4 modelPos : POSITION |
表示该参数中的数据是顶点位置坐标 (通常位于模型空间)
1 | in float4 modelNormal : NORMAL |
表示该参数中的数据是顶点法向量坐标,(通常位于模型空间)
Tip: 上面两个变量都是四元变量,目的是为了使用到齐次空间内
位置坐标最后一元是 1
, 顶点法向量最后一元是 0
# 顶点着色器的输出语义
顶点程序的输出语义被输入到片段着色器中,所以顶点着色器的输出语义,通常也是片段程序的输入语义,不过语义词 POSITION 除外。下面这些语义词适用于所有的 CG Vertex profiles 作为输出语义和 Cg fragment profiles 的输入语义: POSITION,PSIZE,FOG,COLOR0-COLOR1,TEXCOORD0-TEXCOORD7 顶点着色器必须包含一个带有 POSITION 的输出变量 如下:
1 | void main_v(float4 position: POSITION, |
上述代码会报错,因为必须包含一个输出变量
# 使用 struct 保证输出语义与输入语义一致
为了保证顶点程序输出语义和片段程序的输入语义的一致性,通常使用相同的 struct 类型数据作为两者之间的传递。
1 | struct VertexIn{ |
注意:当时用 struct 结构中的成员变量绑定语义时,需要注意到顶点着色器程序中使用的 POSITION 语义词,是不会被片段程序所使用的。 顶点程序中绑定的语义 (POSITION 除外) 会传递到对应的片元着色器相同的语义中去。
# 片段着色器的输出语义
片段着色器的输出语义比较少,通常是 COLOR, 片段着色器必须声明一个 out 向量 (三元或者四元), 绑定到 COLOR 语义上,这个值将被用作最终的颜色值
1 | void main_f(out float4 color:COLOR){ |