How to sharpen shadows when camera moves near them?

Hello everyone,

When I use shadows, they often flicker when I move my camera.
It seems they get sharper when I look at them, which is a nice functionality, but it results in severe shadow flickering when I move my camera and blurred shadows when I don’t look at them directly.

Is it possible to sharpen the shadows when the cam moves near them, not when it looks at them?
Thanks.

Shadows are produced by a depth map. Unless you increase the size of the shadow maps, there is no real way of sharpening them. You can smooth them by using different types of dithering techniques (provided in the shadow renderers/filters) However, this doesn’t necessarily produce the effect you’re looking for.

Currently, I don’t think there is a method for dynamically changing the shadow map size (could be totally wrong here… but it requires a rebuild of the buffer, so you will likely have to force a resize event on the screen to reinit the renderer).

Your best bet is to find a happy medium something that looks good up close and doesn’t tank your frame rate. A great example of low rez shadow maps still looking great in a game is Skyrim (as a point of reference).

Eh… bit more info on this (for future reference).

This is semi-based on hearsay, but I believe lighting is going to change soon(ish) to limit the geometries effected by lights based on there area of influence, etc. When this changes, you should be able to use multiple shadow renderers at about the same cost… which would allow you to do some prioritize shadow mapping (i.e. sharpen the shadows closest to your viewport). Anyways… this isn’t totally possible now without a lot of hack-ery, but will be in the near(ish) future.

@t0neg0d
Nonono, I think you misunderstood :slight_smile:

The shadows are getting sharper, but only when I look at them.
What I want is the shadow to get sharper whe I move near them, if possible.

I don’t know how it works, but is it possible that the shadow filter has multiple shadow maps for different things (e.g. one for the whole terrain, one for the things that are closer, …)
At least thats what I believe the 3 stands for:
[java]
new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
[/java]

Please correct me if the shadow maps are used differently.

Have a look at those screens for clarification:
I barely move the cam, but the shadow quality changes quite a bit, which leads to flickering:

What is SHADOWMAP_SIZE set to? It looks REALLY low…

And what dithering are you using? This also looks like it is non-existent.

@t0neg0d

I didn’t use any dithering (=Nearest) for the screenshots to demonstrate the issue more clearly (that’s also why the shadows are so dark).

As for the shadowmap: It’s 8192. The largest I can reasonably select.
But keep in mind: I don’t only need the shadows of the house, but also of the terrian, and this is of course rather big compared to the hut.

That’s what I thought multiple shadowmaps are there for: One for the large stuff (=terrain) and others for smaller stuff that is close to the camera(=houses, bushes, …)

@m41q said: @t0neg0d

I didn’t use any dithering (=Nearest) for the screenshots to demonstrate the issue more clearly (that’s also why the shadows are so dark).

As for the shadowmap: It’s 8192. The largest I can reasonably select.
But keep in mind: I don’t only need the shadows of the house, but also of the terrian, and this is of course rather big compared to the hut.

That’s what I thought multiple shadowmaps are there for: One for the large stuff (=terrain) and others for smaller stuff that is close to the camera(=houses, bushes, …)

Ok… there is a slim possibility that the shadow map size is not being used. A while back, this was hardcoded in one of the shadow renderers at 512 (which is what the shadow map appears to be rendered at in your screen shots). Perhaps @nehon can shed some light on it. At that resolution, you should have some crazy-detailed shadows.

@t0neg0d
Well… I set the shadowmap size to 1024 as an experiment and… just have a look at the disaster: :stuck_out_tongue:

I agree. In this case we gotta summon the dark lord of the shadows, @nehon

wow that’s very strange…Could you show me your shadow init code?

Edit : about how it works it uses PSSM, the shadows are not really split among the geometries, but are split along the camera frustum. 3 maps of 1024 should give you correct results…not …that.

@nehon
[java]
DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(cc.getAssetManager(), shadowmap_size, 3);
dlsf.setLight(sunLight);
dlsf.setEnabled(true);
dlsf.setEdgeFilteringMode(EdgeFilteringMode.Nearest);
dlsf.setShadowIntensity(0.9f);
fpp.addFilter(dlsf);
[/java]

fpp is later added to the viewport. shadowmap_size has been set earlier through an options menu.
I’ve enabled CastAndReceive both on the terrain and on the house.
I’m using the latest nightly.
That’s all the relevant info I can think of right now.
If you have any questions, ask away!

Well your frustum is very large i would say.

Ther are two parameters to limit the shadow range and specify a fadeing, try those.
For far away objects fake shadow either baked into the map, or done with cheap shadow fakes (eg dropshadows) might do the trick.

1 Like

I just had a thought (and it hurt slightly… pity me)! Are you setting the local scale on the rootNode or other nodes attached to your rootNode?

1 Like

Does your ground casts shadows? If so could you try to set it to only receive them?

1 Like

So. After a good night’s sleep I’m back and I tested all of your suggestions:

First, @t0neg0d:
Nope, I’m not scaling very much. The only thing was the house: 1.25x. Setting it to 1x didn’t make any difference.

Second, @nehon:
Yes, the terrain does cast shadows. Setting it to only receive makes a huge difference in terms of shadow resolution of the house - as expected.

Third, @EmpirePhoenix:
My frustum acutally was quite big. Just about 70x what I needed it to be.
While setting it to a smaller value did not help with the resolution of the shadow map very much, it stopped the shadows from switching between two resolutions when I slightly move the camera. If you have a look at the images above: Now it’s always the bottom one displayed.

Your second suggestion was experimenting with setShadowZExtend(…). I have to admit I did not know about this customizations :roll:
While setShadowZExtend didn’t do anything (besides not rendering distant shadows), I used setLambda(1f) and now my shadows up close have a higher resolution.

summary
I think we can consider my issues resolved: No more flickering and a decent resolution. =D
However it seems a limiting factor is the terrain casting shadows. If there is a convenient method already in jME to fake shadows of mountain ranges or something like that, let me now. Otherwise I’ll consider just setting the sun a bit higher so that it doesn’t need shadows and still looks natural.

Thanks everyone!

No it’s not resolved, You shouldn’t have to set the terrain to only receive shadows, it was intended as a test.
That means there is a bug when croping the frustum, when computing the shadow map. I’m gonna look into that.

@nehon said: No it's not resolved, You shouldn't have to set the terrain to only receive shadows, it was intended as a test. That means there is a bug when croping the frustum, when computing the shadow map. I'm gonna look into that.

Maybe I used the wrong words: I meant the result I have is now between acceptable and very good, depending on shadowmap resolution.
It is also acceptable when I turn the terrain shadows on, it’s just not as good. It meant solved my problem, not the bug.

Anyways, if you find bugs I’ll be happy to test them :slight_smile:

Hello,
sorry for ‘reopening’ this topic, but I seem to have the same issues with the directional light shadow filter.
The shadows seem, okay, but when you move, the shadows tend to flicker.

this is how I use the shadow filter:
[java]
DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(application.getAssetManager(), 1024, 3);
dlsf.setLight(directionalLight);
dlsf.setEnabled(true);
dlsf.setShadowZExtend(32); // this was just added for testing, but didn’t change anything.
dlsf.setLambda(1f);[/java]

the filterprocessor is later added to the viewport. I add more filters to the filterpostprocessor, I presume this is ok? Or should you create a filterpostprocessor for each filter?

[video]jMonkey 1413224141 - YouTube

[video]jMonkey 1413225007 - YouTube

the normals of my mesh should be okay, they come from the normals used in the box mesh. Furthermore, after the mesh generation I use:
[java]TangentBinormalGenerator.generate(mesh);[/java]

construction of the chunk geometry
[java]
Geometry geometry = new Geometry(chunkLocation.toString());
geometry.setMaterial(VoxelContext.INSTANCE.getMaterial());
geometry.setLocalTranslation(VoxelNavigation.getWorldChunkLocationFromChunkLocation(chunkLocation));
geometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
//geometry.setShadowMode(RenderQueue.ShadowMode.Receive); // when I uncomment this, all is ok, but the terrain doesn’t cast shadows…
geometry.setCullHint(Spatial.CullHint.Dynamic);
chunk.setGeometry(geometry);
[/java]

does anyone have an idea, how I can resolve this?

It can be related to the order of the filters. Shadows should be first

@nehon said: It can be related to the order of the filters. Shadows should be first

shadow is first.
I used the Shadow renderer instead of the the filter, and all problems are solved now. Although, the performance is bit lower with the renderer then with the filter.