21.3. Tessellator Spacing

Each of the tessellation levels is used to determine the number and spacing of segments used to subdivide a corresponding edge. The method used to derive the number and spacing of segments is specified by an OpExecutionMode in the tessellation control or tessellation evaluation shader using one of the identifiers SpacingEqual, SpacingFractionalEven, or SpacingFractionalOdd.

If SpacingEqual is used, the floating-point tessellation level is first clamped to $[1,\mathit{maxLevel}]$ , where $\mathit{maxLevel}$ is the implementation-dependent maximum tessellation level (VkPhysicalDeviceLimits::maxTessellationGenerationLevel). The result is rounded up to the nearest integer $n$ , and the corresponding edge is divided into $n$ segments of equal length in (u,v) space.

If SpacingFractionalEven is used, the tessellation level is first clamped to $[2,\mathit{maxLevel}]$ and then rounded up to the nearest even integer $n$ . If SpacingFractionalOdd is used, the tessellation level is clamped to $[1,\mathit{maxLevel}-1]$ and then rounded up to the nearest odd integer $n$ . If $n$ is one, the edge will not be subdivided. Otherwise, the corresponding edge will be divided into $n-2$ segments of equal length, and two additional segments of equal length that are typically shorter than the other segments. The length of the two additional segments relative to the others will decrease monotonically with $n-f$ , where $f$ is the clamped floating-point tessellation level. When $n-f$ is zero, the additional segments will have equal length to the other segments. As $n-f$ approaches 2.0, the relative length of the additional segments approaches zero. The two additional segments must be placed symmetrically on opposite sides of the subdivided edge. The relative location of these two segments is implementation-dependent, but must be identical for any pair of subdivided edges with identical values of $f$ .

When the tessellator produces triangles (in the Triangles or Quads modes), the orientation of all triangles is specified with an OpExecutionMode of VertexOrderCw or VertexOrderCcw in the tessellation control or tessellation evaluation shaders. If the order is VertexOrderCw, the vertices of all generated triangles will have clockwise ordering in (u,v) or (u,v,w) space. If the order is VertexOrderCcw, the vertices will have counter-clockwise ordering.

The vertices of a triangle have counter-clockwise ordering if

\[ a = u_0 v_1 - u_1 v_0 + u_1 v_2 - u_2 v_1 + u_2 v_0 - u_0 v_2 \]

is positive, and clockwise ordering if $a$ is negative. $u_i$ and $v_i$ are the $u$ and $v$ coordinates in normalized parameter space of the $i$ th vertex of the triangle.

[Note]Note

The value $a$ is proportional (with a positive factor) to the signed area of the triangle.

In Triangles mode, even though the vertex coordinates have a $w$ value, it does not participate directly in the computation of $a$ , being an affine combination of $u$ and $v$ .

For all primitive modes, the tessellator is capable of generating points instead of lines or triangles. If the tessellation control or tessellation evaluation shader specifies the OpExecutionMode PointMode, the primitive generator will generate one point for each distinct vertex produced by tessellation. Otherwise, the tessellator will produce a collection of line segments or triangles according to the primitive mode. When tessellating triangles or quads in point mode with fractional odd spacing, the tessellator may produce interior vertices that are positioned on the edge of the patch if an inner tessellation level is less than or equal to one. Such vertices are considered distinct from vertices produced by subdividing the outer edge of the patch, even if there are pairs of vertices with identical coordinates.

The points, lines, or triangles produced by the tessellator are passed to subsequent pipeline stages in an implementation-dependent order.