Shadows are very imprecise, not rendering for smaller objects

Hi,

I am still learning Babylon JS and I’m facing an issue with shadows. I have a ground receiving shadows, and cones casting shadows. The light is a directional light.

var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(1, -2, 1), this.scene);
light.position = new BABYLON.Vector3(-1, 2, -1);
light.intensity = 0.5;
var shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
ground.receiveShadows = true;
var cone = BABYLON.MeshBuilder.CreateCylinder("test", {diameterBottom: diameterBottom, diameterTop: diameterTop, height: height, tessellation: tesselation}, scene);

What I don’t understand is that if the cone is “too small”, then there is either no shadow cast, or one very imprecise. If I scale my cone up, then the shadow is rendered.

Below you can see my scene rendered first with my initial arbitrary scale (the smaller cones do not even have a shadow), then with everything scaled x10, and finally scaled x100.

With everything scaled x10, the smaller cones do have a shadow, though very imprecise. It seems that scaling up more does not change the quality of the shadow. Diameter for the cone on scale x1 is 0.18 to 0.05, height is 0.25. I know it’s “small” but I also thought that in 3D engines unit scaling was arbitrary.

1/ Why is the shadow so imprecise/jagged/aliased? Is there a setting to make it more accurate? (it might be as simple as a boolean to set somewhere on the shadow generator but I’ve been going through the docs, and I probably missed it)

2/ It seems that there is a “minimum” scale at which the shadow is cast. Why? Does that mean I should not have objects smaller than “1”?

Thanks!

EDIT: I noticed that if I change the size of the shadow map from 1024 to 8192, I get acceptable shadows when my scene is scaled x10. I suppose that makes sense in terms of precision. But I still have no shadow at all on scale x1 and I don’t understand why.

EDIT: reproduced here: https://playground.babylonjs.com/#15UN5M#2

It probably is related to the total size of the scene rendered to the map. Despite having a 1024 or 8192 size texture even with only 2 objects, if they are really far away from each other, we would loose lots of precision with almost only empty space in the map.

The way around would be to use cascaded shadow maps (@Deltakosh :slight_smile: will kill me at some points for having on my todo list since I started on Babylon)

In your case, you could think about duplicating the maps and placing some cluster of neighbours objects inside to let them be more precise per area.

2 Likes

What do you mean by “really far away” objects? I don’t think that is the case for me?

I have made this playground to make things easier:

https://playground.babylonjs.com/#15UN5M#2

Please note how the larger cones do have a shadow, but the smaller cones do not. Why not?

the extends of the scene are pretty large resulting in not enough precision to draw the small objects. You can find a nice article here: Cascaded Shadow Maps - Windows applications | Microsoft Docs

This is what we need to implement to solve your issue.

I see… I think I understand the concept/issue. And it seems that there is nothing built-in that can address the issue? As I’m just starting learning Babylon, and have no extensive experience with 3D in general, I have no idea how to implement such a thing myself.

So far I have a workaround, which is to have a map sized at 8192 (even though I’ll admit I have no idea what the impact is in terms in loading/performance/size compared to 1024) AND scale the whole scene x4 (for some reason anything below the shadows will not show or show very, very degraded - and anything higher doesn’t seem to do much of a difference).

Yup it is definitely an area open to improvment.

Ok, well, cool, thank you for your help!

1 Like