一.GLSL的内建变量
在着色器中,需要当前着色器以外地方的数据的话,必须把数据传进来。之前我们是通过uniform类型和采样器来完成的。之外,GLSL还支持另外几个以gl
为前缀的变量,提供更多读写数据的方式,比如说顶点着色器的gl_Position
和片段着色器的gl_FragCoord
1.顶点着色器变量
- gl_PointSize
当我们选取的一个图元是GL_POINT
的话,每一个顶点都是一个图元,都会被渲染为一个点。这时我们可以通过OpenGL的glPointSize
函数来设置渲染出来的点的大小,也可以在顶点着色器中修改这个值。
在顶点着色器中修改点大小的功能默认是禁用的,如若使用,则需要启用它
glEnable(GL_PROGRAM_POINT_SIZE);
同时我们可以将点的大小设置为裁剪空间的z值,也就是顶点距观察者的距离,点的大小会随着据观察者顶点距离的变远而增大。最后得到一个类似粒子的效果。
- gl_VertexID
整型变量gl_VertexID储存了正在绘制顶点的当前ID。
2.片段着色器变量
- gl_FragCoord(输入变量)
之前我们一直利用这个变量的z
分量来获取片段的深度值,然而,我们也可以利用它的x和y分量来实现一些效果。
gl_FragCoord
的x和y分量是窗口空间的坐标,原点为窗口的左下角,我们可以利用对x,y的控制得到一些想要的效果。
如下:我们可以得到一个两种颜色划分的渲染结果图。
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
可以判定当前片段是属于正向面的一部分还是背向面的一部分。如果是正向面的一部分,那么其值为true
,如果是背向面的一部分,那么其值为false
。这样我们就可以创建一个立方体,在内部和外部使用不同的纹理。
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D frontTexture;
uniform sampler2D backTexture;
void main()
{
if(gl_FrontFacing)
FragColor = texture(frontTexture, TexCoords);
else
FragColor = texture(backTexture, TexCoords);
}
如下,从箱子内部观察时: