2015-06-09 4 views
1

Я пытаюсь реализовать простую программу тесселяции, основанную на уроке this.Результат тесселяции мерцания - OpenGL/GLSL

Это мои шейдеры:

Vertex:

#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]; 
} 

Tessellation оценщик:

#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, в котором, когда уровень Тесс становится выше, то поверхность начинает мерцать. Однако до сих пор я не мог его решить.

Чтобы рисовать, я просто сделать:

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

Таковы мои результаты:

enter image description here enter image description here enter image description here

+0

Думаю, вы должны вывести только треугольник, а не треугольную полосу;) – GameDeveloper

ответ

0

Ну, проблема, казалось, с разрисованным вызова и как мой данные были структурированы. Правильно работает:

glBindVertexArray(_vao); 
    LoadUniformVariables(); 
    glPatchParameteri(GL_PATCH_VERTICES, 3); 
    glDrawElements(GL_PATCHES, _modelTriangulation.size(), GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 
Смежные вопросы