Skip to main content
gamedev.net
🔒 Locked

Rendering multiple lighting passes.

Started by cnagle150 Jul 14, 2003 at 4:01 PM 4 replies 550+ views
Original Post
cnagle150
cnagle150
Have a newbe question about blending multiple lighting passes. I''m designing a game engine in Direct3D. I want to be able to have any Object lit by any number of lights. Now Direct3D itself supports up to a certain number depending on what the Device Capabilities are. If I had more lights than what the hardware supported, would I render the object with as many lights as the hardware supported, then turn on blending and rerender the object with different lights turned on?
Sneftel
Sneftel
Yep, that would work. But keep in mind that it would be extremely rare for a single object to have an appreciable amount of light from more than a few sources at a time.


How appropriate. You fight like a cow.
Yann L
Yann L
No, it would not work. Consider a simple lighting equation:

End_Result = clamp(light1 + light2 + light3 + ... + lightn) * diffuse_texture.

Say, your hardware does not more than 2 lights per pass (generally hardware can do much more, but for the sake of simplicity, let''s assume 2). If you split it as you mentioned, the lighting equation would look like this:

Pass1_result = clamp( clamp(light1 + light2) * diffuse_texture )

Pass2_result = clamp( clamp(light3 + light4) * diffuse_texture )

Both blended together (additive):

End_result = Pass1_result + Pass2_result

End_result = clamp( clamp(light1 + light2) * diffuse_texture ) + clamp( clamp(light3 + light4) * diffuse_texture )

See the problem ? The two diffuse_texture modulations are also clamped. That''s not the case in the original equation. The reason is the limited precision of the 8bit framebuffer, the result of each lighting pass will get clamped to 8 bits. The lights can safely saturate, but in this case, the diffuse texture will also.

Now, in practice, the effect you will get is saturation, where it shouldn''t. If you have two white lightsources, both shining on a textured wall, you would expect a brightly lit spot, with the wall texture perfectly visible. No saturation. And that''s in fact what you get with the first equation. But with the multipass technique, you''ll get a big white blob, the wall texture will seem over-exposed. If you do even more lighting passes, the spot will eventually fade to opaque white.

The right way to do it (other than a floating point framebuffer), is by re-arranging your terms. In the first passes, render only lighting, without the objects diffuse texture. They will also saturate. But in this case, that''s no problem, since only lighting is involved. Once you have rendered all your lighting passes, blend in your final textured object, using multiplicative blending. Render it without any lighting at all:

Pass1_result = clamp(light1 + light2)
Pass2_result = clamp(light2 + light3) (blended with pass1, additive)
... etc ...
End_result = diffuse_texture (blended with the framebuffer, multiplicative)

cnagle150
cnagle150
Okay. Assuming I''m implementing a scene from Halo 2. Suppose I had a room with some lights.

Light
0 - Diffuse lighting for entire room. Or maybe none.
1 - Rotating alarm in on the ceiling in the center of the
room. (Might be 3 or 4 spotlights emitted toward the
ground at 120 or 90 degrees to each other.
2 - Flashlight at end of Player''s gun.
3 - Enemy1 flashlight.
4 - Enemy2 flashlight.
5 - Enemy3 flashlight.
6 - Enemy4 flashlight.
7 - Light emitted from explosion.

Rendering Passes:
0 - Render everything with Light 0 on, diffuse lighting.
(non textured)
(Turn on blending, additive)
1 - Render geometry intersecting each spotlight of the
alarm light.
2 - Render geometry intersecting flashlight at end of
Player''s gun.
3 - Render geometry intersecting Enemy1 flashlight.
4 - Render geometry intersecting Enemy1 flashlight.
5 - Render geometry intersecting Enemy1 flashlight.
6 - Render geometry intersecting Enemy1 flashlight.
7 - Render geometry intersecting Explosion point light
bounding sphere.
(Switch blending to multiplitive)
8 - Render everything with texturing turned on.

Would this work?
Yann L
Yann L
Yep, that would work. But you should try to render as much as you can in a single pass. Pretty much every card can do 8 per-vertex lights in a single pass, and much more, if you use your own lighting in a vertex shader. If you want PP light, modern 3D cards have between 4 and 8 texture units. Although it''s a good idea to also support older hardware, make sure to use resources if the card provides them.
silvermace
silvermace
projective texturing in the above senario would be faster (i think)
and give more control over how lights affect each other ...

check it out (although Yann, your gonna have to check me on that..)



A GOOD friend will come bail you out of jail...
but, a TRUE friend will be sitting next to you saying, "Damn, we fucked up."
Ingite 3D Game Engine Home -- Just click it

Topic Locked

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

Sign in to reply to this topic.