Search code examples
openglartifactstessellation

Artifacts on edges from tesselation control points


The first image shows the artifact up close: Close-up of clear color showing through

and the second shows it in context (see the lower right): artifacts in lower right side

The mesh is built from a grid of n x n vertices, which are triangulated to form the mesh. The vertices are separated by 1/n units. It looks like the gl clear color is showing through lines connecting the original vertices in the mesh (resulting in a grid). The lines along which the clear color is showing form quads. The number of vertices per tessellation patch is 3. Without tessellation, the artifact is not present. With tessellation enabled, the artifact appears but does not become more or less pronounced as a function of the tessellation factor. Has anyone seen artifacts like this as a result of tessellation? If so, what was their root cause, and are there any fixes? I am beginning to suspect some numeric bug, but scaling the terrain prior to tessellation does not impact the visibility of this artifact either.

As requested, here are the relevant pieces of code:

Tess control:

float GetTessLevel(float d1, float d2) {
    return 2;
}

void main() {
    TEworldPos[gl_InvocationID] = TCworldPos[gl_InvocationID];
    float EyeToVertexDistance0 = distance(cameraPos, TCworldPos[0]);
    float EyeToVertexDistance1 = distance(cameraPos, TCworldPos[1]);
    float EyeToVertexDistance2 = distance(cameraPos, TCworldPos[2]);

    // Calculate the tessellation levels
    gl_TessLevelOuter[0] = GetTessLevel(EyeToVertexDistance1, EyeToVertexDistance2);
    gl_TessLevelOuter[1] = GetTessLevel(EyeToVertexDistance2, EyeToVertexDistance0);
    gl_TessLevelOuter[2] = GetTessLevel(EyeToVertexDistance0, EyeToVertexDistance1);
    gl_TessLevelInner[0] = gl_TessLevelOuter[2];

Tess eval:

uniform mat4 viewProj;
void main() {
vec3 posFromBary = gl_TessCoord.x * TEworldPos[0] +
                       gl_TessCoord.y * TEworldPos[1] +
                       gl_TessCoord.z * TEworldPos[2];
gl_Position = viewProj * vec4(posFromBary, 1.0);
}

Solution

  • The problem was caused by what appears to be a GPU bug that is present on at least the Intel Iris Pro 1536 MB integrated GPU. Calling any GLSL noise functions in a pipeline that also tessellates at least one patch causes these artifacts. Noise by itself and tessellation by itself work as expected, but combined produce small artifacts along the edges of tessellated patches as illustrated in the above example. A temporary workaround is to use this open-source glsl simplex noise implementation (others in this repo probably work well, but I have only tested this one), which does not yield any artifacts when combined with tesselation.