Sign in to follow this  

GLSL lighting problems

Recommended Posts

Hi, I'm trying to write a shader for my engine that will render multiple point lights in a single pass with normal mapping. Before I write the shader for multiple lights I'm trying to get it working with a single fixed light. In the shader editor I'm using (qshaderedit) the shader seems to work. However, when I load the shader into my engine the light seems to follow the camera rather than stay fixed. Here is my fragment shader code:

varying vec3 v_V; 
varying vec3 v_N;
varying vec2 v_TC; 
varying vec3 v_T;

uniform sampler2D normalMap;
uniform sampler2D textureMap;

void main() {
//these are the fixed light properties (for now)
	vec3 lightPos = vec3(0.3, 0, 0);
	vec4 lightDif = vec4(1, 1, 0, 1);
	vec4 lightAmb = vec4(0.5, 0.5, 0.5, 0.5);
	vec4 lightSpec = vec4(1, 1, 0, 1);

	vec3 aux = lightPos - v_V;
	vec3 N = normalize(v_N);
	vec3 L = normalize(aux); 
	vec3 E = normalize(-v_V); // we are in Eye Coordinates, so EyePos is (0,0,0)
	vec3 H = normalize(L + E);

	vec3 T = normalize(v_T);
	vec3 B = normalize(cross(N, T));
	mat3 tSpace = mat3(T, B, N); //Build texture space matrix

	vec3 L1 = tSpace * L; //Convert light and eye vectors to tex space
	vec3 E1 = tSpace * E;
	vec3 H1 = normalize(L1 + E1); //Calc the half vector

	vec3 N1 = normalize(texture2D(normalMap, v_TC)).xyz;
	N1 = vec3(2.0) * (N1 - vec3(0.5));

	vec4 diffuseColour = texture2D(textureMap, v_TC);
	//calculate Ambient Term:
	vec4 Iamb = gl_FrontMaterial.ambient * lightAmb;

	//calculate Diffuse Term
	vec4 Idiff = diffuseColour * max(dot(L1,N1), 0.0) * lightDif;
	vec4 Ispec = max(dot(H1, N1), 0.0) * gl_FrontMaterial.shininess * gl_FrontMaterial.specular * lightSpec;

	// calculate Specular Term:
	// write Total Color:
	gl_FragColor = (Iamb + Idiff + Ispec);

and the vertex shader:
varying vec3 v_V;
varying vec3 v_N;
varying vec2 v_TC;
varying vec3 v_T;

void main() {
	gl_Position = ftransform();
	v_V = (gl_ModelViewMatrix * gl_Vertex).xyz;
	v_N = gl_NormalMatrix * gl_Normal;
	v_T = gl_NormalMatrix *;
	v_TC = gl_MultiTexCoord0.xy;


My best guess is that the light position in those calculations is in "eye space" whereas I want to specify it in "world space". How can I get it to world space from eye space? Also if any one can point my to any good articles on multiple lights in a single shader that would be helpful too. Thanks, Luke.

Share this post

Link to post
Share on other sites
You could just set the lights in you application with glLight(), and then read the converted values from gl_LightSource in your shader. You can access multiple lights via gl_LightSource[1], gl_LightSource[2], etc

You might be able to do what you want here by specifying lightPos in the vertex shader and applying the ModelView matrix to it (or not, I get confused by all the various spaces involved ^_^;), but encoding light position in shaders seems like a bad idea in the long run.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this