StrandedKitty / three-csm

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

Shadow artifacts on flat surfaces #19

Closed kriffe closed 1 year ago

kriffe commented 1 year ago

Shadow artifacts appears on surfaces and are hard to compensate for. Appears for all frustrum split modes, but seems to be worst for lograthitmic

What is the cause? And are there any ways to compensate to remove this?

image

Test in https://threejs.org/examples/webgl_shadowmap_csm.html

swift502 commented 1 year ago

I can't speak for the cause, but this seems to be a common inherent property of most real-time shadow implementations. In Blender's Eevee renderer the same thing happens.

image

The only remedies I know of are the traditional tweaking "near" and "far" shadow distances, and tweaking "shadowBias". I don't see shadowBias exposed in the demo but it should be a setting in the code.

swift502 commented 1 year ago

The logarithmic mode is probably the worst because it has extreme cascade splits that probably aren't useful in many real-world cases. It makes some of the shadow maps unnecessarily huge and therefore very low res, introducing the artifacts.

Do you need to use the logarithmic mode though? The artifacts don't appear in "practical" mode right?

StrandedKitty commented 1 year ago

Hi, it's called shadow acne. You should try tuning shadowBias as @swift502 pointed out. Basically, the less detailed shadow map is the larger shadowBias value should be (I mean value in absolute units, it is possible that you actually need a negative value, I don't remember exactly). And faraway cascades are not detailed at all, so they need a larger shadowBias, but in this implementation all the cascades share the same bias value and you can't specify one per cascade.

The most straightforward way to fix bias for different cascades is to just scale it by camera size. I will look into this, it should be easy to implement.

kriffe commented 1 year ago

The logarithmic mode is probably the worst because it has extreme cascade splits that probably aren't useful in many real-world cases. It makes some of the shadow maps unnecessarily huge and therefore very low res, introducing the artifacts.

Do you need to use the logarithmic mode though? The artifacts don't appear in "practical" mode right?

@swift502 Thank you for the quick reply. Practical mode is good enough. But I get the same artifacts for practical mode in another application so I used the logarithmic mode to illustrate the problem in the open example.

kriffe commented 1 year ago

The most straightforward way to fix bias for different cascades is to just scale it by camera size. I will look into this, it should be easy to implement.

@vHawk Thank you for the suggestions and finally having a name for the problem. I have played around with shadowBias but it tends to give artifacts in other areas instead. Automatic scaling by camera size sounds like a clever way to handle it. Perhaps bias could be adjusted with faraway distance could have a positive impact?

StrandedKitty commented 1 year ago

I've added a slider to tweak shadowBias for you to better understand how it affects shadows. Also, actual bias value is now proportional to cascade camera size, it should help with artifacts in distant cascades.