Shadows, receiving shadows vs point light

Hi guys:

Need help, ran into a wall with the CSM implementation. I got the codes and maths working for the first cascade (weird shadows but it seems like its working). The problem:

Currently, a shadowgenerator uses 1 shadowmap per light and the customrenderfunction call uses said light for viewprojection matrix calculations. see below:

this._shadowMap.customRenderFunction = this._renderForShadowMap.bind(this);

In CSM, for n cascades, there are n shadowmaps. So I’ve implemented it via an array of shadowmaps/RTTs.

this._cascadeShadowMaps[index].customRenderFunction = this._renderForCSMs.bind(this);

So far so good, but when it comes time for the customrenderfunction to coimpute the projection matrix, it does not know which shadowmap to work on. Usually, you’d expect to pass an arrayindex or some form of data thrhu, like so:

this._cascadeShadowMaps[index].customRenderFunction = this._renderForCSMs(index).bind(this);

But from the RTT source, it expects the customrenderfunction to be
public customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>, beforeTransparents?: () => void) => void;

So this._renderForCSMs(index).bind(this); throws compiler errors. I’ve searched thru the entire bjs source on github but seen no other RTT arrays with a similar use case. I can live without passing the index arg as long as there is a way for me to access the shadowmap.name with the render function, I can parse it to get the index value but even that is proving difficult.

Sorry if this seems like a trivial problem, I’m not the most TS savvy coder, so any help is appreciated.

edit: made a pg: Babylon.js Playground to illustrate the problem.

I don’t see the problem with the PG?

If at the end of the PG you call:

    cascadeShadowMaps[0].customRenderFunction();
    cascadeShadowMaps[1].customRenderFunction();

It does display the right values in the console.

1 Like

My bad. The PG is a poor port from the TS codes which doesn’t show the problem. @sebavan has helped me track it down. Apparently, I made getShadowMap return the first map in the csm array to temporarily test the maths. That was last week. And I forgot about it, so the scene was always getting only the 1st shadow map, lol.

Now I have to figure out what getShadowMap should return for CSM w/o breaking back compat.

Boom ba da Boom… test scene of a 100 instanced spheres on a 100 x 100 sized ground plane, no filters, 1024 map size. Directional light, sphere has no material.


default: var shadowGenerator = new BABYLON.ShadowGenerator(1024, light);

var shadowGenerator = new BABYLON.ShadowGenerator(1024, light, 4);
4 is the maximum number of cascades atm.

4 Likes

Woot! can’t wait to see it

1 Like

sorry, boss…my cpu cooler died, I think. pc innards look like a pigeon just shat all over it. It’ll be a while before I can submit the PR. :frowning:

Ohhhhh no feel sorry for you… Good luck with that !

1 Like

Yay!, I live again ! So quick update: 1st pass CSM implementation is almost done, only left with the shimmering artifact. I don’t know if I want to tackle blending and I know I don’t want to do the filtering since I’m not the best person for the job.

Anyways, for now, I’m setting the usage as

var shadowGenerator = new BABYLON.ShadowGenerator(mapsize, directional light, number of cascades, far);

where number of cascades is bound to 2 to 4. So, 2 or 3 or 4 cascades. And far is the furthest value for the cascade and must be between camera.minZ and camera.maxZ. If far is absent, codes will fallback to camera.maxZ. Lemme know how it sounds or whether you prefer a different syntax.

far is already available on light so I do not think we should add it again in the shadow generator. About the number of cascades I wonder if it should not be a property instead like we do for the rest of the generator config.

1 Like