Specular light shader

Hello all,

I have the following function within a vertex shader that I got from “Egon Rath’s Notes” on www.matrix44.com. Unfortunately, I can’t seem to get it to work.



uniform mat4 mProjection;
uniform mat4 mView;
uniform mat4 mModel;

uniform vec4 EyePosition;
uniform vec4 LightPosition;
uniform vec4 LightColor;

// The Colors of the material
uniform vec4 AmbientMaterial;
uniform vec4 DiffuseMaterial;
uniform vec4 SpecularMaterial;

uniform vec3 Drawing_Color;

varying vec3 lighted_color;


vec4 GetSpecularColor()
{
    // Transform the Vertex and corresponding Normal into Model space
    vec4 trans_normal = mModel * vec4( gl_Normal, 1 );
    vec4 trans_vertex = mModel * gl_Vertex;

    // Get the directional vector to the light and to the camera
    // originating from the vertex position
    vec4 light_direction = normalize( LightPosition - trans_vertex );
    vec4 camera_direction = normalize( EyePosition - trans_vertex );

    // Calculate the reflection vector between the incoming light and the
    // normal (incoming angle = outgoing angle)
    // We have to use the invert of the light direction because "reflect"
    // expects the incident vector as its first parameter
    vec4 reflection = reflect( -light_direction, trans_normal );

    // Calculate specular component
    // Based on the dot product between the reflection vector and the camera
    // direction.
    //
    // hint: The Dot Product corresponds to the angle between the two vectors
    // hint: if the angle is out of range (0 ... 180 degrees) we use 0.0
    float spec = pow( max( 0.0, dot( camera_direction, reflection )), 32 );

    return vec4( SpecularMaterial.r * spec, SpecularMaterial.g * spec, SpecularMaterial.b * spec, 1.0 );
}


I set the uniforms like this:



MyViewMatrix.Get_Current_Matrix(viewMatrix);
    MyModelMatrix.Get_Current_Matrix(modelMatrix);

    pglUniformMatrix4fv(view_matrix_location, 1, false, &viewMatrix[0]);
    pglUniformMatrix4fv(model_matrix_location, 1, false, &modelMatrix[0]);

camera_position[0] = 0.0f;
    camera_position[1] = 0.0f;
    camera_position[2] = 10.0f;
    camera_position[3] = 0.0f;

    pglUniform4fv(camera_position_location,1,camera_position);

    pglUniform3fv(draw_color_location,1,m_current_color);
    pglUniform4fv(light_position_location,1,light_position);
    pglUniform4fv(light_color_location,1,light_color);

    pglUniform4fv(ambient_material_location,1,ambient_material_color);
    pglUniform4fv(diffuse_material_location,1,diffuse_material_color);
    pglUniform4fv(specular_material_location,1,specular_material_color);



. . . and do the actual rendering with:



MyModelMatrix.Rotate(30.0f,1.0f,0.0f,0.0f);
MyModelMatrix.Rotate(frame*8,0.0f,1.0f,0.0f);

glBegin(GL_POLYGON);
glNormal3f( 0.0f, 0.0f, 1.0f);
                glVertex3f(  1.5, -1.5, 1.5 );
                glVertex3f(  1.5,  1.5, 1.5 );
                glVertex3f( -1.5,  1.5, 1.5 );
                glVertex3f( -1.5, -1.5, 1.5 );
glEnd();

Unfortunately, the light appears at weird angles. I’ve fiddled with it for almost two days and can’t make heads or tails of where the problem is. To make progress in debugging, my first two questions are:

  1. Is there anything obviously wrong with the vertex shader function?
  2. Is there anything wrong with the way I set the data for the light position and camera position? (I suspect these two aspects of the process the most.)

Let me know if there is any other information I can give. I’ve attached an image.

Some things that might be the problem:

[ul]
[li] What is mModel? I took a quick look at my working phong shader example, and there the light direction was transformed with the normal matrix, which transforms into camera coordinates. Is that what you used? (Camera coordinates should be part of the view matrix)[/li][li] Instead of [/li]vec4( SpecularMaterial.r * spec, SpecularMaterial.g * spec, SpecularMaterial.b * spec, 1.0 );
you can just write
vec4( SpecularMaterial.rgb * spec, 1.0 );
[li] The fourth component of your camera position is 0. I think it should be 1, at least I’ve had serious problems with other coordinates that had 0 as their fourth component.[/li][li] Try to set the light behind the camera, stop all rotations and look straight vertically at the quad. See if the specular part appears in the center of the quad, and then see which effects the rotations do. The rest of your code seems ok to me (although I’m not sure what exactly reflect does. When in doubt, do it manually :wink: ).[/li][/ul]

Finally got it working with your suggestions. Thanks! (sorry for delay in response. . . had a hospital emergency).