Skip to main content
gamedev.net
🔒 Locked

Lights

Started by Aikon Sep 20, 2005 at 9:56 AM 3 replies 1.6k views
Original Post
Aikon
Aikon
Hi, I couldn't find a good answer to the 8 lights limit problem with OpenGL yet. Here are some quotes: "It's 8 dynamic lights *per object*." <-- what are objects? "This is not just 8 lights, but 8 lights per vertex" <-- aha. "Any game that uses standard OpenGL lighting..." <-- what else can you use? "Keep in memory in each room what 8 lights are in there, then use those. The rest won't matter because you can't see them." <-- and what if I have no rooms? (a huge terrain for example.) In fact I often can see more than 8 lights. Look at this: Octagon Engine. You can download the 3MB small engine source+demo. It says how many lights are visible, and it goes up to 15. Another thing with this engine is: I have searched through the code but I couldn't find anything like 'glEnable(GL_LIGHT0);' so what lights does it use? (And it does use OpenGL.) I have built some maps for Half-Life 2 with Valves Hammer Editor, and it was possible to place more than 8 lights. (I know this one sounds stupid...)
mldaalder
mldaalder
The 8 lights thing is 8 lights per vertex.
An object in OpenGL can be a vertex.

This means that you can change the light(s) such as GL_LIGHT0 to something else between each vertex.

There are other things that you can use besides OpenGL lights.
You could do your own light mapping.
Or doing your own per vertex (either on the CPU or in Vertex shader) or per pixel (in a pixel program) lighting.

There was/is an article on FlipCode that discussed (not OpenGL specific) about "doing your own lighting".

I hope that helps.
mikeman
mikeman
Ok, I'll try answer:

Quote:

"It's 8 dynamic lights *per object*." <-- what are objects?


It's what you define it to be. OpenGL is not aware of objects, it's just how you deside to organize your geometry. For a space-like game, it could be planets. It could be the enemies or rooms in an FPS. It can even be a single triangle. One method is that, for every object you render, you turn on only the 8 closest lights to it. If you have too many little objects, you need to update the lights frequently, which costs in performance. If you have a few large objects, you lose in flexibility.


Quote:

"This is not just 8 lights, but 8 lights per vertex" <-- aha.


Not really. The lighting is per-vertex(OpenGL calculates lighting values at the vertices), but you can't call glLightf() or turn on/off lights between a call to glBegin() and glEnd(). It's more like 8 lights per primitive.

Quote:

"Any game that uses standard OpenGL lighting..." <-- what else can you use?
"Keep in memory in each room what 8 lights are in there, then use those. The rest won't matter because you can't see them." <-- and what if I have no rooms? (a huge terrain for example.)


Ok, this is how it is: Lighting is a huge issue. The 8-light per-vertex lighting of OpenGL is just a start. Lighting is nothing more than calculating the sum of ambient,diffuse and specular reflectance of the rendered objects. There are countless ways of how to do this, by combining several features of the API. For example, this is a quick way of how to do 16-light lighting:

glDepthFunc(GL_LEQUAL);//Turn on the first 8 lights here...DrawGeometry();glEnable(GL_BLEND);glBlendFunc(GL_ONE,GL_ONE);//Additive blending//Turn off the first 8 lights and turn on the rest 8 lights...DrawGeometry();


You see that with multiple rendering passes, you can increase the number of lights. Another example: HL2 uses what we call lightmaps, which are used for static lights. The level editor calculates the lighting for the level, and stores it into a texture. In the game, the lightmap is multiplied with the normal textures, and gives the impression of lighting. So you see, here there is no limitation on the number of lights, since the lighting is precalculated and stored.

Also, you can use vertex and/or pixel shaders to do your own lighting, even calculating it for every pixel on the screen and not for every vertex. Generally, the possibilities and techniques are endless.
Aikon
Aikon
EDIT: I wrote this before I read mikeman's post. But I'll leave it here.

Thanks, it helped.

So per-pixel lighting is never done with the standard OpenGL lights?

The OpenGL Lights are dynamic. This means they can move around and cast light onto moving objects. Right? Which game nowadays still uses per-vertex lighting? Can't you have dynamic lights with per-pixel lighting?

I understood that it is 8 lights for one vertex, but I set a fixed position for each of the 8 lights. How can I have another 8 lights for the next scene (and i need more since I used up 8 lights which already have their position)? Do I turn them off in one room and turn them on in the next? I hope not...
PixelPhil
PixelPhil
Hi,

The octagon engine you pointed out is looks like it is doing per pixel lighting with Doom 3 style. The way the Doom 3 lighting works is truly different from the fixed function pipeline of opengl. The process is layed out this way:

1- Clear your screen & Z-buffer with black

2- Draw your entire scene (roughtly front to back) with Z-writing only. Color output is off in this pass and no textures are involved. Modern hardware does that at double speed.

3- For each visible light (Doom 3 lights have a bounding box as weird as it seems so finding the number od visible light is just a matter of doing frustum/portal culling).
3.a- Determine the subset of visible objects that intersects the light
4.b- Draw this subset of objects with a vertex/pixel shader that does per pixel DOT3 bump mapping with specular. The blending for these passes is additive (ONE, ONE).

I skipped the shadows bit for clarity's sake.

OpenGL point lights also have an attenuation factor so you also can deduce their bounding box. By intersecting the bounding boxes of your lights and your objects you can tell which light will influence, you will then only set these lights in the LIGHT_0-7. Most game assume that a chunk of their level or object cannot be lit by more than eight light... and it is a rather safe assumption. Though you can still rely on multiples passes to push that limitation drawing up to eight lights at a time.
Note that you must have some kind of accelerating structure (Areas, octree...) to make your Object-Lights itersection determination efficient. Doing it in brute force won't scale well.

I hope this helps,

Phil

Topic Locked

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

Sign in to reply to this topic.