What Does gl_VertexID Provide in GLSL?
In OpenGL Shading Language (GLSL), the built-in variable
gl_VertexID provides the integer index of the specific
vertex currently being processed by the vertex shader. This built-in
input enables shaders to identify vertices sequentially, query
corresponding per-vertex data stored in storage buffers or textures, and
generate geometry procedurally without relying on traditional vertex
buffer attributes.
Understanding the Value of gl_VertexID
The value assigned to gl_VertexID depends directly on
the rendering command issued by the application:
- Non-Indexed Draw Calls (
glDrawArrays): When rendering sequentially,gl_VertexIDcorresponds to the zero-based offset of the vertex being drawn, starting from thefirstparameter and incrementing by one for each subsequent vertex up tofirst + count - 1. - Indexed Draw Calls (
glDrawElements): When rendering with an element array buffer,gl_VertexIDcontains the actual index read from the index buffer for that vertex. If base vertex rendering functions likeglDrawElementsBaseVertexare used,gl_VertexIDreflects the sum of the value in the index buffer and the specified base vertex offset.
Key Applications in Modern Rendering
Because gl_VertexID acts as a unique per-invocation key
for the vertex shader, it unlocks several efficient rendering
techniques.
Bufferless and Fullscreen Quad Rendering
A common optimization involves drawing full-screen passes or
post-processing effects without allocating or binding a dedicated Vertex
Buffer Object (VBO). By issuing a draw call for three vertices
(glDrawArrays(GL_TRIANGLES, 0, 3)), the vertex shader
computes clip-space coordinates mathematically from
gl_VertexID:
#version 330 core
void main() {
float x = float((gl_VertexID & 1) << 2) - 1.0;
float y = float((gl_VertexID & 2) << 1) - 1.0;
gl_Position = vec4(x, y, 0.0, 1.0);
}This constructs an oversized triangle covering the entire viewport without requiring any vertex attribute fetching overhead on the CPU or GPU.
Programmable Vertex Pulling
Instead of configuring rigid Vertex Array Objects (VAOs) with vertex
attribute pointers, developers can bind raw data using Shader Storage
Buffer Objects (SSBOs), Texture Buffer Objects (TBOs), or Uniform Buffer
Objects (UBOs). The vertex shader uses gl_VertexID directly
to index into these buffers and manually fetch positions, normals,
texture coordinates, or skinning weights.
Specifications and Constraints
- Stage Restriction:
gl_VertexIDis available only in the vertex shader stage. It is not accessible in fragment, geometry, or tessellation control shaders. - Data Type: It is represented as a signed 32-bit
integer (
int). - Read-Only: Shaders can read the value to calculate transformations and lookups, but modifying the variable is strictly prohibited.
- Modern Successors: In Vulkan GLSL and modern
cross-compilation environments (SPIR-V),
gl_VertexIndexis often preferred, which explicitly defines whether base vertex offsets are included compared to legacy OpenGL behavior.