Skip to content

Implement percentage-closer filtering (PCF) for point lights.#12910

Merged
alice-i-cecile merged 7 commits into
bevyengine:mainfrom
pcwalton:cubemap-pcf
Apr 10, 2024
Merged

Implement percentage-closer filtering (PCF) for point lights.#12910
alice-i-cecile merged 7 commits into
bevyengine:mainfrom
pcwalton:cubemap-pcf

Conversation

@pcwalton

@pcwalton pcwalton commented Apr 8, 2024

Copy link
Copy Markdown
Contributor

I ported the two existing PCF techniques to the cubemap domain as best I could. Generally, the technique is to create a 2D orthonormal basis using Gram-Schmidt normalization, then apply the technique over that basis. The results look fine, though the shadow bias often needs adjusting.

For comparison, Unity uses a 4-tap pattern for PCF on point lights of (1, 1, 1), (-1, -1, 1), (-1, 1, -1), (1, -1, -1). I tried this but didn't like the look, so I went with the design above, which ports the 2D techniques to the 3D domain. There's surprisingly little material on point light PCF.

I've gone through every example using point lights and verified that the shadow maps look fine, adjusting biases as necessary.

Fixes #3628.


Changelog

Added

  • Shadows from point lights now support percentage-closer filtering (PCF), and as a result look less aliased.

Changed

  • ShadowFilteringMethod::Castano13 and ShadowFilteringMethod::Jimenez14 have been renamed to ShadowFilteringMethod::Gaussian and ShadowFilteringMethod::Temporal respectively.

Migration Guide

  • ShadowFilteringMethod::Castano13 and ShadowFilteringMethod::Jimenez14 have been renamed to ShadowFilteringMethod::Gaussian and ShadowFilteringMethod::Temporal respectively.

I ported the two existing PCF techniques to the cubemap domain as best I
could. Generally, the technique is to create a 2D orthonormal basis
using Gram-Schmidt normalization, then apply the technique over that
basis. The results look fine, though the shadow bias often needs
adjusting.

For comparison, Unity uses a 4-tap pattern for PCF on point lights of
(1, 1, 1), (-1, -1, 1), (-1, 1, -1), (1, -1, -1). I tried this but
didn't like the look, so I went with the design above, which ports the
2D techniques to the 3D domain. There's surprisingly little material on
point light PCF.

I've gone through every example using point lights and verified that the
shadow maps look fine, adjusting biases as necessary.
@pcwalton pcwalton requested a review from superdump April 8, 2024 19:06
@pcwalton

pcwalton commented Apr 8, 2024

Copy link
Copy Markdown
Contributor Author

Before:

Screenshot 2024-04-08 120914

After:

Screenshot 2024-04-08 120819

@superdump

Copy link
Copy Markdown
Contributor

Please don’t merge this until I have reviewed it. It’s something I particularly care about.

@pcwalton

pcwalton commented Apr 8, 2024

Copy link
Copy Markdown
Contributor Author

I looked at three.js. It uses a 3x3 box filter: https://github.com/mrdoob/three.js/blob/6421f3a49ebed3d07de781776f47624e6d26e896/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js#L295-L309

I also looked at Blender. It doesn't seem to have any PCF for point lights at all.

Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl Outdated
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl Outdated
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl Outdated
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl Outdated
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl Outdated
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl
Comment thread examples/3d/3d_shapes.rs Outdated
@SolarLiner SolarLiner added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen labels Apr 9, 2024
Comment thread crates/bevy_pbr/src/light/point_light.rs
Comment thread crates/bevy_render/src/maths.wgsl
Comment thread crates/bevy_pbr/src/render/shadow_sampling.wgsl
@pcwalton pcwalton requested a review from superdump April 10, 2024 07:37
@SolarLiner SolarLiner added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Apr 10, 2024

@IceSentry IceSentry left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tested on windows 10, webgl and webgpu. Everything looks good. Code quality is great. I like changing the names to Gaussian and Temporal. I don't understand the math enough to comment on it though.

@alice-i-cecile alice-i-cecile added this to the 0.14 milestone Apr 10, 2024
@alice-i-cecile alice-i-cecile added the M-Release-Note Work that should be called out in the blog due to impact label Apr 10, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Apr 10, 2024
Merged via the queue into bevyengine:main with commit d59b1e7 Apr 10, 2024
@alice-i-cecile

Copy link
Copy Markdown
Member

Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1298 if you'd like to help out.

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

Labels

A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible M-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Percentage Closer Filtering for shadows

5 participants