Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-Object Motion Blur #9924

Merged
merged 46 commits into from Apr 25, 2024
Merged

Per-Object Motion Blur #9924

merged 46 commits into from Apr 25, 2024

Conversation

aevyrie
Copy link
Member

@aevyrie aevyrie commented Sep 25, 2023

Screen.Recording.2023-12-12.at.1.42.15.AM.mp4

Objective

Solution

  • This is a post-process effect that uses the depth and motion vector buffers to estimate per-object motion blur. The implementation is combined from knowledge from multiple papers and articles. The approach itself, and the shader are quite simple. Most of the effort was in wiring up the bevy rendering plumbing, and properly specializing for HDR and MSAA.
  • To work with MSAA, the MULTISAMPLED_SHADING wgpu capability is required. I've extracted this code from Add handling for more naga capabilities #9000. This is because the prepass buffers are multisampled, and require accessing with textureLoad as opposed to the widely compatible textureSample.
  • Added an example to demonstrate the effect of motion blur parameters.

Future Improvements

  • While this approach does have limitations, it's one of the most commonly used, and is much better than camera motion blur, which does not consider object velocity. For example, this implementation allows a dolly to track an object, and that object will remain unblurred while the background is blurred. The biggest issue with this implementation is that blur is constrained to the boundaries of objects which results in hard edges. There are solutions to this by either dilating the object or the motion vector buffer, or by taking a different approach such as https://casual-effects.com/research/McGuire2012Blur/index.html
  • I'm using a noise PRNG function to jitter samples. This could be replaced with a blue noise texture lookup or similar, however after playing with the parameters, it gives quite nice results with 4 samples, and is significantly better than the artifacts generated when not jittering.

Changelog

  • Added: per-object motion blur. This can be enabled and configured by adding the MotionBlurBundle to a camera entity.

@aevyrie aevyrie added C-Enhancement A new feature A-Rendering Drawing game state to the screen labels Sep 25, 2023
@github-actions
Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@aevyrie
Copy link
Member Author

aevyrie commented Sep 26, 2023

CI is failing on check bans for some reason. 🤷

@JMS55 JMS55 added this to the 0.13 milestone Oct 1, 2023
@IceSentry IceSentry self-requested a review November 17, 2023 19:00
@JMS55
Copy link
Contributor

JMS55 commented Nov 29, 2023

Needs rebasing, please

Copy link
Contributor

@JMS55 JMS55 left a comment

Choose a reason for hiding this comment

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

Shader could avoid some branches, use a better noise (IGN/STBN), and could experiment with some established surface comparison heuristics (plane distance, normals) (commonly used in denoising), but it works well enough and I don't want to block on further, possibly futile, experimentation. I'm happy merging it as-is.

@aevyrie
Copy link
Member Author

aevyrie commented Feb 25, 2024

Can anyone recommend a way to profile performance? I'm dubious to make perf changes without being able to meaningfully measure perf.

@JMS55
Copy link
Contributor

JMS55 commented Feb 25, 2024

Make sure you have a reproducible exact frame setup, and then run it through Nvidia's NSight GPU Frame Profiler, or AMD's equivalent (Radeon Graphics Analyzer iirc). You'll get per-pass timings, as well as statistics on shader occupancy, per-line stalls and timings, etc.

@aevyrie
Copy link
Member Author

aevyrie commented Feb 25, 2024

I'm working on Metal. 😧

@JMS55
Copy link
Contributor

JMS55 commented Feb 25, 2024

I really wouldn't worry about the perf, lets just leave it as-is.

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

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

I didn't look at this too closely yet but it looks fine to me, none of these nits should be considered blocking.

crates/bevy_core_pipeline/src/motion_blur/motion_blur.wgsl Outdated Show resolved Hide resolved
examples/3d/motion_blur.rs Show resolved Hide resolved
examples/3d/motion_blur.rs Show resolved Hide resolved
examples/3d/motion_blur.rs Outdated Show resolved Hide resolved
examples/3d/motion_blur.rs Show resolved Hide resolved
Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

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

This looks good to me, just a couple of nits.

@IceSentry IceSentry 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 23, 2024
@alice-i-cecile alice-i-cecile added the C-Needs-Release-Note Work that should be called out in the blog due to impact label Apr 25, 2024
@alice-i-cecile
Copy link
Member

I'm comfortable with the code quality here, and this is a useful standard rendering feature. Merging :)

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Apr 25, 2024
Merged via the queue into bevyengine:main with commit ade70b3 Apr 25, 2024
33 checks passed
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-Enhancement A new feature C-Needs-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
Status: Done
Development

Successfully merging this pull request may close these issues.

Request add Soft shadow and motion blur function
7 participants