我正在尝试基于this教程实现一个简单的细分程序。

这些是我的着色器:

顶点:

#version 410 core

uniform mat4 mvMatrix;
uniform mat3 normalMatrix;

in vec4 vPosition;
in vec3 vNormal;

// Input for the tesselation control shader
smooth out vec3 vEyePos_TCS;
smooth out vec3 vNorm_TCS;

void main()
{
    vNorm_TCS = normalize(normalMatrix * vNormal);
    vEyePos_TCS = vec3(mvMatrix * vPosition);
}


镶嵌控制:

#version 410 core

// Define the number of CPs in the output patch
layout (vertices = 3) out;

uniform vec3 eyePos;

in vec3 vEyePos_TCS[];
in vec3 vNorm_TCS[];

// Output for the tesselation evaluation shader
out vec3 vEyePos_TES[];
out vec3 vNorm_TES[];

float GetTessLevel(float dist0, float dist1)
{
    float avgDist = (dist0 + dist1) / 2.0;

    if (avgDist <= 10.0)
        return 5.0;
    else if (avgDist <= 15.0)
        return 3.0;
    else
        return 1.0;
}

void main()
{
    // Set the control points of the output patch
    vEyePos_TES[gl_InvocationID] = vEyePos_TCS[gl_InvocationID];
    vNorm_TES[gl_InvocationID] = vNorm_TCS[gl_InvocationID];

    // Calculate the distance from the camera to the three control points
    float dist0 = distance(eyePos, vEyePos_TES[0]);
    float dist1 = distance(eyePos, vEyePos_TES[1]);
    float dist2 = distance(eyePos, vEyePos_TES[2]);

    // Calculate the tesselation levels
    gl_TessLevelOuter[0] = GetTessLevel(dist1, dist2);
    gl_TessLevelOuter[1] = GetTessLevel(dist2, dist0);
    gl_TessLevelOuter[2] = GetTessLevel(dist0, dist1);

    gl_TessLevelInner[0] = gl_TessLevelOuter[2];
}


镶嵌评估器:

#version 410 core

layout(triangles, equal_spacing, ccw) in;

uniform mat4 pMatrix;

in vec3 vEyePos_TES[];
in vec3 vNorm_TES[];

// Input for the geometry shader
out vec3 vEyePos_GS;
out vec3 vNorm_GS;

vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2)
{
    return vec3(gl_TessCoord.x) * v0 + vec3(gl_TessCoord.y) * v1 + vec3(gl_TessCoord.z) * v2;
}

void main()
{
    // Interpolate the attributes of the output vertex using the barycentric coordinates
    vNorm_GS = interpolate3D(vNorm_TES[0], vNorm_TES[1], vNorm_TES[2]);
    vEyePos_GS = interpolate3D(vEyePos_TES[0], vEyePos_TES[1], vEyePos_TES[2]);

    gl_Position = pMatrix * vec4(vEyePos_GS, 1.0);
}


几何:

#version 410

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

in vec3 vEyePos_GS[];
in vec3 vNorm_GS[];

out vec3 vEyePos_FS;
out vec3 vNorm_FS;
out vec3 gTriDistance;

void main()
{
    vNorm_FS = vNorm_GS[0];
    vEyePos_FS = vEyePos_GS[0];
    gTriDistance = vec3(1, 0, 0);
    gl_Position = gl_in[0].gl_Position;
    EmitVertex();

    vNorm_FS = vNorm_GS[1];
    vEyePos_FS = vEyePos_GS[1];
    gTriDistance = vec3(0, 1, 0);
    gl_Position = gl_in[1].gl_Position;
    EmitVertex();

    vNorm_FS = vNorm_GS[2];
    vEyePos_FS = vEyePos_GS[2];
    gTriDistance = vec3(0, 0, 1);
    gl_Position = gl_in[2].gl_Position;
    EmitVertex();

    EndPrimitive();
}


分段:

#version 410 core

uniform vec3 vLightPosition;
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;

in vec3 vEyePos_FS;
in vec3 vNorm_FS;
in vec3 gTriDistance;

out vec4 fragColor;

float amplify(float d, float scale, float offset)
{
    d = scale * d + offset;
    d = clamp(d, 0, 1);
    d = 1 - exp2(-2 * d * d);
    return d;
}

void main()
{
    vec3 L = normalize(vLightPosition - vEyePos_FS);
    vec3 E = normalize(-vEyePos_FS);
    vec3 R = normalize(-reflect(L, vNorm_FS));

   //calculate Ambient Term:
   vec4 Iamb = ambientColor;

   //calculate Diffuse Term:
   vec4 Idiff = diffuseColor * max(dot(vNorm_FS, L), 0.0);
   Idiff = clamp(Idiff, 0.0, 1.0);

   // calculate Specular Term:
   vec4 Ispec = specularColor * pow(max(dot(R, E), 0.0), 0.3 * 128.0);
   Ispec = clamp(Ispec, 0.0, 1.0);

   fragColor = Iamb + Idiff + Ispec;

   float d1 = min( min( gTriDistance.x, gTriDistance.y ), gTriDistance.z );
   fragColor = fragColor * amplify( d1, 60, -0.5 ) ;
};


我面临的问题似乎与to this one类似,其中当TESS级别变高时,表面开始闪烁。但是,到目前为止我还无法解决。

绘制,我简单地做:

glBindVertexArray(_vao);
LoadUniformVariables();
glPatchParameteri(GL_PATCH_VERTICES, 3);
glDrawArrays(GL_PATCHES, 0, _modelCoordinates.size());
glBindVertexArray(0);


这些是我的结果:

最佳答案

好吧,问题似乎出在我的绘图电话以及如何构造我的数据上。以下工作正常:

    glBindVertexArray(_vao);
    LoadUniformVariables();
    glPatchParameteri(GL_PATCH_VERTICES, 3);
    glDrawElements(GL_PATCHES, _modelTriangulation.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

10-08 11:30