Reputation: 1594
I just implemented the "god-ray" shader from nVidia's lovely GPU Gems 3 book: Volumetric Light Scattering as a Post-Process.
Anyway, it's almost perfect, except for one flaw. Somehow the position of the light is not being moved with the rest of the scene.
Picture examples:
This looks exactly as it should.
This does not. The light should be radiating outward from the white sphere, but it looks like the position hasn't changed from the first picture.
I'm doing the transformations in the vertex shader:
uniform vec4 light_coords;
varying vec2 light_pos;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
light_pos = vec2(gl_ModelViewProjectionMatrix * light_coords) * 0.5 + 0.5;
}
Is this correct?
The position of the light in world coordinates is (0, 0, -2) It's entirely possible that the error is somewhere else in the code, but I wanted to make sure my calculations in the vertex shader were correct before diving into the rest of it.
EDIT: I made some changes based on what Nicol Bolas suggested below, and it's better, but still not right.
It still looks fine when the camera is at its original position, but when I rotate the scene, it looks as though the calculated light position is now too far to the left.
Here's the GLSL code I'm using:
uniform vec4 light_coords;
uniform mat4 light_modelview;
varying vec2 light_pos;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
light_pos = vec2(gl_ProjectionMatrix * light_modelview * light_coords) * 0.5 + 0.5;
}
light_modelview
is obtained here:
glPushMatrix()
glTranslatef(self.position[0], self.position[1], self.position[2])
glScalef(2, 2, 2)
self.modelview = glGetFloatv(GL_MODELVIEW_MATRIX)
glCallList(self.sphere)
glLightfv(self.light_id, GL_POSITION, self.position)
glPopMatrix()
position
is [0, 0, -2]
. It's passed into the shader as light_coords
Ideally, I'd like light_pos
to be anywhere in (0, 0) to (1, 1) if it's on the screen, and greater or less than that if it's off the screen.
Any clue what I'm doing wrong? I'm still kinda new to OpenGL, so I'm a little unsure what does what.
Upvotes: 3
Views: 2158
Reputation: 473407
If light_coords
is in world space, then multiplying it by the gl_ModelViewProjectionMatrix
only makes sense if gl_Vertex
is also in world space. Somehow, I doubt that it is.
In general, you don't pass light directions or whatever light_coords
is supposed to be in world space. You pass it in view space. You transform from world space to view space on the CPU, and you put the view space coordinates in the shader.
Upvotes: 4