Normals, GLSL, FP/VP

Started by
17 comments, last by MARS_999 18 years, 9 months ago
Quote:Original post by James Trotter
The light position is transformed as if it were a vertex. You would want to specify it after you have applied the camera transformations.


Hmm I am sure I am doing it correctly, I had no issues with my FP/VP, but here is what I am doing, I call glLookAt() first and then these functions later on

glPushMatrix();	glLoadIdentity();    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);	glPopMatrix();


The lightPosition never changes for now...
Advertisement
Can you please post the whole GLSL code? You've posted only a line, we don't know how you calculate the vertex positions or the light vectors.

However, the rule of thumb is that you update the light position every frame after the camera transformation.

Quote:
The lightPosition never changes for now...


No it doesn't, but the vertex and normals do change due to camera changes, and so the lighting changes too. You have the light pos in world coordinates, and you have "normal = normalize(gl_NormalMatrix * gl_Normal);" which transforms the normal into eye coordinates.
Here is the FS code
   varying vec4 diffuse, ambient;   varying vec3 normal, lightDir, halfVector;   varying vec2 blendmap_texCoord, texture_coord;        void main()   {      vec3 n,halfV,viewV,ldir;      float NdotL,NdotHV;               /* The ambient term will always be present */      vec4 color = ambient;            /* a fragment shader can't write a varying variable, hence we need      a new variable to store the normalized interpolated normal */      n = normalize(normal);            /* compute the dot product between normal and ldir */      NdotL = max(dot(n,lightDir),0.0);         if (NdotL > 0.0) {         color += diffuse * NdotL;         halfV = normalize(halfVector);         NdotHV = max(dot(n,halfV),0.0);         color += gl_FrontMaterial.specular *                gl_LightSource[0].specular *                pow(NdotHV, gl_FrontMaterial.shininess);      }      gl_FragColor = color;   }


VS code
   varying vec4 diffuse, ambient;   varying vec3 normal, lightDir, halfVector;   varying vec2 blendmap_texCoord, texture_coord;          void main()   {         //gl_TexCoord[0] = gl_MultiTexCoord0;      blendmap_texCoord = vec2(gl_MultiTexCoord0);      texture_coord = blendmap_texCoord * 20;                           /* first transform the normal into eye space and       normalize the result */      normal = normalize(gl_NormalMatrix * gl_Normal);            /* now normalize the light's direction. Note that       according to the OpenGL specification, the light       is stored in eye space. Also since we're talking about       a directional light, the position field is actually direction */      lightDir = normalize(vec3(gl_LightSource[0].position));         /* Normalize the halfVector to pass it to the fragment shader */      halfVector = normalize(gl_LightSource[0].halfVector.xyz);                     /* Compute the diffuse, ambient and globalAmbient terms */      diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;      ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;      ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;           gl_Position = ftransform();   } 


HTH you help me!!! ;)
Quote:
/* now normalize the light's direction. Note that
according to the OpenGL specification, the light
is stored in eye space. Also since we're talking about
a directional light, the position field is actually direction */
lightDir = normalize(vec3(gl_LightSource[0].position));


How do you expect it to be stored in eye space when you call glLightfv() with the identity as the modelview matrix? As others said, call Lightf() immediately after camera transformations.
Quote:Original post by mikeman
Quote:
/* now normalize the light's direction. Note that
according to the OpenGL specification, the light
is stored in eye space. Also since we're talking about
a directional light, the position field is actually direction */
lightDir = normalize(vec3(gl_LightSource[0].position));


How do you expect it to be stored in eye space when you call glLightfv() with the identity as the modelview matrix? As others said, call Lightf() immediately after camera transformations.


Not trying to be stupid or ungrateful, but I think I stated earlier that in my FP/VP everything worked fine... My FFP setup code for my light and camera haven't changed when I call them, so I can't see how I am calling them in the wrong place? So here is my rendering code which I dont' think is wrong but anyway...
	//reset viewport to our original viewport size	glViewport(0, 0, gWidth, gHeight);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();		g_Camera.LookAt();	//reset light position or else the light position will jump all over	glPushMatrix();	glLoadIdentity();        glLightfv(GL_LIGHT0, GL_POSITION, terrain.lightPosition);	glPopMatrix();	glTranslatef(0.0f, -move_y, 0.0f);		//move height based on mouse wheel	glPushMatrix();	terrain.DrawTerrainVBO(timer.speedfactor, false); 	glPopMatrix();
I honestly don't understand why we're arguing about this instead of just going and make that little change on your code and see for yourself that it works. I don't know why it worked on your previous settings. All I know is the error I see in your current settings, and I just pointed it out(along with others).
Quote:Original post by mikeman
I honestly don't understand why we're arguing about this instead of just going and make that little change on your code and see for yourself that it works. I don't know why it worked on your previous settings. All I know is the error I see in your current settings, and I just pointed it out(along with others).


I did make the change I moved the glLight() right after glLookAt()????
//reset light position or else the light position will jump all overglPushMatrix();glLoadIdentity(); <---- Take this line away [wink]glLightfv(GL_LIGHT0, GL_POSITION, terrain.lightPosition);glPopMatrix();


I believe that should do it. If you're curious about it, you should look it up in chapter 5 of the OpenGL programming guide (the "red book"). Look at example 5-4, and 5-5, pages 192 and 193.

I think that the book is freely available on the internet somewhere if you don't have it with you.

Hope this helps.

Edit: On second thought, of the above four lines of code, only the call to glLightfv should be necessary.
Quote:Original post by James Trotter
//reset light position or else the light position will jump all overglPushMatrix();glLoadIdentity(); <---- Take this line away [wink]glLightfv(GL_LIGHT0, GL_POSITION, terrain.lightPosition);glPopMatrix();


I believe that should do it. If you're curious about it, you should look it up in chapter 5 of the OpenGL programming guide (the "red book"). Look at example 5-4, and 5-5, pages 192 and 193.

I think that the book is freely available on the internet somewhere if you don't have it with you.

Hope this helps.

Edit: On second thought, of the above four lines of code, only the call to glLightfv should be necessary.


Ok, that works now!! ;) Thanks all for the help and understanding, it just threw me off when my FP/VP worked fine without having to call the glLightfv() to set the lightposition after I position the camera...

This topic is closed to new replies.

Advertisement