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.

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.

Contents

Overview

Tessellation options

The presence of an active TES in a program or program pipeline means that the tessellation primitive generation stage will occur, thus tessellating the given patch. 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 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).

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 ​ 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, 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:

patch in vec4 data;

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

invec3gl_TessCoord;inintgl_PatchVerticesIn;inintgl_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.

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:

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.

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