Skip to content

Use less blur for distant directional shadow splits#48776

Merged
akien-mga merged 1 commit into
godotengine:masterfrom
Calinou:directional-shadow-distant-split-lower-blur
Apr 12, 2022
Merged

Use less blur for distant directional shadow splits#48776
akien-mga merged 1 commit into
godotengine:masterfrom
Calinou:directional-shadow-distant-split-lower-blur

Conversation

@Calinou

@Calinou Calinou commented May 16, 2021

Copy link
Copy Markdown
Member

master version of #60186.

This makes the transition between shadow splits less noticeable, specially when the expensive Blend Splits property is disabled. In many scenarios, you no longer need to enable Blend Splits to get good directional shadow appearance.

From empirical benchmarking, this seems to have a small performance cost (average 160.6 FPS over 5 screenshots instead of 163.8 FPS). I'm not sure if this is introduced by benchmarking. It's not very scientific since I carried this out from the editor and its fluctuating frame time information.
Edit: Further testing didn't reveal any performance difference.

This closes godotengine/godot-proposals#2729.

Note: Not cherry-pickable to the 3.x branch, since this relies on the per-light shadow blur feature found in the new Vulkan renderer.

3.x equivalent of this PR (doesn't work with Blend Splits enabled yet): https://github.com/Calinou/godot/tree/directional-shadow-distant-split-lower-blur-3.x

TODO

  • Don't hardcode the blur factors. Instead, calculate them based on the effective "share".
    • By default, the multipliers would be:
      • 1.0 for the first split.
      • 0.5 for the second split.
      • 0.2 for the third split.
      • 0.1 for the fourth (and last) split.
    • These multipliers should change automatically when the split offsets are adjusted in the DirectionalLight.
  • Adapt the mobile renderer shader code as well.

Preview

Note: GI and ambient lighting was disabled to make the difference in shadow rendering more obvious.

Before

Distant shadows have less detail. There is a noticeable "cut" between splits near the lamp posts in the middle of the image.

Old shadows

After

Distant shadows keep a similar level of detail. Despite Blend Splits being disabled, the cut between splits is now much less noticeable.

New shadows

@jcostello

Copy link
Copy Markdown
Contributor

I was about to create a proposal for this. Is this and the blend splits at draft?

@Calinou

Calinou commented Aug 30, 2021

Copy link
Copy Markdown
Member Author

I was about to create a proposal for this. Is this and the blend splits at draft?

Yes, this PR needs to be finished before it can be merged. Note that there's already a proposal open: godotengine/godot-proposals#2729

@Calinou Calinou force-pushed the directional-shadow-distant-split-lower-blur branch from 5af4c62 to f8c168e Compare October 22, 2021 22:11
@Calinou

Calinou commented Oct 22, 2021

Copy link
Copy Markdown
Member Author

Rebased and tested again. Some changes I did:

  • Refactored to avoid repetition.
  • Bias splits' share is now calculated automatically.
  • Copied over the changes to the mobile renderer. Note that light rendering is currently broken there, but it's unrelated to this PR.

The performance impact seems to be unnoticeable in practice.

Before

2021-10-22_23 49 48

After

2021-10-22_23 49 25

@mrjustaguy

Copy link
Copy Markdown
Contributor

Any reason why this PR has been dormant for so long, or just faded into the backlog of PRs to check?

@Calinou

Calinou commented Apr 5, 2022

Copy link
Copy Markdown
Member Author

Any reason why this PR has been dormant for so long, or just faded into the backlog of PRs to check?

It needs a review by a rendering contributor (other than me) 🙂

Comment thread servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl Outdated
@Calinou Calinou force-pushed the directional-shadow-distant-split-lower-blur branch from f8c168e to 825f693 Compare April 10, 2022 18:22
@Calinou

Calinou commented Apr 10, 2022

Copy link
Copy Markdown
Member Author

I applied @clayjohn's suggestions and tested again on both clustered and mobile backends (with and without Blend Splits). It looks good, even when split distances are customized.

PS: I found a way to further improve shadow appearance by scaling the normal bias depending on the split's share. This is in a separate branch for now, but I can include it in this PR if you want: https://github.com/Calinou/godot/tree/directional-shadow-normal-bias-split
With both changes, I'd say Blend Splits becomes unnecessary 99% of the time 🙂

@Calinou Calinou force-pushed the directional-shadow-distant-split-lower-blur branch from 825f693 to e093668 Compare April 10, 2022 18:30
@mrjustaguy

Copy link
Copy Markdown
Contributor

Blend Splits with consistent blur levels alone probably becomes unnecessary for plenty of scenes. If Normal bias change adds to that.. especially if and when godotengine/godot-proposals#3908 (spherical Splits) become a thing... Blend Splits will really be a nearly pointless feature for most use cases.. 😃

@mrjustaguy

mrjustaguy commented Apr 10, 2022

Copy link
Copy Markdown
Contributor

Eh, I've noticed how Shadow Blur quality setting is now very inconsistent in what it's doing...

For example, Soft Shadows Low look the softest, while going towards Ultra generally slowly decreases how soft they are, and the level of graininess is about the same.

Also, I didn't test out the Normal tweaked branch, but this seems to negate the need for #55757 Normal bias setting changes

@Calinou

Calinou commented Apr 10, 2022

Copy link
Copy Markdown
Member Author

For example, Soft Shadows Low look the softest, while going towards Ultra generally slowly decreases how soft they are, and the level of graininess is about the same.

I can reproduce this on the Vulkan Clustered backend, but not the Vulkan Mobile backend. Can you reproduce this on a vanilla master branch and previous 4.0 alphas?

Also, I didn't test out the Normal tweaked branch, but this seems to negate the need for #55757 Normal bias setting changes

The shadow bias still needs to be increased up close, so I think #55757 is still relevant.

@clayjohn

Copy link
Copy Markdown
Member

For example, Soft Shadows Low look the softest, while going towards Ultra generally slowly decreases how soft they are, and the level of graininess is about the same.

This appears to be a regression in master. It looks like the enums are misaligned or something.

@clayjohn clayjohn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Once we resolve that shadow regression in master this will look even better!

@mrjustaguy

mrjustaguy commented Apr 11, 2022

Copy link
Copy Markdown
Contributor

Alpha 6 has no issues, only Clustered has this issue as stated above.

On another note, the Normal Bias PR increases shadow acne considerably in some scenarios, such as on a flat plane when the sun is just rising, however in other cases it massively improves quality. (16k shadow map can easily do 10-20km view distance with it)

And I found why Normal Bias at 2 is a good idea, highly curved objects clear out micro-shadow acne quite well... and the issue that I've reported for Directional Shadows (#55757 (comment)) is no longer effectively present, well in the Normal bias split branch.

@mrjustaguy

mrjustaguy commented Apr 11, 2022

Copy link
Copy Markdown
Contributor

I think I may have figured out why there is such shadow acne appearing on a Plane when the plane is viewed (by the Directional Shadow) from such an angle (85-90 degrees angle from Plane's Normal)
The Shadow Map for that Plane is turning into essentially a Pixel Line, which doesn't have enough information for Shadows to be Acne-free, and there is an extremely a Sharp change in the Depth.

There might be a solution for this, which would be to detect Large differences in Depth on the Shadow Map and based on that increase Bias for the areas of the Shadow Map that are affected..

Here's a Sketch of the base Idea:
Bias

White - Depth Far
Black - Depth Close
Red - Huge difference between Depths of two neighboring Pixels - Increased Bias for any shadows rendered using those, proportional to the difference between Depths, the Higher the Depth Difference, the More Bias (Not Normal Bias, regular Bias) is added

Note: This idea could also be applied to Spot and Omni Lights (especially Omni Lights) to Reduce their Shadow Acne in cases like #55757 (comment)

This makes the transition between shadow splits less noticeable,
specially when the expensive Blend Splits property is disabled.
@Calinou Calinou force-pushed the directional-shadow-distant-split-lower-blur branch from e093668 to 1a41a17 Compare April 11, 2022 17:47
@Calinou

Calinou commented Apr 11, 2022

Copy link
Copy Markdown
Member Author

Tested again after rebasing on latest master. This should be good to merge now.

Before

2022-04-11_19 47 39

After

2022-04-11_19 46 48

Performance is pretty much identical.

Testing project: test_shadow_b.zip

@clayjohn clayjohn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, looks great rebased on master. Great work!

@akien-mga akien-mga merged commit 35d2efc into godotengine:master Apr 12, 2022
@akien-mga

Copy link
Copy Markdown
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use lower shadow blur for distant directional shadow splits

5 participants