Light Management?

Started by
11 comments, last by Basiror 18 years, 8 months ago
Hi there! I´ve posted a thread about this in the DirectX Forum two days ago, but I guess it was a) a bit of a misnomer ("What lighting / shadowing should I use?") and b) a bit unclear and confusing, because I myself was more confused about what I wanted to know. But now I hope I know better what I want to know ;) So please forgive me for this "kind of a double-post". Now straight to the point: I´m planning a 2D action adventure much like Flashback, Blackthorne, Another World and the old Prince of Persias (but I hope less frustrating ;) ), but with a 3D engine. Furthermore the gameplay won´t be "screen-based" like all the games above were, but with smooth scrolling. Now I´ve been planning and planning and recently stumbled about something quite important that slipped my mind: Lights and how to manage them. I guess there might be about 3 or 4 shadowcasting lightsources and one or perhaps more than one for ambient lighting on the screen at once and a level might well consist of an area as large as about 40 or 50 screens, which could give something between 100 and 200 light sources per level. I guess cutting all the light sources down to the ones affecting the current screen wouldn´t be that difficult, so I guess that doesn´t need too much of an explanation. But I don´t have an idea how I should manage the remaining light sources. I´ve read about two different approaches to use many lights with batching: First one rendered a pass per light, rendering only the geometry affected by the light, and blended those passes together to give the final picture. The second one used a distinct number of the lights that affect the current mesh / part of mesh (if it´s too big to render at once) the most and rendered the batch using those lights. Are there other approaches for that? Can anyone point me to a paper / tutorial showing this approaches or other ones? I´m especially confused about how I would build a scenegraph using those light management approaches. So some help with this would also be appreciated. Some things to consider: - Polycount: The screen will contain something about 24 to 35 tiles of the map (6x4 or 7x5). That is not completely settled yet, but it should be something about that. Each tile can contain a background mesh (wall, wall with column(s), vent shaft, something like that, perhaps animated), a "platform" mesh (things the player can walk on), and a number of "dynamic" meshes (for items, entities, NPC´s, the player character and so on). I think NPC´s and the PC will be made of something between 1000 to 3000 polys, and there will be something like 6 of them max on the screen, other items / entities should be something between 12 (standard crate ;) )and 1000 polys. I think there might be about 20 of those things max on the screen. Polycount for background meshes should be something between 2 and 100 (something very special, but probably much lower), same goes for platform meshes. This adds up to a relatively low expected maximum polycount of 45.000 (which is a real maximum and will be touched never, I guess). Most of the time I think something about 12.000 polys will suffice. - Shadows: I´ve not settled which shadowing technique I will use, but I think shadow maps could do well. Some clues about different techniques and their advantages / disadvantages would be appreciated for sure. What I´m pretty sure about is that I want dynamic shadows badly :) dynamic soft shadows would be even better (which is why I´m thinking about shadow maps). I´ve not yet read too much about lightmaps, but I hope I can get around prerendered lightmaps. So I would love to have a completely dynamically lit level. Thx for reading and for any help in advance!
Advertisement
Lights:
I suggest putting all light sources in level to common "Light Pool". Then, each frame, you collect a list of lightsources currently visible. Then you can do one pass per light, rendering all geometry seen by current light source and blending results additively to framebuffer.

Shadows:
You said you wanted soft shadows, but unfortunately there is no fast enough method
for rendering them in realtime. If you want soft shadows, you'll need to use lightmaps.

Shadow maps are faster than stencil shadows, but they have some disadvantages. For example, for casting shadows from point light sources, you'll need to render shadow cube map, which means rendering all geometry from light's point of view six times. They also suffer from aliased edges. Easiest way to fix this issue is to increase shadow map resolution. There are also techniques like Perspective Shadow Maps (PSM) and Trapezoidal Shadow Maps (TSM), but they don't work well in all situations. PCF filtering helps a bit, but it's natively supported only on nVidia cards. For Ati cards, you need to do PCF in pixel shader.

Stencil shadows have pixel-perfect edges (no aliasing), they work well with all different types of lights, but they consume a lot of fillrate. Also, if you have lots of shadow-casting objects visible, computation of shadow volumes gets quite expensive.

Whatever shadowing method you choose, try to abstract it enough so you can change the method without hassle.

Good luck for your project! [smile]
Thx for your answer!

So you suggest doing the "one-pass-per-light-source" approach for about 4 or 5 light sources, let´s say, one ambient source and 4 "direct" light sources. So I would render the whole scene using the ambient light and add the pass for every direct light to that ambient pass?

I´m still thinking about this shadow mapping stuff. Restricting the shadowcasting lights to spotlights shouldn´t be a problem, since I´m in kind of a 2D environment I could place the spotlight in front of the scene and noone would spot the difference to a normal point light. So this would be a work-around for that pointlight - shadow cubemap mess. One thing I´m further thinking about is restricting the shadowcasting light sources to a fitting number of possible textures in the shader model I´m using, so I could combine the shadowmaps into one "screen-shadowmap" in an extra "pass" which I can then use to directly render the scene using all the shadowmaps.
This wouldn´t make any sense of course with the "one-pass-per-light" approach Centipede suggested and if shadow maps really are too slow too use.
I found an article here at GameDev about soft-edged shadows using shadow maps which looked quite good. Since I thought shadow mapping doesn´t suffer too much from raising complexity of the shadowed scene, I thought this could work.
Article can be found here:
http://www.gamedev.net/reference/articles/article2193.asp

[edit]
I just about another thing:
could I turn the shadow map into some kind of light map by saving the shading of the point in it, including the light color, so I would end up with a complete "light map" I do my look-ups from when I combine all the "shaded shadow maps" together in the "pass" mentioned above?
[/edit]

[edit2]
forget the idea, just plain stupid.... storing color information would destroy the depth information in the shadow map, which is what is needed to make the whole thing work... but could I use the Z-buffer to store the shadow map and render to a color texture to do light and shadow map in one pass?
But I guess that wouldn´t do any good, since rendering the "light map" would be the same thing I do anyway when rendering the scene onto the screen....
[/edit2]

[Edited by - matches81 on August 19, 2005 10:08:04 AM]
Quote:Original post by matches81
So you suggest doing the "one-pass-per-light-source" approach for about 4 or 5 light sources, let´s say, one ambient source and 4 "direct" light sources. So I would render the whole scene using the ambient light and add the pass for every direct light to that ambient pass?

In case you didn't know this already, this is how lights are usually rendered when using pass-per-light-method:

1. Clear screen
2. Turn on z-writes
3. Do an ambient + zfill-pass.
4. Turn z-writes off, but keep z-testing on.
5. Render all lights, using additive blending.
6. Render all objects with "diffuse material", meaning, for example, textures. This time use modulative blending.

Also, SimmerD has written some good stuff about his semi-deferred lighting approach. Check out this thread he made about it.

Quote:
I´m still thinking about this shadow mapping stuff. Restricting the shadowcasting lights to spotlights shouldn´t be a problem, since I´m in kind of a 2D environment I could place the spotlight in front of the scene and noone would spot the difference to a normal point light. So this would be a work-around for that pointlight - shadow cubemap mess.

This sounds like a good idea. You could also cast shadows from directional light sources. Usually one directional light is enough for whole level. This would help cutting down the number of lights needed, which can lead to nice speedups especially if you choose the one-pass-per-light approach.
Quote:
I found an article here at GameDev about soft-edged shadows using shadow maps which looked quite good. Since I thought shadow mapping doesn´t suffer too much from raising complexity of the shadowed scene, I thought this could work.
Article can be found here:
http://www.gamedev.net/reference/articles/article2193.asp

I would not use that method myself. Even though it looks nice in that particular test scene, I think it's not very practical in real game. At least it's propably too slow. Although you could make it an option for those users with beefy video cards.

I hope that clarifies things a bit. [smile]
Quote:Original post by centipede
You said you wanted soft shadows, but unfortunately there is no fast enough method
for rendering them in realtime. If you want soft shadows, you'll need to use lightmaps.


Err, I thought PCF was soft shadowing? Is this and this not considered true soft shadowing then?
....[size="1"]Brent Gunning
Skittleo: Yeah, PCF can be used for soft shadowing, I dunno what centipede was banging on about, because soft shadowing has been done with SMs for quite a while (and a bit less time for shadow volumes).

Quote:I would not use that method myself. Even though it looks nice in that particular test scene, I think it's not very practical in real game. At least it's propably too slow. Although you could make it an option for those users with beefy video cards.


Yeah, don't. The algorithm in general is VERY slow, and just doing more PCF samples in shadow mapping would be much, much faster. Plus, it suffers from poor image quality, and that is not shown in the screenshots because the guy is looking at ONLY the shadow on the ground. For the self shadowing, the image looks very strange because the softness blends to areas that it shouldn't. I had a version where I first compared depths in the blur to fix that, which worked wonderfully, but the algo is just so slow on even higherend cards that it's hard to justify it in almost any circumstance.
Quote:Original post by skittleo
Quote:Original post by centipede
You said you wanted soft shadows, but unfortunately there is no fast enough method
for rendering them in realtime. If you want soft shadows, you'll need to use lightmaps.

Err, I thought PCF was soft shadowing?

My mistake! I have'nt really considered PCF as a technique to produce true soft shadows, but as a way to smoothen aliased shadow map edges.

Well, you can use those as a cheap way of doing it, but if you have even 4 samples, you can get slightly chunky soft shadows. Get up to, say, 16 or more and the shadows get a nice smooth softness to them.
Quote:Original post by centipede
In case you didn't know this already, this is how lights are usually rendered when using pass-per-light-method:

1. Clear screen
2. Turn on z-writes
3. Do an ambient + zfill-pass.
4. Turn z-writes off, but keep z-testing on.
5. Render all lights, using additive blending.
6. Render all objects with "diffuse material", meaning, for example, textures. This time use modulative blending.


thx for the quick guide ;)
What I don´t understand is step 5. You say render all lights using additive blending. Do I consider the normal of the lit surface in this step or do I just "paint a gradient circle" onto the rendertarget?
If I do consider the normals, the result of those passes plus the ambient pass would be something like a "screen lightmap", correct? This would also explain step 6 to me.
So best time to use the shadow maps would be in step 5 for every light? Because if I used the shadow maps in step 5 I would end up with a single "texture" containing all the lighting information for the scene, correct?
Furthermore if I wanted to do some weird post-processing stuff with the lights I could keep the result of every light´s pass and modify it like I want...

Perhaps I got it right, but it surely do feel like I´m getting the grip on it.

@all: Thx for your answers. I´ll just leave that algorithm aside and look at that PCF stuff. I also thought about using a directional light to ease the pain a bit, but how would I render a shadow map for that? Would the projection matrix be ortographic or something like that, since all rays from a directional light are parallel?
so the final product will be used like this:
screen lightmap * surface textures = final picture?

Isn´t that something called deferred shading?

This topic is closed to new replies.

Advertisement