Is 4 lights too many ?

Hi,

(Note there was a previous post re epth Problem but now we find it’s something else … so a new thread !)

Is 4 lights too much ? … I’ve been working on a major problem with an application that we’re developing. We launched a beta version of our application to find that it failed on many systems. The problem looked like a face culling problem and indeed we found that by disabling culling did correct the problem but that in itself isn’t a viable solution. The appearance of the erroneous culling is dependent on view angle with respect to the face normal and effects only quad surfaces !

Eventually we isolated the problem to the fact that we were using 4 lights … switch one off and the problem goes away … problem is that we need 4 lights !

Now, the main development machine uses a GeForce 2 card and I guess the NVidia drivers were a little old … but they worked and didn’t exhibit this problem. However we upgraded the drivers and voila - 4 lights is too much !

We attempted to produce a minimal subset of our code and that’s attached below … note that our world is offset by -20 on the Z-Axis … little to be gained to explain why that came about - is what it is !

Can anyone tell us what we’re doing wrong, whether you’ve got the same problem or have heard of this before … we’re tearing our hair out at the moment !

Many thanks,

Andrew - SoftSpot Software

Note that it’s in Delphi …

// OpenGL Initialized parameters …
const
Ambient : TGLArrayf4 = (0.70, 0.70, 0.70, 1.0);
Diffuse : TGLArrayf4 = (0.75, 0.75, 0.75, 1.0);
Specular : TGLArrayf4 = (0.50, 0.50, 0.50, 1.0);
begin
glLightfv(GL_LIGHT0, GL_AMBIENT, @Ambient ); // Light 0
glLightfv(GL_LIGHT0, GL_DIFFUSE, @Diffuse );
glLightfv(GL_LIGHT0, GL_SPECULAR, @Specular);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_AMBIENT, @Ambient ); // Light 1
glLightfv(GL_LIGHT1, GL_DIFFUSE, @Diffuse );
glLightfv(GL_LIGHT1, GL_SPECULAR, @Specular);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT2, GL_AMBIENT, @Ambient ); // Light 2
glLightfv(GL_LIGHT2, GL_DIFFUSE, @Diffuse );
glLightfv(GL_LIGHT2, GL_SPECULAR, @Specular);
glEnable(GL_LIGHT2);
glLightfv(GL_LIGHT3, GL_AMBIENT, @Ambient ); // Light 3
glLightfv(GL_LIGHT3, GL_DIFFUSE, @Diffuse );
glLightfv(GL_LIGHT3, GL_SPECULAR, @Specular);
glEnable(GL_LIGHT3);
glEnable(GL_LIGHTING);

glEnable(GL_DEPTH_TEST);

glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

Lights coordinates …

const
LightPos0 : TGLArrayf4 = (-20.0, 20.0, 0.0, 1.0);
LightPos1 : TGLArrayf4 = (-20.0, 20.0, -40.0, 1.0);
LightPos2 : TGLArrayf4 = ( 20.0, 20.0, -40.0, 1.0);
LightPos3 : TGLArrayf4 = ( 20.0, 20.0, 0.0, 1.0);

Lights within main draw routine …

glLightfv(GL_LIGHT0, GL_POSITION, @LightPos0);
glLightfv(GL_LIGHT1, GL_POSITION, @LightPos1);
glLightfv(GL_LIGHT2, GL_POSITION, @LightPos2);
glLightfv(GL_LIGHT3, GL_POSITION, @LightPos3);


// Floor List
glNewList(fGenList, GL_COMPILE);
glColor3ub(80, 80, 80);
glBegin(GL_QUADS);
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f( 0.0, 0.0); glVertex3f(-100.0, -17.0, -100.0);
glTexCoord2f( 0.0, 20.0); glVertex3f(-100.0, -17.0, 100.0);
glTexCoord2f(20.0, 20.0); glVertex3f( 100.0, -17.0, 100.0);
glTexCoord2f(20.0, 0.0); glVertex3f( 100.0, -17.0, -100.0);
glEnd;
glEndList;

I wouldn’t think that 4 lights would be too many, especially on a Geforce2. It “should” go to software driver for any lights not hardware accelerated. However, you are using multiple lights for directional light information that could easily be handled by multitexture capability of geforce2 and above. Nvidia has a paper on some more advanced uses of it, but the technique is pretty easy. http://developer.nvidia.com/view.asp?IO=brdfs I haven’t used a Geforce2 in a long time, so I cannot test the lighting problem myself. You might find out the full range of video cards that you will need to address and then check the chip capabilities and limitations of each. If you are limited to only 2 layers of multitexture vs 4, etc, 4 lights vs 8, etc. Are you sure the Geforce2 card was not an MX version? Get the specifics, for instance a Geforce4mx is NOT equivalent to a Geforce4. If you have any ATIs, also check differences and equivalences to your nvidia boards so that they do not fail either.

you also mentioned the possibilty of driver problems. You could download a previous driver from cnet.com or a driver site that keeps previous versions, or catch a beta release. IF the driver change makes it fail, DO check with your video card maker as they might get it fixed on the next release. If memory serves, and it has been a while, I did test seven lights on a geforce2 GTS, but it has been too long to be sure.

Good luck! Post here if you have additional problems. Note: if you do decide to use multitexture, remember to use smaller textures as you are moving twice as much data down the pipe, or at the very least, smaller lighting texture, just large enough to get the appearance you want and no larger. Memory speed is a limitation on older boards, I’ve been spoiled on the new Geforce4s as the textures flow VERY rapidly, even maximum sized ones.

Are you certain you are specifying the correct winding order for all the quads? It does seem strange that it would only show up when the 4th light was enabled, but it may be worth verifying that the winding order is correct, as that is all that is supposed to matter when you enable culling.

If you are using strips, you should be aware of how the vertices are used in order to achieve the same winding order. Take a simple example of 5 vertices. 0, 1, 2, 3, 4.

Triangle 1 will be: 0, 1, 2
Triangle 2 will be: 2, 1, 3 (NOT 1, 2, 3 like you might expect.)
Triangle 3 will be: 2, 3, 4.

etc.

Edit: I should learn to read the included code more carefully before posting…

I noticed you have a single quad in a list for the floor. Are you tiling that, or is it just the one quad? I’m assuming it is the floor you are seeing the culled faces in?

[This message has been edited by Deiussum (edited 06-10-2002).]