0

(Edit): The original code I posted was for both gouraud and phong shading options. I've changed it so it is just phong shading and posted below. The mesh is too big to describe here, as it is generated from a Bezier Patch.

I'm having some problems with flat and phong shading in Open GL 3 Mesa 9. It seems no matter what I do I get flat shaded figures, with tiny facets (planes) and I cannot get Blinn-Phong shading to work.

Here are my shaders:

(Vertex Shader)

//material parameters

uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;


attribute vec4 vPosition;
//attribute vec4 vColor;
attribute vec4 vNormal;
attribute vec4 vControlColor;
attribute vec2 texcoord;


uniform mat4 model_view;
uniform mat4 projection;

uniform int flag;
uniform int phong_flag;
uniform vec4 eye_position;

//lighting parameters
uniform vec4 light_1;               //light 1 position         
uniform vec4 light_2;               //light 2 position



varying vec4 control_color;
varying vec4 color;
varying vec4 position;
varying vec4 normal;

varying vec2 st;

void
main()
{

    control_color = vControlColor;
    position = vPosition;
    normal = vNormal;
    tex_coords = texcoord;
    st = texcoord;
    gl_Position = projection*model_view*vPosition;

}

And my fragment shader:

//material parameters

uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;
uniform vec4 eye_position;

uniform int phong_flag;


//lighting parameters
uniform vec4 light_1;               //light 1 position         
uniform vec4 light_2;               //light 2 position
varying vec4 light_2_transformed;   //light 2 transformed position
uniform int Control_Point_Flag;
uniform sampler2D texMap;

varying vec4 color;
varying vec4 position;
varying vec4 normal;
varying vec4 control_color;

varying vec2 st;

void
main()
{

        vec4 N = normalize(normal);
        vec4 E = normalize(eye_position - position);
        vec4 L1 = normalize(light_1 - position);
        vec4 L2 = normalize(light_2 - position);
        vec4 H1 = normalize( L1 + E);
        vec4 H2 = normalize( L2 + E);

        //calculate ambient component
        vec4 ambient = AmbientProduct;


        //calculate diffuse componenent
        float k_d_1 = max(dot(L1,N), 0.0);
        float k_d_2 = max(dot(L2,N), 0.0);
        vec4 diffuse1 = k_d_1*DiffuseProduct;
        vec4 diffuse2 = k_d_2*DiffuseProduct;

        //calculate specular componenent
        float k_s_1 = pow(max(dot(N, H1), 0.0), Shininess);
        float k_s_2 = pow(max(dot(N, H2), 0.0), Shininess);
        vec4 specular1 = k_s_1*SpecularProduct;
        vec4 specular2 = k_s_2*SpecularProduct;   

        //if specular color is behind the camera, discard it
        if (dot(L1, N) < 0.0) {
            specular1 = vec4(0.0, 0.0, 0.0, 1.0);
        }
        if (dot(L2, N) < 0.0) {
            specular2 = vec4(0.0, 0.0, 0.0, 1.0);
        }


        vec4 final_color = ambient + diffuse1 + diffuse2 + specular1 + specular2;

        final_color.a = 1.0;

        /* gl_FragColor = final_color; */
        gl_FragColor = final_color*texture2D(texMap, st);

}

Does everything look ok for my shaders?

genpfault
  • 51,148
  • 11
  • 85
  • 139

1 Answers1

2

Things worth noting:

  1. You have variables for a ModelView in your vertex shader, but you never use it in calculating position. Your vertex "position"s are thus whatever is passed from your OpenGL application and are not affected by any transformations you may be trying to do, though they are physically placed correctly because you use the matrices for gl_Position.
  2. You aren't passing a Normal matrix to your shader. The Normal matrix is calculated by taking the transpose inverse of the ModelView matrix. Calculate this outside of the shader and pass it in. If you don't multiply your normals by the Normal matrix, you'll still be able to transform your model, but the normals will all still be facing the same way, so your lighting will be incorrect.

However, your normal vectors on the OpenGL side are may likely be the culprit. See this question for a good explanation of a possible source of unwanted flat shading.

As a side note, both of your shaders seem more complicated than they should be. That is to say, they have too many variables that aren't used and too much stuff that you could condense into fewer lines. It's just housekeeping, but it will make keeping track of your code easier.

Community
  • 1
  • 1
GraphicsMuncher
  • 4,583
  • 4
  • 35
  • 50
  • Umm... 1) This is only shader code, not application code. In my application I do pass the modelview and projection matrices in via Uniform variables in the display callback. The normals are passed in via a vbo, along with the geometry. Also, 2,I was informed there is no need for a normal matrix if I'm passing normal vectors. And this code that you are saying is overly complex was taken directly from a GL textbook and is not necessarily all of mine in origin. I'll check out the link you'vec provided. – user1610329 Jun 06 '13 at 22:22
  • 1) This is all evident in your original question. 2) I'm giving you advice based on shader books I've used. You can read [this question](http://stackoverflow.com/questions/5823438/opengl-gl-normalmatrix) for some justification about of matrices. – GraphicsMuncher Jun 07 '13 at 14:36