Point light shadows at last

This has been requested numerous times, so i finally stepped in and made something that works.

This is far from a perfect solution, and enhancements are already in my mind, but i think having it as a basis is good enough.



http://i.imgur.com/EhqQT.jpg?1



This is using 6 different shadow maps, one for each direction. I plan to make it work with a cubemap, that should be faster.

Also i duplicated a lot of code from the PSSMRenderer so i’m gonna refactor this a little bit.

The API should stay the same though.



So basically you have now a PointLightShadowRenderer and a PointLightShadowFilter (using one or the other depends on how many objects cast and receive shadows like for PSSM)

You can check the usage in the test case called, guess what, TestPointLightShadows

http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestPointLightShadows.java



it’s basically like the PSSMRenderer but instead of setting the light direction you just feed the processor/filter with the light itself.

I plan to do this for the pssmRenderer too, it allows to set the position of the light on each frame so if the light moves, the shadows also move.



One more thing, this feature already exists with the PSSMRenderer but it’s more likely that people will want it with pointlight shadows :

If you want several light to cast shadows you have to make a processor/filter for each one.

BUT, you have to set pointLightShadowRenderer.setFlushQueues(false) on all the processors except the last one.

This avoid the shadow queues to be flushed after rendering the shadows so another processor can use the shadow queues.



Feel free to make suggestions, ask questions, report issues, give some hugs

30 Likes

Looks really nice. I’d do some metrics on the cube map vs 6 shadow maps though, I saw an article a few months ago and they said they tried both and found 6 shadow maps faster. Obviously results will vary so it would need testing in the JME3 environment (and maybe even on a range of hardware) to see which way it goes here.

Thanks nehon! This is awesome!

Niceness

@zarch said:
Looks really nice. I'd do some metrics on the cube map vs 6 shadow maps though, I saw an article a few months ago and they said they tried both and found 6 shadow maps faster. Obviously results will vary so it would need testing in the JME3 environment (and maybe even on a range of hardware) to see which way it goes here.

oh really?
I'll test it then. The main issue with 6 maps is that there is a lot of branching in the shader to find which map and matrix to use.
It appears you can alleviate this with a cube shadow map and some magic math trick.
Any chance you have a link to that article? Sounds quite interesting.

I guess ti depends on the modernness of the graficcard, current generation card have no real penalty for branching anymore. (As that would harm cuda, opencl very much)

Let me see if I can find it. It was in the context of deferred shading I think.



Yep, found it:

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html



See section 9.3.4



Hmmm, seems I did mis-remember slightly, it turns out they found doing 6 spotlights was better than 1 point light for deferred shading so all their point lights were done that way in the end. Not quite the same situation.

Awesome stuff :smiley:

Someone has been busy :slight_smile: Looks great!



Is there a difference between a regular shadow map and a PSSM map with no spilts? Just thinking about the name of the shadowrenderer/filter.

@kwando said:
Someone has been busy :) Looks great!

Is there a difference between a regular shadow map and a PSSM map with no spilts? Just thinking about the name of the shadowrenderer/filter.

the main difference is the lights matrix., PSSM use directional light so the light view space is a space in parallel projection.
Here each light view space is a regular pyramidal frustum with a 90 degrees fov.

I'd like to keep the processors separated and just make them extend an abstract one that have the common features.
1 Like

Orgasm, nuff said.

This is so awesome! I could never get the shadow map displayed properly after rendering. And after about 4+ hours of reading, trying, reading, trying I put off finishing this. Yay!!! Now I don’t ever have to!

nehon you are the glue keeping jME together!



awesome stuff :slight_smile:

Yes, yes yes!



Thanks man.

great!! and thanks!!



In the code I can see only one PointLight per filter is allowed, but can I add two filters from multiple point light shadow?? I tried but doesn’t work …



any suggestion?

yep, wait for the next commit



There was an issue preventing multiple lights from casting shadows



But still it’s gonna be one filter per light yes

1 Like

This is pretty awesome! :slight_smile:



I have a question,


If you want several light to cast shadows you have to make a processor/filter for each one.


New processors/filters for every lights...is this overhead due to the use of forward rendering system?

actually it’s overhead because we want to be compatible with opengl2.0 hardware.



Right now if i want one pass to render all shadows i have to feed the shader with textureArrays, and this is not possible with glsl beyond 1.3 (open gl 3.0)



Maybe I’ll make a solution later, but for now i’m focusing on making it work and maintainable.

1 Like

What depth precision do you need? If 8 bit is enough it would be possible to calculate 4 lights in one pass using a simple texture even on gl2.0

8 is only 256 levels, I seriously doubt that is enough (although I’m sure nehon will confirm). 16 bits on the other hand might be achievable.