绘制线框时OpenGL闪烁碎片

时间:2018-02-22 17:51:30

标签: c++ opengl graphics glsl

我一直在跟随OpenGL 4着色语言烹饪书,并获得了带有贝塞尔曲面的茶壶渲染。我尝试的下一步是使用几何着色器在曲面上绘制线框。可在第228-230页上找到here的说明。根据给出的代码,我已经显示了线框,但是,我还有多个片段可以闪烁不同的材质颜色。

可以看到here

的图像

我已经缩小了可能的问题,并且发现由于某种原因,当我执行三角高度计算时,我的计算得到可变边长,好像我在每个顶点的边距中硬编码值在几何着色器中的三角形中,茶壶不再闪烁,但线框显示也没有。 (下面的地理着色器中的变量ha,hb,hc)

我想知道是否有人之前遇到过这个问题或者意识到解决方法。

以下是我的代码的一些部分:

几何着色器:

/*
 *   Geometry Shader
 *
 *   CSCI 499, Computer Graphics, Colorado School of Mines
 */

#version 410 core

layout( triangles ) in;

layout( triangle_strip, max_vertices = 3 ) out;

out vec3 GNormal;
out vec3 GPosition;
out vec3 ghalfwayVec;
out vec3 GLight;

noperspective out vec3 GEdgeDistance;

in vec4 TENormal[];
in vec4 TEPosition[];
in vec3 halfwayVec[];
in vec3 TELight[];

uniform mat4 ViewportMatrix;

void main() {
    // Transform each vertex into viewport space
    vec3 p0 = vec3(ViewportMatrix * (gl_in[0].gl_Position / gl_in[0].gl_Position.w));
    vec3 p1 = vec3(ViewportMatrix * (gl_in[1].gl_Position / gl_in[1].gl_Position.w));
    vec3 p2 = vec3(ViewportMatrix * (gl_in[2].gl_Position / gl_in[2].gl_Position.w));

    // Find the altitudes (ha, hb and hc)
    float a = length(p1 - p2);
    float b = length(p2 - p0);
    float c = length(p1 - p0);
    float alpha = acos( (b*b + c*c - a*a) / (2.0*b*c) );
    float beta = acos( (a*a + c*c - b*b) / (2.0*a*c) );
    float ha = abs( c * sin( beta ) );
    float hb = abs( c * sin( alpha ) );
    float hc = abs( b * sin( alpha ) );

    // Send the triangle along with the edge distances

    GEdgeDistance = vec3( ha, 0, 0 );
    GNormal = vec3(TENormal[0]);
    GPosition = vec3(TEPosition[0]);
    gl_Position = gl_in[0].gl_Position;
    EmitVertex();

    GEdgeDistance = vec3( 0, hb, 0 );
    GNormal = vec3(TENormal[1]);
    GPosition = vec3(TEPosition[1]);
    gl_Position = gl_in[1].gl_Position;
    EmitVertex();

    GEdgeDistance = vec3( 0, 0, hc );
    GNormal = vec3(TENormal[2]);
    GPosition = vec3(TEPosition[2]);
    gl_Position = gl_in[2].gl_Position;
    EmitVertex();

    EndPrimitive();

    ghalfwayVec = halfwayVec[0];
    GLight = TELight[0];
}

Fragment Shader:

/*
 *   Fragment Shader
 *
 *   CSCI 441, Computer Graphics, Colorado School of Mines
 */

#version 410 core

in vec3 ghalfwayVec;
in vec3 GLight;
in vec3 GNormal;
in vec3 GPosition;
noperspective in vec3 GEdgeDistance;

layout( location = 0 ) out vec4 FragColor;

uniform vec3 mDiff, mAmb, mSpec;
uniform float shininess;

uniform light {
    vec3 lAmb, lDiff, lSpec, lPos;
};

// The mesh line settings
uniform struct LineInfo {
    float Width;
    vec4 Color;
} Line;

vec3 phongModel( vec3 pos, vec3 norm ) {
    vec3 lightVec2 = normalize(GLight);
    vec3 normalVec2 = -normalize(GNormal);
    vec3 halfwayVec2 = normalize(ghalfwayVec);

    float sDotN = max( dot(lightVec2, normalVec2), 0.0 );
    vec4 diffuse = vec4(lDiff * mDiff * sDotN, 1);

    vec4 specular = vec4(0.0);
    if( sDotN > 0.0 ) {
        specular = vec4(lSpec * mSpec * pow( max( 0.0, dot( halfwayVec2, normalVec2 ) ), shininess ),1);
    }

    vec4 ambient = vec4(lAmb * mAmb, 1);

    vec3 fragColorOut = vec3(diffuse + specular + ambient);
    // vec4 fragColorOut = vec4(0.0,0.0,0.0,0.0);
    return fragColorOut;
}


void main() {
    //     /*****************************************/
    //     /******* Final Color Calculations ********/
    //     /*****************************************/

    // The shaded surface color.
    vec4 color=vec4(phongModel(GPosition, GNormal), 1.0);

    // Find the smallest distance
    float d = min( GEdgeDistance.x, GEdgeDistance.y );
    d = min( d, GEdgeDistance.z );

    // Determine the mix factor with the line color
    float mixVal = smoothstep( Line.Width - 1, Line.Width + 1, d );
    // float mixVal = 1;

    // Mix the surface color with the line color
    FragColor = vec4(mix( Line.Color, color, mixVal ));
    FragColor.a = 1;
}

1 个答案:

答案 0 :(得分:0)

我最终绊倒了我的问题的解决方案。在几何着色器中,我在结束基元之后传递了中间向量和光向量,因此,这些向量的值从未被正确地发送到片段着色器。由于没有给片段着色器提供数据,因此使用了垃圾值,Phong着色模型使用随机值来计算片段颜色。将EndPrimative()之后的两行移动到几何着色器中主函数的顶部解决了该问题。