StrandedKitty / three-csm

☀️ Cascaded shadow maps (CSMs) implementation for Three.js
MIT License
296 stars 21 forks source link

Migrating from v1.0.2 to v2.0.0 bugs the shadows #20

Open ultWorld opened 1 year ago

ultWorld commented 1 year ago

image

Hi, i am working on a fork of sketchbook and want to migrate to latest versions of the libraries.

Do you have any idea on what can i do to fix?

ultWorld commented 1 year ago

@swift502 i tried to test a lot on customSplitCallback but unfortunatly i feel that is not the problem anymore. :/

P.S. : This is Vivasvan from your Discord. :)

StrandedKitty commented 1 year ago

Hi, could you please provide a more detailed explanation of your problem? What exactly is broken, what version of three.js you are using in your project, what have you already tried to fix it, etc. Also it would be nice if you could provide a demo.

vivasvan1 commented 1 year ago

There are 2 issues according to me.

1) the character and object start casting very faded and weak shadows on the floor after the migration.

2) there seems to be leak from the edges of the walls. ( Not sure if this is normal or not )

Both are visible in the image.

I am using v0.145.0 for three js https://www.npmjs.com/package/three

Thing i tried:

1) I tried to removing all other light sources keeping only the directional light. (The above image)

2) i tried multiple different customSplitCallback which didn't work.

3) i played around with all other params of CSM which doesn't seem to fix both the issues. ( Reducing the light intensity minimises the issue 2. But its still there. )

Will send you a demo link shortly.

swift502 commented 1 year ago

I believe the only issue is just an extremely large shadow texture size.

How far is the clipping distance of the CSM? Can it maybe be reduced and the shadow map resolution increased?

swift502 commented 1 year ago

Another idea: have you been changing the glb models? are you sure you aren't importing another light sources from the glbs? It kinda looks like there's multiple overlapping shadows, one sharp, and other very blurry:

image

In the vanilla sketchbook demo, nothing is ever perfectly black, like the tunnel shadow in your picture. I don't see how that could happen, except if multiple shadow casters were combined to turn the tunnel floor completely black.

StrandedKitty commented 1 year ago

2) there seems to be leak from the edges of the walls. ( Not sure if this is normal or not )

This is most likely related to shadowBias, try using a larger value. Shadow bias must be adjusted manually for your scene, so try playing with it and see if it helps to reduce leaks.

ultWorld commented 1 year ago

Thank you guys for your reply.

Another idea: have you been changing the glb models? are you sure you aren't importing another light sources from the glbs? It kinda looks like there's multiple overlapping shadows, one sharp, and other very blurry:

@swift502 Yeah I am sure there is not light i removed the hemi-light and i am using your original glb.

How far is the clipping distance of the CSM?

I tried everything from 0 to camera.far( i.e. 1010) ....weirdly this parameter doesnt seem to change anything.

This is most likely related to shadowBias, try using a larger value. Shadow bias must be adjusted manually for your scene, so try playing with it and see if it helps to reduce leaks.

shadowBias: 0.001 - seems to completely removes all shadows above and below tunnel. 0.0001 - Makes the tunnel shadow show on top and also no player shadow on floor.
image 0.00001 - reduces the effect but still like 0.0001 0.000001 - futher reduces the effect of tunnel shadow on top but still no character shadow.

image

ultWorld commented 1 year ago

I wrote this small demo .... why is the shadow still blur in this?

https://codepen.io/vivasvan100/pen/BaxPeLb?editors=1010

not sure but it could be the same effect.

swift502 commented 1 year ago

@ultWorld I think it works just fine. Using the settings from my Sketchbook demo, you get shadows as you see them in my demo.

image

// I had to slightly modify this function, the "target" parameter is new in v2
let splitsCallback = (amount, near, far, target) =>
{
    for (let i = amount - 1; i >= 0; i--)
    {
        target.push(Math.pow(1 / 4, i));
    }
};

let csm = new THREE.CSM({
    maxFar: 250,
    cascades: 3,
    shadowMapSize: 2048,
    lightDirection: new THREE.Vector3(1, -1, 1).normalize(),
    camera: camera,
    parent: scene,
    mode: 'custom',
    customSplitsCallback: splitsCallback,
    lightFar: 5000,
    lightNear: 1,
    shadowBias: 0,
});
csm.fade = true;

As I suspected, your maxFar is far too far (funny, I know), set maxFar to 10 and see how sharp the shadows immediately become.

image

shadowBias really isn't the main issue here, of course you'll have edge leaks if a shadow pixel is as big as the entire wall it's cast from. Same with the character model.

So obviously CSM works, now it's about how you allocate the splits, and how much resolution you give the shadow maps. I believe practical splits don't offer the right split distribution, which is why I always used my own splits. You can also increase the shadowMapSize, with an understandable performance penalty.

image

Finally, in my Sketchbook demo I got away with the highest shadow resolution I could, while already sacrificing a lot of performance. @StrandedKitty always emphasized how "unoptimized" this system essentially is, and that it's performance penalty might always be quite high compared to the results.

swift502 commented 1 year ago

@vivasvan1 Now, are these demo settings the same as in your Sketchbook fork? What is your maxFar in the Sketchbook fork?

swift502 commented 1 year ago

PS: While you can tie shadow maxFar to camera.far, I think most games don't do that. Usually the shadows can disappear quite a bit before camera.far, and it still looks acceptable. And you save lots of shadow resolution and performance.

image

Maybe modern games do it differently, but traditionally I think it's just done like this. Just because in the code pen you set maxFar: camera.far, but maybe that's borrowed from the official CSM examples.

swift502 commented 1 year ago

PPS: The reason the official Basic example works with a 1000 maxFar is because it must be absolutely massive compared to your cube in the codepen, or even the Sketchbook world.

So scaling up your 3D scene should work just as well as lowering the distance parameters in the CSM.

That's my theory anyways.

ultWorld commented 1 year ago

@swift502 Thank you so much. It did work. Amazing work.

As I suspected, your maxFar is far too far (funny, I know), set maxFar to 10 and see how sharp the shadows immediately become.

hahah. Yes, this is correct. This is what was going on in both the demo and my fork. reducing the maxFar to 300 from camera.far worked. Also the leak on the edge seems to be reduced quite a bit.

image

image

You can also increase the shadowMapSize, with an understandable performance penalty.

This is also helps. I changed it 2048 -> 4096. and the shadows look pretty much how i desired. On my laptop the performace drop is hardly noticible but maybe will set it 2048 or even less for mobile devices.

This works now but would it be possible dark shadows like the once you have in your original work?

image

And again thank you so much to both of you. Really appriciate your help <3 :+1:

P.S.

@vivasvan1 Now, are these demo settings the same as in your Sketchbook fork? What is your maxFar in the Sketchbook fork?

This was the perfect question. Its crazy to me how you figured it out only from this :sunglasses:

swift502 commented 1 year ago

Cool!

This works now but would it be possible dark shadows like the once you have in your original work?

What's odd to me that in some places the shadow darkness is correct right?

image

Generally for darker shadows, you would just decrease the hemi light intensity. But you seem to have a "smooth edge" to your shadows, so they go from light to dark at the edges. And I don't know what that's about... Maybe a new feature of the CSM system? 😄

swift502 commented 1 year ago

Oh, well, could it be the new fading feature? Do the shadows look different when you set fade = false? It could just be interpolating between the two closest cascades, I imagine that would look something like this. Just an idea.

StrandedKitty commented 1 year ago

@ultWorld Hi, did you manage to fix these problems with shadows?

vivasvan1 commented 1 year ago

@StrandedKitty yes i did manage to fix it ... check the ongoing PR on the Sketchbook's repository.