PDA

View Full Version : Multiple lights/shadow maps deferred rendering?



nickels
06-14-2010, 09:47 AM
So this (rainy) weekend I ventured into multiple lights with cascading shadow maps and discovered the limits of shaders. I ran into the per vertex shader out variable limit trying to pass all the projective texture coordinates down the pipeline to the fragment shader.
I also got into trouble trying to access an array of texture samplers implementing the shadow depth buffers.

each light has a shadow map with up to 6 textures (stored as an array), so six projective coords per light....

All of this has led me to thinking about a deferred approach. Render each light separately...

Anyone tried this? Any thoughts about how well the approach might work?

thanks!

Dark Photon
06-14-2010, 05:10 PM
cascading shadow maps ... ran into the per vertex shader out variable limit trying to pass all the projective texture coordinates down the pipeline to the fragment shader.
That's one way to do it ..."if" you had enough interpolators. But those are precious, and producing "all" texcoords, when you only need 1 or 2 likely, is a bit wasteful.

Another approach that's lighter on varyings is to just pass the eye-space position down to the fragment shader. Then in the fragment shader input your eye-to-light-clip transforms in a uniform array there and do a multiply to produce only the shadow map texcoord (or texcoords) you need based on selected split (or splits if you're rolling your own filtering).


I also got into trouble trying to access an array of texture samplers implementing the shadow depth buffers.
What kind of trouble? Works fine here. Post a little snippet and site GPU and vendor driver version.


All of this has led me to thinking about a deferred approach.
Bit draconian for what problems you had. And comes with its own set of problems too. And I don't think magically solves your shadowing issues.

nickels
06-15-2010, 08:42 AM
Another approach that's lighter on varyings is to just pass the eye-space position down to the fragment shader. Then in the fragment shader input your eye-to-light-clip transforms in a uniform array there and do a multiply to produce only the shadow map texcoord (or texcoords) you need based on selected split (or splits if you're rolling your own filtering).



Good idea, I've been thinking about this and might be able to do something like this. For the cascaded maps, the light coord view matrices are actually all the same except for their 'light eye positions'. This could help compress the data in the fragment shader....

The goal is dynamic global illumination, sort of like:

Stalker deferred rendering (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html)

I was hoping to get at least 3 or 4 lights with shadow maps at full framerates to start, wasn't really able to get even 2 without problems... more than 3 hit the varying limit...

For the moment I'm trying multiple directional lights, each with cascades, so the number of projective coords goes up pretty quickly. I don't know how this will generalize when adding point and spotlights, but the point lights will have likely 6 maps...




I also got into trouble trying to access an array of texture samplers implementing the shadow depth buffers.
What kind of trouble? Works fine here. Post a little snippet and site GPU and vendor driver version.


I've hesitated because I don't want to take the time to reduce the problem to a simple example, but maybe I will fish and post the full shader... Not sure if the problem relates to the arrays or just too many dependant lookups and conditionals...

I will take the warning about deferred to heart and play with the 'super shader' approach some more, thanks!

Dark Photon
06-15-2010, 05:28 PM
I was hoping to get at least 3 or 4 lights with shadow maps at full framerates to start, wasn't really able to get even 2 without problems... more than 3 hit the varying limit...
3-4 lights with standard forward rendering, no sweat, even if one has shadows.

Now when you start talking real-time dynamic shadows from 3-4 light sources, then it's worth stepping back and thinking whether deferred (lighting or shading) might be better. Depends on your problem but maybe.

Thing is with forward rendering gets kinda hard to do the scene render all in one pass (even with shadow gen in other passes) as you're finding out. So you want to accumulate lighting. Maybe at least consider a depth pre-pass with EQUAL Z test for the opaque scene passes, if not a deferred technique altogether (Light Pre-pass or Deferred Shading).

Also, with multiple light sources (all probably being point lights with falloff but maybe one), you can maximize perf by tight-culling to the falloff radius of the point light sources. Again, not so easy to capitalize on in one pass.

nickels
06-16-2010, 08:30 AM
I was hoping to get at least 3 or 4 lights with shadow maps at full framerates to start, wasn't really able to get even 2 without problems... more than 3 hit the varying limit...
3-4 lights with standard forward rendering, no sweat, even if one has shadows.


Yes, with moving the projective coordinate calculation into the fragment shader I was able to get there!



Now when you start talking real-time dynamic shadows from 3-4 light sources, then it's worth stepping back and thinking whether deferred (lighting or shading) might be better. Depends on your problem but maybe.


The wisdom is much appreciated. Its one thing to figure out how to write shaders by nosing through the book, but something totally different to see the big picture!

I am going to work on spot and point lights for the moment, then come back and perhaps try the deferred approach. I hope to integrate the lighting volumes into my collision engine as well, so as each object comes through the shader pipeline it knows exactly the set of lights that it is influenced by and influences (via shadows)!!