Tessellation Evaluation Shader

From OpenGL.org
Revision as of 19:09, 4 June 2013 by Alfonse (talk | contribs) (Primitive generation)

Jump to: navigation, search
Tessellation Evaluation Shader
Core in version 4.0
Core ARB extension ARB_tessellation_shader

The Tessellation Evaluation Shader (TES) is a Shader program written in GLSL that takes the results of a Tessellation operation and computes the interpolated positions and other attributes. These values are passed on to the next stage in the pipeline.


The Tessellation Evaluation Shader (TES) takes the abstract primitive generated by the tessellation primitive generation stage, as well as the actual vertex data for the entire patch, and generates a particular vertex from it. Each TES invocation generates a single vertex.

The number of times the TES is invoked can differ from implementation to implementation. It will be invoked at least once per tessellated vertex, but there is no guarantee that the TES won't be invoked multiple times for the same vertex.

Tessellation options

The presence of an active TES in a program or program pipeline is what governs whether or not the tessellation primitive generation stage will occur. Because of that, many options that control the way in which tessellation happens are specified in the TES itself.

The details of what these mean for the tessellation results are described in the section on the tessellation primitive generation. This section will only describe how to specify these options, not go into detail on exactly what they do.

All of these options are input layout qualifiers. They are specified using that syntax:

layout(param1​, param2​, ...) in;

They can be specified as separate statements or all in one. However, each particular type of parameter can only be specified once (you technically can specify them multiple times, but they all must be the same).

Abstract patch type

The TES defines the type of abstract patch that will be tessellated.

The possible values for this are:

  • isolines​: The patch is a rectangular block of parallel lines. The output is a series of lines.
  • triangles​: The patch is a triangle. The output is a series of triangles.
  • quads​: The patch is a quadrilateral. The output is a series of triangles.

The TES must provide this option.


The TES has options that control the spacing between tessellated vertices of the abstract patch. The possible values for this are:

  • equal_spacing​: There will be equal distances between vertices in the abstract patch.
  • fractional_even_spacing​: There will always be an even number of segments. All but two of the segments will have a fixed length. The remainder will go into two equal-length segments on symmetrical sides of the edge.
  • fractional_odd_spacing​: As even-spacing, but there will always be an odd number of segments.

This is optional. If the TES does not specify this parameter, equal_spacing​ will be used.

Primitive ordering

When emitting triangles, the Winding Order can be important for face culling. The process of tessellation takes place over an abstract patch, which is not in any particular coordinate system. It is the TES's responsibility to take abstract patch coordinates and generate real clip-space (or whatever your Geometry Shader expects) positions from them.

Therefore, maintaining the proper winding order for triangles is the job of the TES. To facilitate that, the TES has the ability to control the winding order of the primitive generator. This is done via the cw​ and ccw​ parameters.

Remember that this parameter only controls the winding of the abstract patch triangles. How this converts to the actual patch and clip-space output positions is up to the TES.

This is optional. If the TES does not specify this parameter, ccw​ will be used. Since lines don't have a winding order, this parameter is useless when using the isolines​ patch type.

Primitive generation

Normally, the kind of Primitive emitted by the primitive generator is defined by the abstract patch type. isolines​ will generate a series of line-strips, while the others will generate a series of triangles.

The TES can force the primitive generator to override this and simply generate a point primitive for each vertex in the tessellated patch. A Geometry Shader could modify these and build a quad from each point, or they could simply be drawn as points.

To do this, use the layout qualifier point_mode​. Obviously specifying this makes the ordering parameter unimportant.


The inputs for the TES are the per-vertex and per-patch outputs from the Tessellation Control Shader (or directly from the vertex shader if no TCS is active). Each TES invocation can access all of the outputs for a particular patch.

Per-vertex inputs from the TCS are arrays of values, indexed by a vertex index. Like TCS outputs, TES inputs can be declared without an explicit size:

in vec2 vertexTexCoord[];

The length of the array (vertexTexCoord.length()​) is the size of the input patch.

Per-patch outputs from the TCS can be taken as inputs in the TES using the patch​ keyword:

patch in vec4 data;

There are a number of built-in inputs for TES's:

in vec3 gl_TessCoord;
in int gl_PatchVerticesIn;
in int gl_PrimitiveID;

gl_TessCoord​ is the most important input. It is the location within the abstract patch for this particular vertex. Every input parameter other than this one will be identical for all TES invocations within a patch.

Which components of this vec3​ that have valid values depends on the abstract patch type. For isolines​ and quads​, on the XY components have valid values. For triangles​, all three components have valid values. All valid values are normalized floats (on the range [0, 1]).

gl_PatchVerticesIn​ is the vertex count for the patch being processed. This is either the output vertex count specified by the TCS, or the patch vertex size specified by glPatchParameter if no TCS is active. Attempts to index per-vertex inputs by a value greater than or equal to gl_PatchVerticesIn​ results in undefined behavior.

gl_PrimitiveID​ is the index of the current patch in the series of patches being processed.

Note: The Tessellation#Tessellation primitive generator will cull patches that have a zero for one of the outer tessellation levels. It is not clear from the OpenGL specification whether gl_PrimitiveID​ will be affected by this.

The TES also takes the built-in variables output by the TCS:

in gl_PerVertex
  vec4 gl_Position;
  float gl_PointSize;
  float gl_ClipDistance[];
} gl_in[gl_MaxPatchVertices];

Note that just because gl_in​ is defined to have gl_MaxPatchVertices​ entries does not mean that you can access beyond gl_PatchVerticesIn​ and get reasonable values.

The TES also has access to the tessellation levels via built-in inputs:

patch in float gl_TessLevelOuter[4];
patch in float gl_TessLevelInner[2];

Only the outer and inner levels actually used by the abstract patch are valid. For example, if this TES uses isolines​, only gl_TessLevelOuter[0]​ and gl_TessLevelOuter[1]​ will have valid values.


Each TES invocation outputs a separate vertex worth of data. Therefore, the TES outputs are scalars (you can have output arrays, but, they won't be treated specially the way per-vertex input arrays are).

Outputs from the TES can have interpolation qualifiers on them.

The only built-in outputs are the standard per-vertex block:

out gl_PerVertex {
  vec4 gl_Position;
  float gl_PointSize;
  float gl_ClipDistance[];

See also