Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: help with flat shading

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    20

    help with flat shading

    I would like use flat shading with vbo. I wish that each face has the same color as with the old glShadeModel(GL_FLAT).
    Someone have some piece of shader to do it?

    I tried this fragment shader but doesn't work correctly... I saw some sort of color interpolation on the faces.
    I tried to use it:

    bool resultVertex=p.attachVertexShader(STRINGIFY(
    varying vec3 ec_pos;
    void main()
    {
    ec_pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    gl_Position = ftransform();
    }
    ));

    bool resultFragment=p.attachFragmentShader(STRINGIFY(
    varying vec3 ec_pos;

    void main()
    {
    vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos)));
    vec3 light_dir=vec3(0.0,0.85,0.85);
    float d=dot(light_dir,ec_normal);
    gl_FragColor = vec4(d,d,d,0);

    }));

    Thanks.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Mar 2009
    Location
    Karachi, Pakistan
    Posts
    810
    For flat appearance, I would suggest computing the color per-vertex (use flat qualifier for OpenGL v3.3 and above) as follows rather than per-fragment as you are doing currently. You will still get some interpolated color due to rasterizer interpolation but it should be flatter looking as compared to per-fragment result.
    Code :
    //vertex shader
    varying vec4 color;
    void main() {
       vec3 ec_pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
       vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos)));
       vec3 light_dir=vec3(0.0,0.85,0.85);
       float d=dot(light_dir,ec_normal);
       color = vec4(d,d,d,0);
       gl_Position = ftransform();
    }
     
    //fragment shader
    varying vec4 color;
    void main() {
       gl_FragColor = color;
    }
    Regards,
    Mobeen

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,962
    Quote Originally Posted by ale211734 View Post
    I tried this fragment shader but doesn't work correctly... I saw some sort of color interpolation on the faces.
    I tried that approach and it worked fine, with no trace of variation.

    Although dFdx/dFdy are only approximate, I can't conceive of any way that the results could be other than in the plane of the primitive. The magnitudes could vary, but the normalize() takes care of that.

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,962
    Quote Originally Posted by mobeen View Post
    For flat appearance, I would suggest computing the color per-vertex (use flat qualifier for OpenGL v3.3 and above) as follows rather than per-fragment as you are doing currently.
    You can't realistically compute the face normal in the vertex shader, as a vertex shader knows nothing of the other vertices forming the face. You can do it in a geometry shader.

    Quote Originally Posted by mobeen View Post
    You will still get some interpolated color due to rasterizer interpolation
    A "flat"-qualified variable isn't interpolated.

    Quote Originally Posted by mobeen View Post
    Code :
    //vertex shader
    varying vec4 color;
    void main() {
       vec3 ec_pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
       vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos)));
    dFdx and dFdy can only be used in a fragment shader.

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2015
    Posts
    20
    Quote Originally Posted by GClements View Post
    You can't realistically compute the face normal in the vertex shader, as a vertex shader knows nothing of the other vertices forming the face. You can do it in a geometry shader.


    A "flat"-qualified variable isn't interpolated.


    dFdx and dFdy can only be used in a fragment shader.

    Hello,
    how can i calculate face normale with geometric shader and pass it to fragment shader?
    can someone can help me with code?

  6. #6
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,962
    Quote Originally Posted by ale211734 View Post
    how can i calculate face normale with geometric shader and pass it to fragment shader?
    Code :
    layout(triangles) in;
    layout(triangle_strip, max_vertices=3) out;
     
    out vec3 normal;
     
    void main()
    {
        vec3 v1 = gl_in[1].gl_Position - gl_in[0].gl_Position;
        vec3 v2 = gl_in[2].gl_Position - gl_in[0].gl_Position;
        normal = normalize(cross(v1, v2));
        for (int i = 0; i < gl_in.length(); i++) {
            gl_Position = gl_in[i].gl_Position;
            EmitVertex();
        }
        EndPrimitive();
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •