顶点着色器的输出向量
gl_Position
,和片段着色器的
gl_FragCoord;
gl_PointSize:
其中一个图元是
GL_POINTS
,如果使用它的话,每一个顶点都是一个图元,都会被渲染为一个点。我们可以通过OpenGL的glPointSize
函数来设置渲染出来的点的大小,但我们也可以在顶点着色器中修改这个值。
GLSL定义了一个叫做
gl_PointSize
输出变量,它是一个float
变量,你可以使用它来设置点的宽高(像素)。在顶点着色器中修改点的大小的话,你就能对每个顶点设置不同的值了。
在顶点着色器中修改点大小的功能默认是禁用的,如果你需要启用它的话,你需要启用OpenGL的
glEnable(GL_PROGRAM_POINT_SIZE);
gl_VertexID:
gl_Position
和
gl_PointSize
都是
输出变量
,因为它们的值是作为顶点着色器的输出被读取的。我们可以对它们进行写入,来改变结果。顶点着色器还为我们提供了一个有趣的
输入变量
,我们只能对它进行读取,它叫做
gl_VertexID
。
整型变量
gl_VertexID
储存了正在绘制顶点的当前ID。当(使用glDrawElements
)进行索引渲染的时候,这个变量会存储正在绘制顶点的当前索引。当(使用glDrawArrays
)不使用索引进行绘制的时候,这个变量会储存从渲染调用开始的已处理顶点数量。
gl_FragCoord:
gl_FragCoord
的x和y分量是片段的窗口空间(Window-space)坐标,其原点为窗口的左下角。我们已经使用glViewport
设定了一个800x600的窗口了,所以片段窗口空间坐标的x分量将在0到800之间,y分量在0到600之间。
void
main
()
{
if
(gl_FragCoord.x <
400
)
FragColor = vec4(
1.0
,
0.0
,
0.0
,
1.0
);
else
FragColor = vec4(
0.0
,
1.0
,
0.0
,
1.0
); }
gl_FrontFacing:
片段着色器另外一个很有意思的输入变量是
gl_FrontFacing
。在
面剔除
教程中,我们提到OpenGL能够根据顶点的环绕顺序来决定一个面是正向还是背向面。如果我们不(启用
GL_FACE_CULL
来)使用面剔除,那么
gl_FrontFacing
将会告诉我们当前片段是属于正向面的一部分还是背向面的一部分。
gl_FrontFacing
变量是一个bool
,如果当前片段是正向面的一部分那么就是
true
,否则就是
false
gl_FragDepth:
Uniform缓存:
Uniform块的内容是储存在一个缓冲对象中的,它实际上只是一块预留内存。因为这块内存并不会保存它具体保存的是什么类型的数据,我们还需要告诉OpenGL内存的哪一部分对应着着色器中的哪一个uniform变量。
通过在Uniform块定义之前添加
layout (std140)
语句,我们告诉OpenGL这个Uniform块使用的是std140布局。除此之外还可以选择两个布局,但它们都需要我们在填充缓冲之前先查询每个偏移量。我们已经见过
shared
布局了,剩下的一个布局是
packed
。当使用紧凑(Packed)布局时,是不能保证这个布局在每个程序中保持不变的(即非共享),因为它允许编译器去将uniform变量从Uniform块中优化掉,这在每个着色器中都可能是不同的。
为了将Uniform块绑定到一个特定的绑定点中,我们需要调用glUniformBlockBinding
函数,它的第一个参数是一个程序对象,之后是一个Uniform块索引和链接到的绑定点。Uniform块索引
(Uniform Block Index)是着色器中已定义Uniform块的位置值索引。这可以通过调用glGetUniformBlockIndex
来获取,它接受一个程序对象和Uniform块的名称。