Light Source rotating with object

Hello everyone,

i wrote this simple shader for some lighting. The calculation of the specular component is borrowed from the Orange book.

Here is the vertex shader:
I’m trying a simple per-vertex lighting. I’m trying to implement a directional light.

Light Direction = (1.0, 0.0, 0.0, 0.0)


uniform vec4 lAmbient;
uniform vec4 mAmbient;
uniform vec4 lDiffuse;
uniform vec4 mDiffuse;
uniform vec4 lightPos;
uniform float waveAmp;
varying vec4 color;
const float SpecularContribution = 0.1;
 
void main(void)
{      
    float spec  = 0.0;

    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
    float lambertTerm = dot( vec4(normal, 0.0), lightPos );
       
    vec4 ambColor   = lAmbient * mAmbient;
    vec4 diffColor  = lDiffuse * mDiffuse * lambertTerm;
    vec3 viewVec    = normalize(-gl_Vertex.xyz);
        
    vec3 lightVec   = normalize(vec3(lightPos)-
                      gl_Vertex.xyz);

    vec3 reflectVec = reflect(-lightVec, normal);
		
        
    if (lambertTerm > 0.0) {
        spec = max(dot(reflectVec, viewVec), 0.0);
	spec = pow(spec, 16.0);
    }
       
    color =   (ambColor + diffColor) 
   	    + (vec4(1.0, 1.0, 1.0, 1.0) * spec);
               
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

The problem is, when i rotate the object, the light source seems to move too. Also, i’m not able to get good specular highlights. Any tips on improving it?

Here is the PIC

Thanks!

You are not doing all calculations in the same coordinate system. For example, viewVec is only -vertex_position if vertex_position is in eye space (i.e. after multiplication with gl_ModelViewMatrix) - or if your eye happens to be in the world origin of course :wink:
Similar for lightVec, here you calculate with lightPos (I assume you want to specify that in world space) and gl_Vertex in object space.
Make sure you do your lighting calculations in a single coordinate system - eye space is a popular choice, but others are possible.

For better specular highlights switch to per-pixel lighting or use a finer mesh, they are always going to look rather rough with per-vertex lighting. The lighthouse3d tutorial has an image that shows the difference.

Thanks Carsten Neumann. I fixed that problem. I’m now doing all calculations in eye space.
Here is the new shader. I’m still doing a per vertex calculation and the specular component is totally off. Here is a pic with the same values.

PIC

Comparing fixed pipeline and the shader code i have written:


GLfloat mAmbient[4] = {1.0, 1.0, 1.0, 0.0};
GLfloat lAmbient[4] = {0.2, 0.2, 0.2, 1.0};
GLfloat mDiffuse[4] = {0.0, 0.3, 1.0, 1.0};
GLfloat lDiffuse[4] = {1.0, 1.0, 1.0, 1.0};
GLfloat lSpecular[4] = {1.0, 1.0, 0.0, 1.0};
GLfloat mSpecular[4] = {0.0, 0.3, 1.0, 1.0};

Using the same values for fixed pipeline and shader. Here is the modified vertex shader.


void main(void)
{      
    float spec  = 0.0;

    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
    float lambertTerm = dot(normal, lightPos.xyz);
       
    vec4 ambColor  = lAmbient * mAmbient;
    vec4 diffColor = lDiffuse * mDiffuse * lambertTerm;       
    vec3 viewVec   = vec3(normalize(-(gl_ModelViewMatrix 
                         * gl_Vertex)));
        
    vec3 lightVec   = normalize(lightPos.xyz);
    vec3 reflectVec = reflect(-lightVec, normal);
		
        
    if (lambertTerm > 0.0) {
	spec = max(dot(reflectVec, viewVec), 0.0);
	spec = pow(spec, 16.0);  // Shininess
    }
		
     vec4 specColor = mSpecular * lSpecular * spec;        
         
     color = ambColor + diffColor + specColor;               
     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Now, the “spec” becomes rather too small when raised to a large number. But how else do i calculate the specular component?

Please let me know where i’m going wrong.

Thanks a lot!

Ah, i’m sorry, i hadn’t normalized the light vector.

Here is the modified one:


vec3 lightVec   = normalize(lightPos.xyz);
float lambertTerm = dot(normal, lightVec);

Here is the snapshot:
PIC

Well the specular component is still not turning up. Can you please tell what’s the mistake?

Thanks!

Hmm, lightPos is not transformed into eye space AFAICT, but perhaps you want the light attached to your camera?

Your material has a fairly dark specular colour, do you get highlights with the fixed function pipeline?

lightVec look like a vector between the eye and the light source, but for the specular calculation you want the vector from the vertex to the light.

Thanks Carsten Nuemann.

Hmm, lightPos is not transformed into eye space AFAICT, but perhaps you want the light attached to your camera?

Yes. I’m giving it in eye space.

Your material has a fairly dark specular colour, do you get highlights with the fixed function pipeline?

Yeah, i guess that was the problem. I increased the specular colour. Now it is better. But it looks quite different with the fixed pipeline.

Here is the Pic:
PIC

I used this page for the equations for calculation of the lights:

LINK

Please let me know if there is any mistake in my calculations.
Thanks!