GLSL Tessellation Control Shader Patch Out Variables
This article provides an overview of the role and mechanics of
patch out variables within OpenGL Shading Language (GLSL)
Tessellation Control Shaders (TCS). It clarifies how the
patch qualifier manages data across geometric primitives,
highlights the technical distinction between per-control-point and
per-patch attributes, and explains how this data is routed efficiently
to the Tessellation Evaluation Shader (TES).
In the OpenGL tessellation pipeline, the Tessellation Control Shader
(TCS) processes an input patch of vertices and emits an output patch
containing a specified number of control points. While standard output
variables in a TCS are structured as arrays corresponding to each output
control point, the patch out qualifier designates
attributes that belong to the patch as an entire entity rather than to
individual control points.
Distinguishing Per-Control-Point from Per-Patch Data
Standard TCS output variables represent per-vertex control point data
(such as positions, normals, or UV coordinates). These outputs are
implicitly or explicitly declared as arrays sized by
gl_OutputVerticesDeclaration:
layout(vertices = 4) out;
out vec3 vPosition[]; // Indexed per control point via gl_InvocationIDIn contrast, declaring an output with the patch
qualifier removes the association with individual control points. A
patch out variable represents patch-level metadata derived
from the control points:
patch out vec4 vPatchColor;
patch out float vSubdivisionBias;Purpose and
Function of patch out Variables
Elimination of Redundant Storage and Bandwidth: If a property applies to the entire primitive—such as dynamic level-of-detail flags, patch-level bounding volumes, or material identifiers derived from control point positions—storing it in standard per-vertex outputs duplicates the value across every control point. Using
patch outensures the value is stored and transferred only once per patch, reducing memory footprint and cross-stage bandwidth.Facilitating Uniform Access in the Evaluation Shader: In the Tessellation Evaluation Shader (TES), control point outputs must be sampled using the patch vertex indices (e.g.,
gl_in[i].vPosition). Variables declared aspatch outin the TCS are matched withpatch indeclarations in the TES. This allows the TES to access patch-wide constants directly, without indexing by vertex ID, ensuring clear separation between interpolative vertex data and primitive-wide constants.Writing Rules and Invocation Control: Because a TCS runs once per output control point (
gl_InvocationID), all invocations within the same workgroup share the patch-level outputs. Writing to apatch outvariable requires careful synchronization. It is standard practice to restrict writes to a single invocation to prevent race conditions:if (gl_InvocationID == 0) { vPatchColor = calculatePatchMetadata(); }
By distinguishing per-patch state from control point geometry,
patch out variables streamline how data is gathered from
incoming control points and transmitted downstream, optimizing execution
and maintainability across the tessellation stages.