Custom Lighting Transform is Ending Up In the Wrong Space

I have sprites and dynamic lights that are passed into a shader as uniforms. Kind of,


/* 1.10 fragment shader */

#define MAX_LIGHTS 64
#define AMBIENT 0.08

uniform int number_of_lights;
uniform vec2 world_space_light_position[MAX_LIGHTS];

void main() {
	vec3 shade = vec3(AMBIENT);
	for(int i = 0; i < MAX_LIGHTS; i++) {
		if(i < number_of_lights) {
			vec2 relative_light_position = world_space_light_position[i] - gl_ModelViewMatrix[3].xy;
			shade += vec3(1.0 / (length(relative_light_position) + 1.0));
		} else {
			break;
		}
	}
	gl_FragColor = vec4(shade, 1.0);
}

I want to move my camera around now but my lights are just ignoring camera movement. I think it’s gl_ModelViewMatrix[3].xy that’s the problem; I want the world coordinates of the sprite.

I guess what I’m asking is how to get the world co-ordinates of the vertex.

I guess what I’m asking is how to get the world co-ordinates of the vertex.

I suppose that you have the vertex position in view space. (in your shader)

To get the vertex position in world space you have just to multiply your vertex by the inverse of the modelview matrix.

To get the vertex position in world space you have just to multiply your vertex by the inverse of the modelview matrix.

Just the inverse of the view matrix, otherwise you are back to model space.
OpenGL normally does not make use of an (explicit) world space, there is just modelspace and viewspace (hence the transformations are lumped together into the modelview matrix). A transformation matrix to/from world space is something you will have to supply manually to your shader (through a uniform variable).

Vertex:


uniform vec2 sprite_position;
varying vec2 fragment_position;

void main() {
	/* this allows for pixel accuracy */
	mat2 modelMatrix = mat2(
		gl_ModelViewMatrix[0].x, gl_ModelViewMatrix[0].y,
		gl_ModelViewMatrix[1].x, gl_ModelViewMatrix[1].y
	);
	fragment_position = sprite_position + (modelMatrix * gl_Vertex.xy);
	gl_Position = ftransform();
}

Fragment:


uniform vec2 l_pos;
varying vec2 fragment_position;

main() {
	vec2 relative = l_pos - fragment_position;
	float shade = 1.0 / (length(relative)+1.0);
	gl_FragColor = vec4(shade, shade, shade, 1.0);
}

Now every sprite has to have sprite_position passed to it which is in world space. Thanks for the helpful comments!

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