1.Vertex shader variables:(顶点着色器有关)
1.1gl_PointSize(顶点大小)
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
gl_PointSize = gl_Position.z;
}
1.2 gl_VertexID(顶点ID)
此只读变量保存我们正在绘制的顶点的当前索引。可以用来对顶点进行操作。
2.Fragment shader variables(片元着色器特性)
2.1 gl_FragCoord(片元位置)
片元x坐标小于400的就显示不同颜色
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);
}
2.2 gl_FrontFacing(片元朝向)
gl_FrontFacing 变量告诉我们当前片段是正面还是背面的一部分。 例如,我们可以决定为所有背面输出不同的颜色。
#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);
}
2.3 gl_FragDepth(片元深度)
gl_FragCoord 允许我们读取屏幕空间坐标并获取当前片段的深度值,但它是只读变量。 GLSL 为我们提供了一个名为 gl_FragDepth 的输出变量,我们可以使用它来手动设置着色器中片段的深度值。
3.Interface blocks (接口块)
GLSL 为我们提供了一种叫做Interface blocks接口块的东西,它允许我们将变量组合在一起。 这种接口块的声明看起来很像结构声明,它现在基于块,输入块还是输出块使用 in 或 out 关键字进行声明。
#version 330 core
out vec4 FragColor;
in VS_OUT
{
vec2 TexCoords;
} fs_in;
uniform sampler2D texture;
void main()
{
FragColor = texture(texture, fs_in.TexCoords);
}
4.Uniform buffer objects(统一 缓冲 对象)
因为统一缓冲区对象是一个缓冲区,就像任何其他缓冲区一样,我们可以通过 glGenBuffers 创建一个缓冲区,将其绑定到 GL_UNIFORM_BUFFER 缓冲区目标并将所有相关的统一数据存储到缓冲区中。
相当于一个自定义的uniform
#version 330 core
layout (location = 0) in vec3 aPos;
//定义了一个uniform block layout,其内容会存储在一个特定的buffer中
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
uniform mat4 model;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
std140,使用一种特殊的内存排列方式和偏移量,提升效率
layout (std140) uniform ExampleBlock
{
// base alignment // aligned offset
float value; // 4 // 0
vec3 vector; // 16 // 16 (offset must be multiple of 16 so 4->16)
mat4 matrix; // 16 // 32 (column 0)
// 16 // 48 (column 1)
// 16 // 64 (column 2)
// 16 // 80 (column 3)
float values[3]; // 16 // 96 (values[0])
// 16 // 112 (values[1])
// 16 // 128 (values[2])
bool boolean; // 4 // 144
int integer; // 4 // 148
};