Need suggestions regarding how to overcome the limitations of lighting

Started by
35 comments, last by _the_phantom_ 17 years, 9 months ago
With only 8 crap lights in OpenGL (why do they have to put limitations on EVERYTHING, it drives me mad), how do I perform the most effective lighting setup using GLSL? I tried doing it with checking what 3 lights were in range of each of the rendered objects and then assigned their values, but that got pooped as shaders only take a shit low value of parameters, which I find to be utterly despicable. I am begging for suggestions on how to make this possible. I need to render each of my objects with all the possible amount of lights affecting it.
Advertisement
You can draw each light in a separate pass. This way You can have unlimited number of lights in Your scene (and shadows too). Just draw ambient pass first, and the set depth test to LEQUAL and turn on additive blending (ONE to ONE). The render the whole scene with one light turned on (repeat this for every light).
if (time() == $) { $ = 0; }
But, won't drawing the same models over and over present me with two problems:

1. Z-fighting.
2. A humungous strain on the CPU and/or GPU.

Got any pseudocode to post?
Setting depth func to GL_LEQUAL eliminates z fighting (don't use EQUAL as some do). Here is some pseudocode:

SetupTheScene();RenderAmbientPass();glDepthFunc(GL_LEQUAL);glBlendFunc(GL_ONE,GL_ONE);glEnable(GL_BLEND);for (int i = 0; i < NumberOfLights; i++) RenderLightPassUsingLight(i);glDepthFunc(GL_LESS);glDisable(GL_BLEND);


By ambient pass I mean no lights turned on - only ambient component.
Light pass means rendering the scene with i-th light turned on.

Later You can modify it:

SetupTheScene();RenderAmbientPass();glDepthFunc(GL_LEQUAL);glBlendFunc(GL_ONE,GL_ONE);glEnable(GL_BLEND);for (int i = 0; i < NumberOfLights; i++){   RenderShadowsForLight(i);   RenderLightPassUsingLight(i);}glDepthFunc(GL_LESS);glDisable(GL_BLEND);


This algorithm is used almost everywhere now.
if (time() == $) { $ = 0; }
Hmm, this looks quite easy. SetupTheScene(), what would that include?
Quote:Original post by Eldritch
Hmm, this looks quite easy. SetupTheScene(), what would that include?


Setting the modelview matrix and/or other things You do at the begining of each frame.
if (time() == $) { $ = 0; }
Ah, great. Gonna try this right away, the heck with food, I eat code ;)
Keep your fingers crossed.
During the ambient pass, what exactly should be enabled? Should I use shaders at all?

I did the stuff you mentioned, but now I get a very messed up scene. Some polygons are translucent while others are solid, and the lighting looks like big squares of color.
During the ambient pass You typicaly render only the diffuse texture multiplied by some small number representing ambient lighting.
Post a screenshot and we'll figure what's wrong.
if (time() == $) { $ = 0; }
To multipass rendering, this code can helps. I use in that way:
	setPerspectiveMode( camera.xp,camera.yp,camera.zp, camera.xlp,camera.ylp,camera.zlp, camera.degrees );	if ( glIsEnabled( GL_LIGHTING ) ){		int sm = 0; int npass = 0;//npass is the number of passes of the drawing scene.		const unsigned int MaxLightsPerFrame = 4;		for ( int v=0; v<N_MAX_LIGHTS; v++ ){			sm += OE.toeLight[v].enabled;		}		npass = sm/MaxLightsPerFrame; //Will draw 4 lights at each frame		if ( sm%MaxLightsPerFrame > 0 )			npass+=sm%MaxLightsPerFrame;		//cout <<npass<<endl;		for( int n=0; n<npass; n++ ){			if ( glIsEnabled( GL_LIGHT0 ) )				glLightfv(GL_LIGHT0+(MaxLightsPerFrame*n), GL_POSITION, OE.toeLight[0+(MaxLightsPerFrame*n)].position );			if ( glIsEnabled( GL_LIGHT1 ) )				glLightfv(GL_LIGHT1+(MaxLightsPerFrame*n), GL_POSITION, OE.toeLight[1+(MaxLightsPerFrame*n)].position );			if ( glIsEnabled( GL_LIGHT2 ) )				glLightfv(GL_LIGHT2+(MaxLightsPerFrame*n), GL_POSITION, OE.toeLight[2+(MaxLightsPerFrame*n)].position );			if ( glIsEnabled( GL_LIGHT3 ) )				glLightfv(GL_LIGHT3+(MaxLightsPerFrame*n), GL_POSITION, OE.toeLight[3+(MaxLightsPerFrame*n)].position );						drawFunc();		}	}else{		drawFunc();	}	unsetPerspectiveMode();	

where N_MAX_LIGHTS is the maximum number of lights that your game/engine will use at once.

But I'm thinking... Is better use 4 lights at each redraw, or 8 ligths?
Because if I will draw 32 point lights, I don't know wich performe better, draw 4 lights each frame totalyzing 8 redraws, or, draw 8 lights(the maximum provided by the OpenGL implementation) each time, redrawing the scene 4 times?

This topic is closed to new replies.

Advertisement