Per-Object Motion Blur
https://github.com/bevyengine/bevy/assets/2632925/e046205e-3317-47c3-9959-fc94c529f7e0
Objective
- Adds per-object motion blur to the core 3d pipeline. This is a common effect used in games and other simulations.
- Partially resolves #4710
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 #9000. This is because the prepass buffers are multisampled, and require accessing with
textureLoadas opposed to the widely compatibletextureSample. - 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
MotionBlurBundleto a camera entity.
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.
CI is failing on check bans for some reason. 🤷
Needs rebasing, please
I cannot replicate the CI failure. The output log looks suspiciously bugged as well. Not sure what is going on there.
@aevyrie the associated type name has changed, replace ViewQuery with ViewData.
Can anyone recommend a way to profile performance? I'm dubious to make perf changes without being able to meaningfully measure perf.
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.
I'm working on Metal. 😧
I really wouldn't worry about the perf, lets just leave it as-is.
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.
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.
I'm comfortable with the code quality here, and this is a useful standard rendering feature. Merging :)
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 https://github.com/bevyengine/bevy-website/issues/1305 if you'd like to help out.