Tessellation Shaders

Tessellation subdivides patches on the GPU for adaptive detail (terrain, curved surfaces, displacement).

25.1 Tessellation control shader (TCS)

#version 410 core
layout (vertices = 3) out;                           // output patch size
in vec3 vWorldPos[];
out vec3 tcWorldPos[];
uniform vec3 uCameraPos;

float lodFactor(vec3 p) {                            // distance-based level of detail
    float d = distance(uCameraPos, p);
    return clamp(64.0 / d, 1.0, 64.0);
}

void main() {
    tcWorldPos[gl_InvocationID] = vWorldPos[gl_InvocationID];
    if (gl_InvocationID == 0) {
        // Outer level i controls the edge opposite vertex i (use edge midpoints for crack-free tessellation)
        gl_TessLevelOuter[0] = lodFactor(0.5 * (vWorldPos[1] + vWorldPos[2]));
        gl_TessLevelOuter[1] = lodFactor(0.5 * (vWorldPos[2] + vWorldPos[0]));
        gl_TessLevelOuter[2] = lodFactor(0.5 * (vWorldPos[0] + vWorldPos[1]));
        gl_TessLevelInner[0] = gl_TessLevelOuter[2];
    }
}

25.2 Tessellation evaluation shader (TES)

Host: glPatchParameteri(GL_PATCH_VERTICES, 3); glDrawArrays(GL_PATCHES, 0, n);. Applications: terrain LOD, PN triangles, Bézier/subdivision surfaces, displacement-mapped detail, ocean surfaces.

#version 410 core
layout (triangles, equal_spacing, ccw) in;           // quads/isolines; fractional_even/odd_spacing
in vec3 tcWorldPos[];
uniform mat4 uViewProj;
uniform sampler2D uHeightMap;
uniform float uHeightScale;

void main() {
    vec3 p = gl_TessCoord.x * tcWorldPos[0] + gl_TessCoord.y * tcWorldPos[1] + gl_TessCoord.z * tcWorldPos[2];
    p.y += textureLod(uHeightMap, p.xz * 0.01, 0.0).r * uHeightScale;   // displacement mapping
    gl_Position = uViewProj * vec4(p, 1.0);
}