Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎯 Unreal

GLSL lighting problems

Started by Kazade Apr 9, 2007 at 5:09 AM 0 replies 2.5k views
Original Post
Kazade
Kazade
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 * gl_MultiTexCoord1.xyz;
	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.
Member of the NeHe team.
Stani R
Stani R
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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.