What Does the Vertex Shader Do in OpenGL?

The vertex shader is the first programmable stage in the modern OpenGL graphics pipeline, responsible for processing individual vertices one at a time. Its primary job is to transform 3D model coordinates into clip space, calculate per-vertex attributes such as normals, texture coordinates, and colors, and pass processed data downstream to later pipeline stages like the rasterizer and fragment shader.

Coordinate Space Transformations

The most critical task performed by a vertex shader is transforming geometry through several coordinate spaces. Raw vertex data typically enters the shader defined in local object space (or model space). The vertex shader applies transformation matrices to position the geometry within the 3D scene and prepare it for rendering:

The culmination of this mathematical transformation is assigned directly to the built-in output variable gl_Position, which defines where the vertex sits within normalized device coordinates (NDC) after prospective division.

Attribute Passthrough and Interpolation Setup

In addition to positional data, meshes contain several per-vertex attributes that downstream pipeline stages require. The vertex shader accepts these inputs—often declared using the in qualifier—processes or transforms them, and writes them to output variables (out qualifier):

Once output from the vertex shader, these attributes are automatically interpolated across the primitive surface by fixed-function hardware during rasterization.

Procedural Vertex Animation and Deformation

Because vertex shaders run independently per vertex across thousands of GPU cores, they are well-suited for high-performance procedural animation and deformation. Instead of re-uploading modified mesh buffers from the CPU every frame, the vertex shader can modify vertex coordinates dynamically on the GPU:

Lighting and Shading Calculations

While per-fragment lighting (such as the standard Blinn-Phong model evaluated in fragment shaders) provides superior visual fidelity, vertex shaders can perform per-vertex lighting computations (historically referred to as Gouraud shading). Computing ambient, diffuse, or specular lighting at the vertex level reduces GPU load significantly because vertex counts are almost always lower than pixel counts. The resulting color values are then smoothly interpolated across the face of the rendered polygon.

Point Sprite Sizing

When rendering GL_POINTS, the vertex shader is responsible for dictating the screen-space footprint of each point primitive. By assigning a floating-point value to the built-in variable gl_PointSize (with GL_PROGRAM_POINT_SIZE enabled on the context), the vertex shader dynamically controls point dimensions based on distance to the camera, particle lifetimes, or custom visual parameters.