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).

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 [[Type Qualifier (GLSL)#Interpolation qualifiers|interpolation qualifiers]] on them.

+

User-defined outputs from the TES can have [[Type Qualifier (GLSL)#Interpolation qualifiers|interpolation qualifiers]] on them.

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 per-vertex data from them. These values are passed on to the next stage in the pipeline.

The number of times the TES is invoked can differ from implementation to implementation. It will be invoked at least once per tessellated vertex in the abstract patch, but there is no guarantee that the TES won't be invoked multiple times for the same vertex. However, like the Vertex Shader, the TES is expected to output the same value for the same vertex in the abstract patch.

Contents

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 particular form of tessellation 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

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.

Spacing

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.

Inputs

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:

the location within the tessellated 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​, only 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​

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​

the index of the current patch in the series of patches being processed for this draw call. Primitive Restart, if used, has no effect on the primitive ID.

Note: The tessellation primitive generator will cull patches that have a zero for one of the active outer tessellation levels. The intent of the specification seems to be that gl_PrimitiveID​ will still be incremented for culled patches. So the primitive ID for the TES is equivalent to the ID for the TCS invocations that generated that patch. But this is not entirely clear from the spec itself.

The TES also has access to the tessellation levels provided for the patch by the TCS or by OpenGL:

patchinfloatgl_TessLevelOuter[4];patchinfloatgl_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.

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

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.

Outputs

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).

gl_PerVertex​ defines an interface block for outputs. The block is defined without an instance name, so that prefixing the names is not required.

These variables only take on the meanings below if this shader is the last active Vertex Processing stage, and if rasterization is still active (ie: GL_RASTERIZER_DISCARD is not enabled). The text below explains how the Vertex Post-Processing system uses the variables. These variables may not be redeclared with interpolation qualifiers.

gl_Position​

the clip-space output position of the current vertex.

gl_PointSize​

the pixel width/height of the point being rasterized. It only has a meaning when rendering point primitives, which in a TES requires using the point_mode​​ input layout qualifier.

gl_ClipDistance​

allows the shader to set the distance from the vertex to each User-Defined Clip Plane. A positive distance means that the vertex is inside/behind the clip plane, and a negative distance means it is outside/in front of the clip plane. Each element in the array is one clip plane. In order to use this variable, the user must manually redeclare it with an explicit size.