I would like to have vertex lighting for my models from all the lightsources in my map. For map geometry there would be lightmaps and for models vertex lighting (like in many games I think). The problem:
OpenGL supports only 8 lights at a time. I think it wouldn’t be enough in some cases, especially if I would check only 8 closest to camera. Is there a way to get more than 8 lights, or can I just use GL_LIGHT0+n (n>8)?
The second problem: it seems that opengl lighting doesn’t concider distance between model and lightsource, which is bad. Can this be fixed?

I think it wouldn’t be such a big deal to write my own vertex lighting algorithm and passing it to vertex colors, but this way I would miss hw T&L.

You could write your own vertex lighting in a vertex program, you’d get HW acceleration then. But aside that, I’m not really sure, I wouldn’t use OpenGL’s standard lights anyway because they are quite restricted (like only having 8 probably).

-Mezz

8 are enough for 99.99% of the cases, explain why you are the other 0.01%.

yes distance attentuation is in…

Here is my code for the given problem
for the player model find ( use a light grid ) the closet
light position ( better use 2 or 3 light )
and calc the new vertex colors for the given player model
vertex colors (vertex light) is used by HW (opengl)

Me problem is i want to use one lightmap (256x256 cirle form black to white) for all
the static light and i must calc the texture UV coords
I use

// Calc Lightmap UV’s
N = vertex normal
L = vertex light vector (normalized)
dot = dotproduct( N, L )
if ( dot <= 0 ) U = V = 0.0
else U = V = dot

in the same function -> CalcVertexLighting but it looks horrible

// For Omnidirection Point Lights
// This function does the vertex lighting calculations of a given object
// pVertices = global pointer to all Vertices from all objects
// pVerticesColors = global pointer to all Vertices Colors from all objects
void CGLObject3ds::CalcVertexLighting( Light3DS *LightObj )
{
static Vector3D lightDir;
static int i;
static float dist, radius, ratio, dot;
static float cr,cg,cb;

``````// for 3ds Omni Light - intensity is the 3ds multiplier
// 1800.0f make it bigger

// This loop goes through all Vertices in the scene
for( i=0; i &lt; numOfVertices; i++ )
{
// Check for visibility (Front Face)
lightDir.x = LightObj-&gt;pos.x - pVertices[i].x;
lightDir.y = LightObj-&gt;pos.y - pVertices[i].y;
lightDir.z = LightObj-&gt;pos.z - pVertices[i].z;
``````

// myVectorMath.Sub( &LightObj->pos, &pVertices[i], &lightDir);
myVectorMath.Normalize( &lightDir );
dot = myVectorMath.DotProduct( &lightDir, &pVerticesNormals[i] );

``````	// Check if front faces visible
if ( dot &gt; 0.0f )
{
// Accurate distance check
dist = myVectorMath.Distance( &LightObj-&gt;pos, &pVertices[i] );

// If within radius than calculate the vertices color based on its
// distance from the light, the light color and the lights intenstity
if ( dist &lt; radius )
{
ratio = (1.0f - dist/radius) * LightObj-&gt;intensity;
cr = ratio * LightObj-&gt;color.fRGB;
cg = ratio * LightObj-&gt;color.fRGB;
cb = ratio * LightObj-&gt;color.fRGB;

// Befor this - pVerticesColors[x].x was filled with a base light color ( 0.3f, 0.3f, 0.3f )
if ((pVerticesColors[i].r += cr) &gt; 1.0f) pVerticesColors[i].r = 1.0f;
else pVerticesColors[i].r += cr;
if ((pVerticesColors[i].g += cg) &gt; 1.0f) pVerticesColors[i].g = 1.0f;
else pVerticesColors[i].g += cg;
if ((pVerticesColors[i].b += cb) &gt; 1.0f) pVerticesColors[i].b = 1.0f;
else pVerticesColors[i].b += cb;
}
}
}
``````

}

“8 are enough for 99.99% of the cases, explain why you are the other 0.01%.”

Consider a map, where is lets say 5 lights visible, then think there’s 5 players shooting at each other and there’s a light from every gun flash. And this is a small scene if comparing to quake3 or similiar fps.

think, just think. do you need more than 8 lights per triangle? no. do you think you need more than 8 lights per mesh? not at all… and a map, you draw at once => you need all the lights there…
how do you draw it at once? normally you cull unused stuff away, and draw each group of faces with different textures individually, so again, you can find the 8 most important lights for the current chunk of the map you draw…

you don’t need 8 lights.

If you had a green light, a blue light and a red light then you would end up with a white vertex, if you added another white light then it would just be a little brighter.

If you had 8 lights and added another one the difference would be very little, add to that your texture map the difference even less. Running in 32bit color wouldn’t give you enough color range.

And if you use more than 8 lights think how slow it would be.

Originally posted by Tim Stirling:
[b]If you had a green light, a blue light and a red light then you would end up with a white vertex, if you added another white light then it would just be a little brighter.

If you had 8 lights and added another one the difference would be very little, add to that your texture map the difference even less. Running in 32bit color wouldn’t give you enough color range.

And if you use more than 8 lights think how slow it would be.[/b]

If you have attenuated lighting, then there is every chance you can use up more than 8 lights… especially if they are small ones.

I remember having this argument with Mark Kilgaard about 5 years ago… I believe he lost the argument… Simply because you can’t think of a reason not to use more than 8 lights, doesn’t mean I (or someone else) can’t…

you can use more than 8 lights, but if that little tiny bit of more correct math does be enough to do such a huge performancedrop that you get by using that much lights… you can try it by making an app that does it multipass, then does the optimal say 8 lights per object, subtract that from the “perfect” one, and check the difference… its by 99% not visible at all… so there is no need.
and vertexlighting sucks anyways… doesn’t get bether by adding more sucking lights…