简体   繁体   English

绘制线框时的OpenGL闪烁片段

[英]OpenGL Flickering Fragments when Drawing Wireframe

I've been following along with the OpenGL 4 Shading Language cookbook and have gotten a teapot rendering with bezier surfaces. 我一直在关注OpenGL 4阴影语言食谱,并获得了带有贝塞尔曲面的茶壶渲染。 The next step I'm attempting is to draw a wireframe over the surfaces using a geometry shader. 我要尝试的下一步是使用几何着色器在表面上绘制线框。 The directions can be found here on pages 228-230. 该方向可以发现这里的228-230页。 Following the code that is given, I've gotten the wireframe to display, however, I also have multiple fragments that flicker different shades of my material color. 按照给出的代码,我已经显示了线框,但是,我也有多个片段,它们闪烁了我的材质颜色的不同阴影。

An image of this can be seen 可以看到这样的图像 这里

I have narrowed down the possible issues and have discovered that for some reason, when I perform my triangle height calculations, I am getting variable side lengths for my calculations, as if I hard code the values in the edge distance for each vertex of the triangle within the geometry shader, the teapot no longer flickers, but neither does a wireframe display. 我缩小了可能的问题,并发现由于某种原因,当我执行三角形高度计算时,我得到的边长是可变的,就像我对三角形的每个顶点的边距中的值进行硬编码一样在几何着色器中,茶壶不再闪烁,但线框显示也不闪烁。 (variables ha, hb, hc in the geo shader below) (下面的地理着色器中的变量ha,hb,hc)

I was wondering if anyone has run into this issue before or are aware of a workaround. 我想知道是否有人之前遇到过此问题或知道解决方法。

Below are some sections of my code: 以下是我的代码的某些部分:

Geometry Shader: 几何着色器:

/*
 *   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;
}

I ended up stumbling across the solution to my issue. 我最终在解决问题的方法中绊了脚。 In the geometry shader, I was passing the halfway vector and the light vector after ending the primitive, as such, the values of these vectors was never being correctly sent to the fragment shader. 在几何着色器中,我在结束图元之后传递了中途向量和光照向量,因此,这些向量的值从未正确发送到片段着色器。 Since no data was given to the fragment shader, garbage values were used and the Phong shading model used random values to compute the fragment color. 由于未向片段着色器提供任何数据,因此使用了垃圾值,而Phong着色模型使用随机值来计算片段颜色。 Moving the two lines after EndPrimative() to the top of the main function in the geometry shader resolved the issue. 将EndPrimative()之后的两行移动到几何着色器中主函数的顶部即可解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM