You may have got it but, i’m currently working on the shadow system.
I warn you that this post is quite long.
Right now we have only PSSMShadowRenderer for directional light and the BasicShadowRenderer for …directional lights :p.
Both of them are now deprecated.
Here is how the new system works :
There is now one ShadowRenderer and its Filter counterpart for each light type :
DirectionalLightShadowRenderer and DirectionalLightShadowFilter for DirectionalLight
PointLightShadowRenderer and PointLightShadowFilter for PointLight
SpotLightShadowRenderer and SpotLightShadowFilter for …wait for it…SpotLight
Each of them takes a light of the according type as a parameter.
The DirectionalLightShadowRenderer is basically the old PSSMShadowRenderer.
with some small differences :
I had to extract the CompareMode and FilterMode from the clas to make them independent enum.
I changed the name of the FilterMode enum so that there are no confusion with the post filters.
It’s now EdgeFilteringMode and the method to set it is setEdgeFilteringMode.
the method to set the compareMode is setShadowCompareMode.
I made an abstract shadow renderer that holds all the common things related to shadow rendering. It’s totally independent of the shadow technique used. This avoid to have duplicate code and should make it easier to extend for those that are willing to make their own shadow renderer but want to keep the compareMode, filtering, shadow intensity, etc… features.
On the shader side, all the shadow code is now in the Shadow.glsllib and Shadow15.glsl libs, to also avoid duplicate code.
It’s not really gonna change your life, it’s just gonna be a lot easier for me to maintain it.
Of course there are bonus for you, I recently made shadows for point lights and just committed the spot light shadows
So some may ask, when do I have to use the Renderer, when do i have to use the Filter. so let’s go
Renderer vs Filter?
What’s ruining the shadow performance is the fact that basically an object that receive and cast shadows has to be rendered three times :
generating the shadow map (only depth rendered)
rendering the scene
rendering shadows over objects on the scene
The idea behind the filter is to replace the last geometry pass by a full screen pass. So the only geometry rendered is a quad, and with some shader Voodoo the shadows are rendered over the objects on screen. So no matter how many objects to cast shadows onto the post pass has a constant cost. Of course this is mostly interesting when there are a fair amount of objects in the scene.
the pros :
filter is faster on crowded scenes (around 20 objects from the test i made but that can vary depending on the hardware)
cons : filter render shadows to anything that renders depth, so the ShadowRecieve queue is ignored. This can be a real problem when you absolutely don’t want shadows over some objects that write depth.
I recommend experimenting with both and see what’s best for your scene.
There are new test cases for shadows : TestDirectionalLightShadows (old TestPssm) TestPointLightShadows, TestSpotLightShadows
You have to make one processor or filter for each light you want to cast shadow.
I’ll work on a way to combine all the post passes into one.
Here is a list of enhancements I intend to do.
future work :
- optimization : proper frustum culling for point and spot lights post shadow pass.
- proper serialization to be able to edit shadows in the SDK
test case for multiple lights with multiple type of lights.
@jonatan.kilhamn said:
Any idea of when this will make it into the stable build? Right now it seems it's only in the nightly.
This is the announcement that it goes to svn, look out for release posts in the blog to see new releases and their features.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there's emotes that hint otherwise or there's an increased use of exclamation marks and all-capital words.
The test code in the file TestSpotlightShadows.java stopped working with a recent update of JME3. In particular it fails with a null pointer exception at line 116 fpp.addFilter(slsf); where a SpotLightShadowFilter is added to a FilterPostProcessor.
I have tested this on two different Windows 7 machines. If you download JME3, the test code (TestSpotlightShadows) runs fine. If you let JME3 install all the current updates the same code raises an exception.
I have been using a very literal copy of the example code in my application, Is there a revision to how I should be setting up the filter?
@kcmoore said:
The test code in the file TestSpotlightShadows.java stopped working with a recent update of JME3. In particular it fails with a null pointer exception at line 116 fpp.addFilter(slsf); where a SpotLightShadowFilter is added to a FilterPostProcessor.
I have tested this on two different Windows 7 machines. If you download JME3, the test code (TestSpotlightShadows) runs fine. If you let JME3 install all the current updates the same code raises an exception.
I have been using a very literal copy of the example code in my application, Is there a revision to how I should be setting up the filter?
Thanks!
That line cannot possibly be the NPE itself. Can you post the full stack trace?
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.jme3.post.FilterPostProcessor.updateLastFilterIndex(FilterPostProcessor.java:365)
at com.jme3.post.FilterPostProcessor.setFilterState(FilterPostProcessor.java:340)
at com.jme3.post.FilterPostProcessor.addFilter(FilterPostProcessor.java:112)
at jme3test.light.TestSpotLightShadows.setupLighting(TestSpotLightShadows.java:116)
at jme3test.light.TestSpotLightShadows.simpleInitApp(TestSpotLightShadows.java:177)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:744)