layout(triangles) in GLSL Tessellation Shaders
Specifying layout(triangles) in a GLSL Tessellation
Evaluation Shader (TES) defines the tessellation domain as a triangle,
instructing the hardware tessellation primitive generator to subdivide
the abstract patch into a mesh of smaller triangles. This layout
configuration determines how the tessellation levels are interpreted,
activates a three-component barycentric coordinate system via
gl_TessCoord, and governs how the resulting vertices are
connected to form the final primitive geometry.
Domain and Primitive Generation
When layout(triangles) is declared, the tessellation
primitive generator operates on a triangular domain rather than a quad
or an isoline. The generator subdivides this triangular area into
smaller internal triangles based on the tessellation level factors
provided by the Tessellation Control Shader (TCS) or the OpenGL API. The
TES is then executed once for each vertex produced during this
subdivision process.
Barycentric Coordinates
(gl_TessCoord)
In a triangular domain, vertex positions are represented using
barycentric coordinates rather than Cartesian coordinates. Within the
shader, the built-in variable gl_TessCoord becomes a
three-component vector (u, v, w) with the following
properties:
- Each component ranges from
0.0to1.0. - The sum of the three components always equals one: \(u + v + w = 1.0\).
- Each component represents the relative weight of one of the three corners of the patch triangle.
Shaders typically use these coordinates to interpolate per-vertex attributes across the patch using weighted sums, such as:
vec3 position = gl_TessCoord.x * p0 +
gl_TessCoord.y * p1 +
gl_TessCoord.z * p2;Interpretation of Tessellation Levels
The layout(triangles) qualifier dictates which values of
the inner and outer tessellation levels are consumed by the hardware
primitive generator:
- Outer Tessellation Levels
(
gl_TessLevelOuter): Only the first three indices ([0],[1], and[2]) are used. Each value dictates how many segments the corresponding outer edge of the master triangle is divided into. - Inner Tessellation Levels
(
gl_TessLevelInner): Only the first index ([0]) is used. This value controls the subdivision density of the interior region of the triangle. The second inner level index ([1]) is completely ignored.
If any of the active outer levels are less than or equal to zero, the patch is discarded entirely, and no vertices or primitives are generated for that patch.
Primitive Assembly
By default, the vertices computed by the TES are assembled into
independent triangles following the winding order specified alongside
the layout (such as cw for clockwise or ccw
for counter-clockwise). If the point_mode layout qualifier
is also included, the primitive generator instead outputs individual
points at each evaluated vertex rather than connecting them into
triangles.