How to do the shadows at the moment

Tried to add shadows to my small test projects.
Turns out all documentation on the wiki uses either SimpleShadowRenderer/Filter or PSSMShadowRenderer/Filter which are both deprecated.

Which is the correct way to make shadows in jme 3.1 beta 1?

mhh looked at the doc, and I realize it’s not clear…
There is one renderer and one filter for each light type.
So if you use a DirectionalLight, you have to use the DirectionalLightShadowRenderer or a DirectionalLightShadowFilter.
I recommend the Renderer to start. The filter may give better perfs in some scenes but comes with many limitations.

So basically this:

/* Drop shadows */
        final int SHADOWMAP_SIZE=1024;
        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3);
        dlsr.setLight(sun); //<==assuming a directional light
        viewPort.addProcessor(dlsr);
3 Likes

The renderer throws an exception if any spatial without a material definition with the “LightDir” is configured to cast/receive shadows (what is pretty obvious looking at the renderer code). Is this a desired behavior?.

About the filter, is it disabling the default antialiasing (the one with the checkbox in the app launcher)?. One enabling the filter the shadows are really crappy and the rest of the scene seems to not be antialiased.

not sure what you mean by this

You have to set the number of sample on the FPP to use antialiasing with filters
fpp.setNumSamples(4) for example for aa x 4

If I: scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive), having the scene any material without the LighDir parameter available (parameter used in the renderer), it throws the exception:

java.lang.IllegalArgumentException: Material parameter is not defined: LightDir
	at com.jme3.material.Material.checkSetParam(Material.java:458)
	at com.jme3.material.Material.setParam(Material.java:474)
	at com.jme3.material.Material.setVector3(Material.java:674)
	at com.jme3.shadow.DirectionalLightShadowRenderer.setMaterialParameters(DirectionalLightShadowRenderer.java:218)
	at com.jme3.shadow.AbstractShadowRenderer.setMatParams(AbstractShadowRenderer.java:569)
	at com.jme3.shadow.AbstractShadowRenderer.postFrame(AbstractShadowRenderer.java:483)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1102)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1145)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:253)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
	at java.lang.Thread.run(Thread.java:745)

This fixes the antialiasing not being performed :D, but the shadows still really bad, is there a way to “fix” this?:

http://i.imgur.com/UyygMix.png

The current filter config is:

DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 4096, 4);
dlsf.setLight(dl);
dlsf.setEnabled(true);

what version do you use?

The one from jcenter: 3.1.0-beta1

mhhh I’m pretty sure I fixed the first issue.
The second is weird considering you use pssm and a 4096 map…
Is you terrain one big quad?
I guess the texture is stretched all over it…
What if you set the terrain to not receive shadows? (just to test)

Well, I deactivated the receive mode for all spatials. The resulting shadows effect is quite better, however, not “perfect”:

If I deactivate the shadow receiving for all spatials the bigger problem is that the shadows are only visible depending on the position on the camera (I’m not sure which is the pattern but the shadows appear and disappear while moving the camera around).
The filter description says: “The expense is the draw back that the shadow Recieve mode set on spatial is ignored”. But then, why deactivating the receive for them changes the filter behavior? O.o

Well the shadow are projected on an area. This area is a merge of the bounding boxes of the shadow recievers. With the filter all that write depth receive shadows. The bigger the receivers the more the shadow map is stretched.
You should split your terrain in several chunks.

Also the “Sadows are not perfect” thing is because your expectation are maybe a bit too high. Do you use any edge filtering? because you should at least use PCF4.

Yes could be that :P. Well, I’m really happy with the resulting effect.

Well, having in mind that the less the geometries in scene, the better the performance, I though that having one only mesh was better, but after some readings I think that this is a bad thought. I’ll try splitting them. Any size (m) sugestion?, maybe 64?

I’m a little be lost with acronyms, what is PCF4?

http://javadoc.jmonkeyengine.org/com/jme3/shadow/EdgeFilteringMode.html

1 Like

Well yes but that’s not always as easy. Splitting the terrain will also allows some chunks to be culled and not rendered at all. So you might end up in a perf boost.

Well that depends too much on the scene, you’ll have to experiment :wink:

Wait, looking at how the scene is composed, I can see that not only the terrain is a quite big mesh but also the all the houses, all the stones… etc. (There is a single big mesh for everything sharing the same material directly from blender). But, if I want to have great shadows I have to separate them in single geometries?, and then, for some optimizations, batch them based on their location?, making chunks? (Well I suppose this is the same as merging them in blender by chunks too)

My outdoor scene is already splitted in 64m chunks and they load per need. Hm… is not too big though. So… I think I’ll have to start trying unmerging all and see how it goes xD.

yes exactly

Thanks for the help :stuck_out_tongue: