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_VertexID corresponds to the zero-based offset of the vertex being drawn, starting from the first parameter and incrementing by one for each subsequent vertex up to first + count - 1.
  • Indexed Draw Calls (glDrawElements): When rendering with an element array buffer, gl_VertexID contains the actual index read from the index buffer for that vertex. If base vertex rendering functions like glDrawElementsBaseVertex are used, gl_VertexID reflects 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_VertexID is 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_VertexIndex is often preferred, which explicitly defines whether base vertex offsets are included compared to legacy OpenGL behavior.