What Does the OpenGL Tessellation Control Shader Do?

The OpenGL tessellation control shader serves as the decision-making stage of the programmable tessellation pipeline, determining how coarsely or finely geometric patches are subdivided before geometry is generated. Operating directly after the vertex shader, its primary responsibilities are calculating inner and outer tessellation levels, transforming or passing through input patch control points, and providing opportunities to cull non-visible geometry early in the pipeline.

Determining Subdivision Levels

The most critical function of the tessellation control shader (TCS) is calculating the tessellation levels that govern the fixed-function primitive generation stage. These levels are specified through two built-in output float arrays: gl_TessLevelOuter and gl_TessLevelInner.

The primitive generator reads these arrays to decide how many segments to produce along the perimeter and across the interior of the patch:

Because the TCS computes these levels dynamically on a per-patch basis, developers can implement adaptive level of detail (LOD). Geometry close to the camera can receive high tessellation factors for crisp detail, while distant geometry receives lower factors to preserve GPU fill rate and vertex throughput.

Managing Patch Control Points

Geometry enters the tessellation pipeline as raw patches rather than traditional points, lines, or triangles. The vertex shader processes each incoming control point individually, after which the TCS groups them into a complete patch.

Using the layout(vertices = N) out; qualifier, the TCS defines the exact number of output control points produced per patch, which does not have to match the input count. For example, a shader can take four input points representing a quad and generate sixteen control points defining a bicubic Bézier patch.

Within the shader, multiple invocations run in parallel—typically one per output control point—indexed by the built-in variable gl_InvocationID. Each invocation calculates or forwards attributes such as position, normals, and texture coordinates via the gl_out array, passing them along to the subsequent tessellation evaluation shader (TES).

Frustum Culling and Optimization

Beyond setting subdivision rates, the TCS acts as an efficient culling stage. If a patch falls entirely outside the view frustum or faces away from the camera, the shader can set its outer tessellation levels to zero (or negative values).

When the fixed-function primitive generator encounters an outer level of zero, it discards the entire patch immediately. This prevents the GPU from generating redundant primitives and avoids running downstream evaluation, geometry, or fragment shaders on invisible geometry, significantly lowering computational overhead.

Placement in the Modern Rendering Pipeline

Understanding the TCS requires recognizing its place in the OpenGL execution flow:

  1. Vertex Shader: Transforms individual source vertices.
  2. Tessellation Control Shader (TCS): Evaluates the whole patch, produces output control points, and assigns subdivision levels.
  3. Primitive Generator: Fixed-function hardware that creates a canonical subdivision mesh based on the assigned levels.
  4. Tessellation Evaluation Shader (TES): Interpolates attributes across the newly created points using the control points provided by the TCS.

By isolating the calculation of subdivision metrics from the actual interpolation of vertex positions, the OpenGL architecture gives developers fine-grained control over dynamic mesh complexity without stalling the hardware primitive assembler.