How GLSL equal_spacing Subdivides Edges

This article provides an overview of the equal_spacing layout qualifier used in OpenGL Shading Language (GLSL) tessellation shaders. It covers the mathematical mechanics behind edge subdivision, how floating-point tessellation levels are clamped and rounded, how normalized parameter coordinates are assigned across segments, and the visual implications of selecting this spacing mode over fractional alternatives.

In GLSL, the primitive generation stage handles tessellation based on parameters declared in the Tessellation Evaluation Shader (TES). When you specify the equal_spacing input layout qualifier, you instruct the tessellation primitive generator to divide patch edges into segments of uniform length based on discrete integer subdivisions.

Floating-Point Clamping and Rounding

Tessellation control shaders output floating-point values for outer and inner tessellation levels (gl_TessLevelOuter and gl_TessLevelInner). When equal_spacing is active, the primitive generator processes these floating-point values using the following sequence:

  1. Clamping: The tessellation level is clamped to the hardware-supported range, bounded below by \(1.0\) and above by the implementation-dependent limit (gl_MaxTessGenLevel).
  2. Rounding Up: The clamped floating-point value is rounded up to the nearest integer: \[n = \lceil \text{clamp}(\text{level}, 1.0, \text{max\_level}) \rceil\]

Because the value is rounded up, any non-integer value strictly greater than an integer \(k\) immediately snaps to \(k + 1\). For example, an outer tessellation level of \(3.01\) will round up to \(4\), resulting in four segments.

Edge Subdivision Mechanics

Once the integer segment count \(n\) is resolved, the primitive generator divides the edge within the normalized parameter domain \([0.0, 1.0]\). The edge is split into exactly \(n\) segments of equal length:

  • Each segment has an identical parametric length of \(\Delta t = \frac{1.0}{n}\).
  • The vertices along the edge are generated at normalized parametric coordinates: \[t_i = \frac{i}{n} \quad \text{for } i \in \{0, 1, \dots, n\}\]

These coordinates are used to produce domain coordinates (gl_TessCoord), which the Tessellation Evaluation Shader uses to interpolate surface positions, normals, and texture coordinates.

Characteristics and Trade-offs

The defining property of equal_spacing is strict geometric uniformity across an individual edge. Unlike fractional_even_spacing or fractional_odd_spacing, which introduce two smaller segments that smoothly grow or shrink as tessellation levels change, equal_spacing guarantees that every single segment on a given edge has the exact same parametric size.

The trade-off of this uniform distribution is visual "popping." When tessellation levels vary dynamically—such as during continuous Level of Detail (LOD) transitions based on camera distance—the number of segments jumps abruptly at each integer boundary, causing noticeable vertex snapping. As a result, equal_spacing is best suited for static tessellation factors or applications where strictly uniform polygon sizing is preferred over smooth LOD blending.