Sign in to follow this  
kloffy

GLSL Multilight Shader Errors

Recommended Posts

I've been implementing a multilight shader in GLSL and I've come across some strange visual errors when the lightcount goes up. 5 Lights 6 Lights I have an ATI X700 graphics card, which isn't exactly new. A friend of mine has a newer card and the shader works fine for him, even with more than 5 lights. Could this mean that I've maxed out the instruction count on my GPU? If so, why isn't it giving me any compile errors. Here is the code for the shader, the only thing that changes when there is a different number of lights is NUM_LIGHTS:
[vert]
#define NUM_LIGHTS 6

varying vec3 eyeVec;
varying vec3 normal;

varying vec3 lightDir[NUM_LIGHTS];

void main()
{
	normal = gl_NormalMatrix * gl_Normal;
	
	vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
	eyeVec = -vVertex;

	for(int i = 0; i < NUM_LIGHTS; i++) 
	{
		lightDir[i] = vec3(gl_LightSource[i].position.xyz - vVertex);
	}
	
	gl_Position = ftransform();	

	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;    
}

[frag]
#define NUM_LIGHTS 6

uniform sampler2D colorMap;

uniform float radius[NUM_LIGHTS];

varying vec3 eyeVec;
varying vec3 normal;
varying vec3 lightDir[NUM_LIGHTS];

void main()
{
	vec4 color = gl_FrontLightModelProduct.sceneColor;

	for(int i = 0; i < NUM_LIGHTS; i++)
	{
		float distSqr = dot(lightDir[i], lightDir[i]);
		float att = clamp(1.0 - (1.0/radius[i]) * sqrt(distSqr), 0.0, 1.0);

		if(att > 0.0)
		{
			color += gl_LightSource[0].ambient * gl_FrontMaterial.ambient * att;

			vec3 N = normalize(normal);
			vec3 L = lightDir[i] * inversesqrt(distSqr);
	
			float lambertTerm = dot(N,L);

			if(lambertTerm > 0.0)
			{
				color += gl_LightSource[i].diffuse * gl_FrontMaterial.diffuse * lambertTerm * att;	
		
				vec3 E = normalize(eyeVec);
				vec3 R = reflect(-L, N);
		
				float specular = pow(max(dot(R, E), 0.0), gl_FrontMaterial.shininess);
		
				color += gl_LightSource[i].specular * gl_FrontMaterial.specular * specular * att;	
			}
		}
	}

	gl_FragColor = color * texture2D(colorMap, gl_TexCoord[0].st);
	gl_FragColor[3] = gl_FrontMaterial.diffuse[3];
}

[Edited by - kloffy on August 12, 2008 8:16:27 PM]

Share this post


Link to post
Share on other sites
Nobody here who could shed some light on what might cause the strange effect in the second screenshot? Like I said, it seems like it's connected with the hardware you use, so it shouldn't be the logic in the shader itself thats faulty. Come on, quit raging in the OpenGL 3.0 thread and help a shader newbie out...

Share this post


Link to post
Share on other sites
Quote:
I have an ATI X700 graphics card, which isn't exactly new. A friend of mine has a newer card and the shader works fine for him, even with more than 5 lights. Could this mean that I've maxed out the instruction count on my GPU? If so, why isn't it giving me any compile errors.


Are you saying this is only a problem on the ATI X700?
If it maxed out, the driver would normally report it when you call glGetInfoLog.
If the problem is across the board, on multiple ATI GPUs with the same Catalyst driver, it could be that the driver is forgetting to update some registers. To remedy it, don't use fixed function stuff like gl_LightModel, but use your own uniforms instead.

Share this post


Link to post
Share on other sites
Thank you for your answer. I am checking the info log and it reports that everything compiled fine and that the shaders are running on hardware. This is where I was expecting to see an error message when the instruction count is exceeding the hardware capabilities. It's good to know that it should be there if that were the case...
Unfortunately, I've only been able to test my code on two GPUs so far, mine (ATI X700) and my friends (newer generation ATI card, I'm not sure about the model...). We are using the latest drivers, however, I'm running XP and he is running Vista. It's really a mystery to me why a greater number of lights works for him and not for me.
The only difference in the two screenshots is that I have added the green light on the left, bringing NUM_LIGHTS up to 6. Both screenshots were made on my machine.
It is very likely to be some hardware/driver thing, but it bugs me that I don't know what it is and how to avoid it. I was hoping that maybe someone has come across something like this before.

Edit: Thanks jezham, I'll change the image hoster...

[Edited by - kloffy on August 12, 2008 7:17:31 PM]

Share this post


Link to post
Share on other sites
Yes it's visible now. Can't really help much though...

Seems you only refer to ambient for light 0. Apart from that, I wonder if your frag prog is getting a redefinition for NUM_LIGHTS, and setting it to zero? But that doesn't explain why it would work with 5 and not 6? The second image does look like (somewhat strange) vertex shading though, compared to the first image's frag lighting.

Share this post


Link to post
Share on other sites
The ambient component that is added only once is the global ambient light. The defines should work fine, as they do for any number of lights less than 6. You are right though, it does look like some sort of strange per vertex lighting. However, if you position the camera in a certain way you can see shapes that are not limited to the vertices, such as this:

Share this post


Link to post
Share on other sites
The last screenshot certainly implies that it's not a hardware limitation. Only the nearest and furthest triangles appear effected.
Perhaps a 'max' around your 'distSqr' calculation will help? But I'm stepping out of my knowledge a little now, that was from another post I was reading earlier.

If worst comes to worst you could always divide the scene so that no triangle uses more than 5 lights, rendering each division with the active (local) set. This should be fine as your lights fade quickly with distance...the bonus of that is it will allow for unlimited (but spaced out) lights, and better performance. But don't give up on finding a solution, there will surely be more ideas out there!

Share this post


Link to post
Share on other sites
Quote:
Original post by jezhamOnly the nearest and furthest triangles appear effected.

It just looks like the lighting is fine in some places due to the camera angle. If you could see the floor you'd see that these errors are everywhere, regardless of distance form the camera.

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