Light position and gluLookAt

Hi,

I have troubles with light transformation. I set the camera position with gluLookAt(). Then i pass the light position as the uniform variable to the vertex shader.

uniform vec4 position;

The question is: what exactly computations do i have to make to have position uniform working as if i use built-in variable gl_LightSource[].position (with this, it’s working fine) ???

All code is fine - only thing i need is to transform position to eye space. By the way -

gl_ModelViewMatrix * position

is not the correct idea :). Can You help me please ?

One more thing… when using gluLookAt(x,y,z…) ← the position of the camera should be already in current model-view matrix, am i right ? Or i should add it somewhere in my calculations in shader ???

some part of my code:


...
vec3 Ni,V;

vec4 V4 =  gl_ModelViewMatrix * gl_Vertex;

V = V4.xyz / V4.w;

Ni =  gl_NormalMatrix * gl_Normal;

vec3 C;

C = -normalize(V);
			
vec3 NN = normalize(Ni);
...

1st.
if you specify the light position with glLight() its transformed by the current MODELVIEW_MATRIX. the modelview matrix transforms you geometry from model-space into eye-space or camera-space.
doing gl_ModelViewMatrix * position will transform position into eye-space and should actually work. you should make sure you do all computation in either eye-space (opengl default) or world-space. how does the current problem look like? is light somewhere else where you expect it?

2nd.
gluLookAt() will multiply new computed matrix with the current matrix on the stack. to avoid this you should call glLoadIdentity() before gluLookAt() so the new matrix isn’t modified by the old one.

I have identity matrix loaded before gluLookAt(). I call glLight…(…,GL_POSITION,…) outside of the rendering function, so i set light before setting camera.

Yes, when i use gl_LightSource[].position in shader everything’s fine. When i use uniform position instead, the difusse and specular highlight is in some other place it should be, like the light source was somewhere else, than fixed pipeline shows.

I have managed to fix this, but in strange way and only for point light sources.

I get the MODELVIEW_MATRIX in program after the camera transf. (gluLookAt), then i multiply it by the position of light like this:



vOut[0] = mMatrix[0] * vSrcVector[0] + mMatrix[4] * vSrcVector[1] + mMatrix[8] *  vSrcVector[2] + mMatrix[12];

vOut[1] = mMatrix[1] * vSrcVector[0] + mMatrix[5] * vSrcVector[1] + mMatrix[9] *  vSrcVector[2] + mMatrix[13];

vOut[2] = mMatrix[2] * vSrcVector[0] + mMatrix[6] * vSrcVector[1] + mMatrix[10] * vSrcVector[2] + mMatrix[14]; 


vOut[3] - result vector
vSrcVector[3] - position of light .xyz
mMatrix - current ModelViewMatrix, in multiplication it’s transposed if i’m right

Then i pass as uniform the transformed position of light. For point light it’s okay, directional and spot still have some problems. In spot light the direction vector is also transformed, but it generates slightly different result that it should. I don’t transform directional light direction, but it still places the highlight’s a bit moved.

I am not sure to understand your last post.

For a directional light, just pass its direction in world space, say wLightDir, then transform it in eye space like this:

vec3 eLightDir = gl_ModelViewMatrix * vec4(wLightDir, 0);

where eLightDir is light direction in eye space.

For a point or spot light, you give light position in world space: wLightPos and transform it like this:

eLightPos = gl_ModelViewMatrix * vec4(wLightPos, 1);

To compute the light direction in eye space at each vertex, you just need to compute eLightPos - ePos (where ePos is the vertex position in eye space).

lets say you have modelview matrix set to identity. setting the light will transform your point/vector by that identity matrix and gives you the same output. so basically you move your light around just with those coordinates you pass in. you should carefully look through your code and reassemble the same behavior as used by fixed function pipeline. guess something is wrong with your order of gl calls?

I did that, it’s not working :p. It generates some strange result.

and should be: vec3 eLightDir = vec3(gl_Model…);

I don’t know. When i pass direction as uniform it’s wrong. When i use gl_LightSource[].direction instead it’s fine. So all calculations seems to be alright. I know from books etc. that direction and position should be pre-multiplied by MV-matrix. But when i do it in shader it’s not working.

Have anyone written shader that generates lighting without using built-in light variables ???

I found only one sample of this in OpenGL Superbible (3rd ed.) with point light. It works ok, as i described above. But for directional and spot light still i don’t know how to solve it :sorrow:.

that direction and position should be pre-multiplied by MV-matrix

What does it means, you pre-multiply light direction by the modelview matrix before giving them to the shader and then multiply it again by the same matrix in the shader?

From the glsl spec, they say that light direction is already given is eye space in the corresponding built-ins. This is just for convenience. You just need to compute lighting with vectors all in same space.
Your problem is related to the space where you are computing lighting IMO.

thats sure confusing. by premultiply you probably mean the order of matrix multiplication? aka row-major vs. column-major?

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.