Skip to content

Implement motion blur feature based on the community plugin#115027

Open
HydrogenC wants to merge 6 commits intogodotengine:masterfrom
HydrogenC:motion-blur
Open

Implement motion blur feature based on the community plugin#115027
HydrogenC wants to merge 6 commits intogodotengine:masterfrom
HydrogenC:motion-blur

Conversation

@HydrogenC
Copy link
Copy Markdown

@HydrogenC HydrogenC commented Jan 16, 2026

This PR implements the motion blur post processing based on the community plugin created by @sphynx-owner . The original repos could be found here: https://github.com/sphynx-owner/godot-motion-blur-addon-simplified and https://github.com/sphynx-owner/JFA_driven_motion_blur_addon.
Closes godotengine/godot-proposals#12258 and godotengine/godot-proposals#2933.
There are some differences compared to the original plugin, notably:

    • Cleaning up of unused resources in shader
    • Cleaning up the code
    • Changed some uniform constants to specification constants, enabling loop unrolling, so the performance is better

This PR is co-authored with @AR-DEV-1 , with me doing the graphics and shaders part and @AR-DEV-1 working with the editor settings parts.
Supported backend: Forward+.

Preview:
image

Docs not yet written, since the API itself may be subject to change during review. Docs will be finished by @AR-DEV-1 after the API itself gets approved.
The current blocker is that the current implementation exposes too many parameters, we may have to scale the number down and make some of them constant instead.

Note

godot-cpp will also be modified with these changes after the the API itself gets approved. The build for the editor with mono on Linux can be ignored for now.

@HydrogenC HydrogenC requested a review from a team as a code owner January 16, 2026 10:00
@HydrogenC HydrogenC marked this pull request as draft January 16, 2026 10:02
@HydrogenC
Copy link
Copy Markdown
Author

Already feature complete and workable, but API might be subject to change. We may want the API to get reviewed first before marking this PR as ready.

@AThousandShips
Copy link
Copy Markdown
Member

AThousandShips commented Jan 16, 2026

All the third-party content needs to be correctly attributed, this currently violates their license

Edit: especially seeing how it's so directly copied you even copied typos and TODOs from the original 🙃

@AR-DEV-1
Copy link
Copy Markdown
Contributor

All the third-party content needs to be correctly attributed, this currently violates their license

I'll do it.

@sphynx-owner
Copy link
Copy Markdown

sphynx-owner commented Jan 16, 2026

Amazing work. I finally got to have a look, and I have a few changes to request:

  1. motion_blur_jitter_tiles should not be an option, that is my bad. It should always be true. Without it the seams between tiles are obvious.
  2. motoin_blur_velocity_depth_test is also a redundant setting, and should be true by default. Again, my bad.
  3. target_framerate, framerate_independent, and uncapped_independence should be reintroduced, as they are key features that users thould be able to play with.
  4. All of the motion separatiion setting, that is all of these
image

should be exposed. Their purpose is not clear, and I take the blame for not communicating them clearly enough. They are actually a key feature that make our motion blur effect as powerful as it is. They allow for movement separation between the camera's movement, rotation, and object's movement, allowing users to configure the contribution of each to the final blur separately!

The thresholds are also a cool feature that expand upon the separation, allowing you to configure a velocity threshold for the "activation" of blur for each of these components. This can yield granular control by the user to keep the game view crisp and blur free unless some extreme motions occur.
Something like this:

2026-01-16.12-51-09.mp4

Since this can be a bit cumbersome to have 6 properties, and yield diminishing returns in terms of granularity, we can consider just having one set of lower and upper threshold parameters that would apply to all 3 components at the same time.

Edit: We can maybe come up with clearer way to expose the framerate related settings. It is not clear what these do and would be hard to communicate through doc comments. Also there are a lot of redundant configurations with them, so I imagine some enum to represent common "framerate modes"

Edit 2: For the framerate modes I am thinking:
NATIVE - the blur is determined purely based on the framerate of the game (final_intensity = intensity)
MIN_FRAMERATE - the blur is determined based on the framerate of the game, but below a minimum framerate limit the amount of blur to that framerate (so it is not abnoxious) (final_intensity = intensity * min(1 / minimum_framerate, time_step) / time_step)
FORCE_FRAMERATE - the blur is determined based on a fixed framerate defined by the user, so even at higher framerate it will maintain the same amount of blur (overblurring, but more consistent). (final_intensity = intensity / (target_framerate * time_step))

For the latter 2 modes, a framerate property should be dynamically exposed.

@sphynx-owner
Copy link
Copy Markdown

I apologize for the bother, I should have been cleaner and clearer about the setup.

@AR-DEV-1
Copy link
Copy Markdown
Contributor

AR-DEV-1 commented Jan 16, 2026

@HydrogenC Please update the PR's description with the following:

(EDIT: THE CHANGES REQUESTED HAVE BEEN MERGED BY THE OP)

@HydrogenC
Copy link
Copy Markdown
Author

HydrogenC commented Jan 16, 2026

All the third-party content needs to be correctly attributed, this currently violates their license

Edit: especially seeing how it's so directly copied you even copied typos and TODOs from the original 🙃

Not really. I made plenty of modifications actually. The TODOs are there because they are not yet resolved so I keep them to hint future contributors. For the TODOs that I have resolved, I already removed them. This doesn't mean that this PR is underworked.
Btw the original author of the community addon @sphynx-owner is also helping us with this PR. Thanks for help. We'll be adding copyright headers for the GLSL files included right over.

@AThousandShips
Copy link
Copy Markdown
Member

This doesn't mean that this PR is underworked.

Nor did I say so!

@jcostello
Copy link
Copy Markdown
Contributor

jcostello commented Jan 16, 2026

Only works for PracticalCameraAttr? Also I notice that then v-sync is disabled I can barely notice the blur

@HydrogenC
Copy link
Copy Markdown
Author

Only works for PracticalCameraAttr? Also I notice that then v-sync is disabled I can barely notice the blur

We can move it elsewhere if required, like to environment. Now it's under practical camera attributes.

@jcostello
Copy link
Copy Markdown
Contributor

Only works for PracticalCameraAttr? Also I notice that then v-sync is disabled I can barely notice the blur

We can move it elsewhere if required, like to environment. Now it's under practical camera attributes.

Yeah I mean, I dont mind that is there, but its not present in PhysicalCameraAttr

@yusuf-123-3
Copy link
Copy Markdown

When rendering driver is d3d12 this happens:
https://github.com/user-attachments/assets/d39eaf15-a490-4aea-be23-e23d49daa6bf

Properties do not appear until you reopen camera_attributes resource:
https://github.com/user-attachments/assets/da753048-45f6-45e3-b705-617775e0ee3d

This one is hard to see but when you run the project with motion blur enabled a little flickering can be seen:
https://github.com/user-attachments/assets/4757bb7e-e30b-47d4-9d7d-d354c5fd97ac

Only camera rotation gives effect:
https://github.com/user-attachments/assets/0cca69eb-285f-4579-96f8-d18538f4a767

I think some properties should be changed in rendering/camera instead of in the camera_attributes:
settings

@sphynx-skillcap
Copy link
Copy Markdown

sphynx-skillcap commented Jan 16, 2026

Wow this is a lot. The second issue can be fixed with calling notify_property_list_changed most likely. The last issue is not even just camera rotation, the entire blur is broken completely WTH.

@yusuf-123-3
Copy link
Copy Markdown

Wow this is a lot. The second issue can be fixed with calling notify_property_list_changed most likely. The last issue is not even just camera rotation, the entire blur is broken completely WTH.

Intensity is set to 100.0 in that clip if you are talking about that

@AR-DEV-1
Copy link
Copy Markdown
Contributor

AR-DEV-1 commented Jan 17, 2026

Only works for PracticalCameraAttr? Also I notice that then v-sync is disabled I can barely notice the blur

I think it is fine in PracticalCameraAttr, as the base class (CameraAttr) has only stuff regarding exposure & auto-exposure & PhysicalCameraAttr also has the same, only with frustum added. So, if required, we could change it.

@HydrogenC
Copy link
Copy Markdown
Author

HydrogenC commented Jan 17, 2026

When rendering driver is d3d12 this happens: https://github.com/user-attachments/assets/d39eaf15-a490-4aea-be23-e23d49daa6bf

@AThousandShips I have a small question. I've done some debugging on this problem and I found removing specification constants fixes the problem. Is specification constants unsupported in the D3D12 backend?

@AR-DEV-1
Copy link
Copy Markdown
Contributor

@AThousandShips I have a small question. I've done some debugging on this problem and I found removing specification constants fixes the problem. Is specification constants not supported in the D3D12 backend?

You may want to also ask @clayjohn

@AR-DEV-1
Copy link
Copy Markdown
Contributor

Properties do not appear until you reopen camera_attributes resource: https://github.com/user-attachments/assets/da753048-45f6-45e3-b705-617775e0ee3d

Is fixed with notify_property_list_changed()

@AThousandShips
Copy link
Copy Markdown
Member

I unfortunately can't help with rendering questions clay would be a better person to respond, and I'm sure he will when he has the time

@sphynx-owner
Copy link
Copy Markdown

@HydrogenC I have a fix for the 4th issue:
image
Until we figure out the framerate modes, this can be removed.

@sphynx-owner
Copy link
Copy Markdown

sphynx-owner commented Jan 17, 2026

In addition, I set up a little side by side of the different blurs because something did not look good, and I found that you did not correctly remove the velocity_depth_test variable in the blur shader, causing overblurring over geometry:
image

2026-01-17.20-38-44.mp4

@allenwp
Copy link
Copy Markdown
Contributor

allenwp commented Jan 17, 2026

sphynx-owner, I'm very happy to see your involvement in this PR, even if just from a testing and review perspective. This sort of testing and insight from an expert on the subject is invaluable to the development of these features! Thank you!

@yusuf-123-3
Copy link
Copy Markdown

yusuf-123-3 commented Jan 17, 2026

Every setting in rendering has this (Fastest/Faster/Fast/Average/Slow/Slower/Slowest/Custom) except rendering/camera/motion_blur/motion_blur_tile_size I feel like it breaks convention

Edit: motion_blur_tile_size does not affect performance that much

AMD Radeon RX 5700 XT - i5-11400F - 16 GB memory

Scene:
Preview Sun and Preview Environment
MeshInstance set to BoxMesh 5 meters away from camera
Camera that constantly rotates

Tile Size  20, Samples  4: 592 FPS
Tile Size 200, Samples  4: 577 FPS

Tile Size  20, Samples  8: 485 FPS
Tile Size 200, Samples  8: 455 FPS

Tile Size  20, Samples 16: 323 FPS
Tile Size 200, Samples 16: 292 FPS

Impact of increasing tile size by 10x:
4  samples, FPS drops by 15 (+0.044 ms)
8  samples, FPS drops by 30 (+0.136 ms)
16 samples, FPS drops by 31 (+0.329 ms)

@HydrogenC HydrogenC force-pushed the motion-blur branch 2 times, most recently from 4d828f1 to 96db643 Compare February 25, 2026 05:13
@allenwp
Copy link
Copy Markdown
Contributor

allenwp commented Mar 2, 2026

I forgot to mention: thanks for providing the generated docs for this PR! That makes it much easier for everyone to start review of the PR. I have been overwhelmed working on HDR ouptut, so I'm not sure if I'll be the person to review this PR, but the public-facing API is critically important to review, as this cannot easily change, if at all, between Godot versions.

I noticed that my previous comment received a lot of confused emojis, so I understand that there might be some confusion about what I wrote. I'll provide some clarification:

I wrote that note from the perspective that is generally taken with all PRs in Godot. This process helps us ensure a high quality, bug-free, maintainable game engine in the long run and is why we ask "Is there a reason why this should be core and not an add-on in the asset library?" in the proposal template. I noticed that the proposal for this PR has notes about how this PR should be better than the existing plugin.

All that said, I was not aware that a decision may have been made to include a motion blur feature in the Godot engine without the need for a plugin. So assuming that this decision has been made, it is still important to verify the performance characteristics of this PR and any differences/improvements/etc. that have been made compared to the plugin. This not only gives validation that integrating the feature into the core engine is valuable, but also ensures that the quality and characteristics of this PR are as-expected.

So, regardless of the exact reasons, seeing some performance comparisons and details regarding any other improvements or benefits compared to the plugin this PR is based off of will still be extremely valuable in the review of this PR.

If others who are interested in this PR are able, it would be good to test this PR with your own project to see how it performs, etc. Once a bug, problem, or limitation has been merged into Godot it becomes much harder to fix later on, so lots of testing of PRs is always appreciated!

HydrogenC and others added 2 commits March 4, 2026 11:06
Graphics part by @HydrogenC, editor part mainly by @AR-DEV-1 & docs mainly by @sphynx-owner

Co-Authored-By: AR <ardev1.deverson@proton.me>
Co-Authored-By: sphynx-owner <61445300+sphynx-owner@users.noreply.github.com>
@Saul2022
Copy link
Copy Markdown

Saul2022 commented Mar 4, 2026

All that said, I was not aware that a decision may have been made to include a motion blur feature in the Godot engine without the need for a plugin.

At the godot priorities, they mention the motion blur pr and that they wanted to add common effects as built in . See https://godotengine.org/priorities/#significantly-improve-post-processing-effects

@AR-DEV-1
Copy link
Copy Markdown
Contributor

AR-DEV-1 commented Mar 4, 2026

All that said, I was not aware that a decision may have been made to include a motion blur feature in the Godot engine without the need for a plugin.

In our priorities, it is clearly mentioned the need for built-in common effects & the motion blur PR is also mentioned there.
https://godotengine.org/priorities/#significantly-improve-post-processing-effects

(Edit: Saul said the same thing as me, I just found about it now)

@passivestar
Copy link
Copy Markdown
Contributor

Tested, works as expected on my end (MBP M1 Max). I already used @sphynx-owner's plugin and found it to give production-ready quality and performance, at least in my testing.

Yeah, the current status is that all of these additional and advanced stuff are actually already implemented in this PR. Now the problem is that the number of parameters is above the number that keeps the effect simple so we have to scale them down

The current set of settings seems mostly fine. Object/movement/rotation multipliers are essential imo, velocity thresholds and framerate modes seem useful too.

The reason why I think it's best to give more control here is that motion blur is a bit of a divisive topic and it's mostly the camera rotation blur that people are more likely to find annoying. It's possible that most don't even know that separate object blur is possible and would prefer to keep it if it was an option in game settings. Framerate modes on the other hand seem to be useful to devs because how blur relates to the framerate is often a hot topic among devs.

I'm unsure about motion_blur_clamp_velocities_to_tile, do we need to expose it or maybe it could just stay on?


I have a nitpick regarding the names of properties and UI, it would be nice to be explicit about movement and rotation referring to camera movement and rotation, and properties could be grouped in inspector like this:

image

You could name properties from generic to specific like this:

  • motion_blur_velocity_multiplier_object
  • motion_blur_velocity_multiplier_camera_movement
  • motion_blur_velocity_multiplier_camera_rotation
  • motion_blur_velocity_threshold_lower
  • motion_blur_velocity_threshold_upper

And then let ADD_SUBGROUP automatically strip away prefixes in inspector like this:

  • ADD_SUBGROUP("Velocity Multipliers", "motion_blur_velocity_multiplier_");
  • ADD_SUBGROUP("Velocity Thresholds", "motion_blur_velocity_threshold_");

Copy link
Copy Markdown
Contributor

@QbieShay QbieShay left a comment

Choose a reason for hiding this comment

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

I'm looking at this and I have some comments.

1st comment: good job everyone! Makes me happy to see motion blur progressing. it was a long and large team effort and it makes me happy to see everyone working together!

A couple of question

  1. Why is it a camera effect and not a world environment effect? Was this dicussed somewhere? what's the rationale?
  2. I see that show in editor for motion blur is a project setting. I wonder if it should be editor setting. Thoughts? If it's project setting it will be synced across collaborators on a project with git.

Critique:

  1. I still feel like the properties about the tile (size and clamping) is not necessary to be exposed to the user. What are the different usecase for those? If they really need to be exposed, they should have more comprehensible names. I still don't understand what they're for.
  2. What passivestar said about the property names. camera stuff should have camera prefix because right now it's extremely unclear of what is what without reading the tooltip
  3. The default camera rotation blur imo should be much lower. I'm part of those people that get motion sick very easily and it's very disorienting as it is now.
  4. I don't understand the usecase for fixed framerate. Sounds like something that was exposed "because why not" more than an actual usecase? If that's indeed the case, it should be removed until there's demand. I may 100% be wrong on this, so if there is a usecase please supply it.
  5. I am a bit confused about reference framerate at 30, can somebody elaborate on why 30 and not 60?
  6. Velocities threshold should be under a toggle instead of changing behaviour when they're both at 0 (unless i misunderstood how they work). It looks like a niche usecase to want to wiggle those manually.

Final thoughts:

I know we've discussed this at length but I still think there should be clearer options for what type of game needs what settings at what value. I understand that racing games, fps games, top down games etc will all have different needs, but as it is right now it's hard to understand the correlation between a property and the kind of game it suits at what value. The naming is a bit aseptic and I think we should sacrifice a bit of precision and technicality in the naming in favor of better clarity for someone that doesn't know in-depth how motion blur works.

@yusuf-123-3
Copy link
Copy Markdown

yusuf-123-3 commented Mar 23, 2026

Why is it a camera effect and not a world environment effect? Was this discussed somewhere? what's the rationale?

Some cameras would need to have it disabled or with different values, for example: if you had low framerate security camera in your game you would want to make it have less intensity or disable it

I see that show in editor for motion blur is a project setting. I wonder if it should be editor setting. Thoughts? If it's project setting it will be synced across collaborators on a project with git.

I agree that it should be in editor settings, I did not think of that before but now that I do it makes a lot of sense, but where should it be put?

I don't understand the usecase for fixed framerate. Sounds like something that was exposed "because why not" more than an actual usecase? If that's indeed the case, it should be removed until there's demand. I may 100% be wrong on this, so if there is a usecase please supply it.

I will use fixed framerate mode in my game, if a player has 500 fps and 120 hz for example they would almost not see or even fully not see any motion blur, fixed framerate mode prevents that

@sphynx-owner
Copy link
Copy Markdown

  1. I still feel like the properties about the tile (size and clamping) is not necessary to be exposed to the user. What are the different usecase for those? If they really need to be exposed, they should have more comprehensible names. I still don't understand what they're for.

I understand if the documentation I added is insufficient, but I am not sure how to improve upon their name, open to suggestions. Tiles size is a "quantity over quality" parameter, and clamping could be removed and be always enabled behind the scenes.

  1. What passivestar said about the property names. camera stuff should have camera prefix because right now it's extremely unclear of what is what without reading the tooltip

I agree with all of passivestar's suggestions.

  1. The default camera rotation blur imo should be much lower. I'm part of those people that get motion sick very easily and it's very disorienting as it is now.

I think since this is a relatively obscure feature, it should not be varied from its complementary movment and object blur parameters by default, however I do think the default intensity in general is way to high. It is set to FULL by default currently, should be at 0.1-0.3.

  1. I am a bit confused about reference framerate at 30, can somebody elaborate on why 30 and not 60?

The reference framerate at 30, combined with the default MOTION_BLUR_FRAMERATE_MODE_CAPPED, means that the motion blur is clamped such that any lower framerate than 30 does not increase the blur. This is a safeguard from otherwise jarring blur levels in cases of lag spikes, a worst case scenario. It could be set to 60 by default if we agree on 60 fps being a better worst case scenario.

  1. Velocities threshold should be under a toggle instead of changing behaviour when they're both at 0 (unless i misunderstood how they work). It looks like a niche usecase to want to wiggle those manually.

I agree that setting the thresholds to 0 being the way to "turn them off" is janky. I am not sure if you are suggesting getting rid of the sliders and replatcing them with toggles, which would not make sense, but I do agree that having a toggle to expose-and-enable/unexpose-and-disable them makes sense.

@QbieShay
Copy link
Copy Markdown
Contributor

I understand if the documentation I added is insufficient, but I am not sure how to improve upon their name, open to suggestions. Tiles size is a "quantity over quality" parameter, and clamping could be removed and be always enabled behind the scenes.

Something like "detailed - balanced - intense"?

The reference framerate at 30, combined with the default MOTION_BLUR_FRAMERATE_MODE_CAPPED, means that the motion blur is clamped such that any lower framerate than 30 does not increase the blur. This is a safeguard from otherwise jarring blur levels in cases of lag spikes, a worst case scenario. It could be set to 60 by default if we agree on 60 fps being a better worst case scenario.

Ok, I need to think more about this but it sounds like it could be "minimum reference fps" then? If I understood correctly

I agree that setting the thresholds to 0 being the way to "turn them off" is janky. I am not sure if you are suggesting getting rid of the sliders and replatcing them with toggles, which would not make sense, but I do agree that having a toggle to expose-and-enable/unexpose-and-disable them makes sense.

I was suggesting to remove the sliders unless the feature is "toggled on" with a bool. One of those bool categories.

@sphynx-owner
Copy link
Copy Markdown

Something like "detailed - balanced - intense"?

More like refined - balanced - sparse, perhaps.

Ok, I need to think more about this but it sounds like it could be "minimum reference fps" then? If I understood correctly

Depending on the framerate mode. In MOTION_BLUR_FRAMERATE_MODE_CAPPED it is that, but it is slightly different if you set the framerate mode differently. Generally it is a reference framerate. We could have different reference framerate properiets that show up based on the selected framerate mode, and name them more appropriately.

I was suggesting to remove the sliders unless the feature is "toggled on" with a bool. One of those bool categories.

sounds good then.

@QbieShay
Copy link
Copy Markdown
Contributor

More like refined - balanced - sparse, perhaps.

realistic - balanced - stylized?

@HydrogenC
Copy link
Copy Markdown
Author

HydrogenC commented Mar 26, 2026

  1. Why is it a camera effect and not a world environment effect? Was this dicussed somewhere? what's the rationale?

'Cause motion blur is like DoF, it's a effect that originates from the camera / human eye instead of something that really exists in the environment. I put it in camera attributes only because DoF is in camera attributes. To be clear, there isn't any blockers that forbid motion blur to be part of environment instead of camera attributes. If it being in environment is more convenient for real-life applications we could migrate it right now.

  1. I still feel like the properties about the tile (size and clamping) is not necessary to be exposed to the user. What are the different usecase for those? If they really need to be exposed, they should have more comprehensible names. I still don't understand what they're for.

It certainly could be removed. AFAIK both Unity and Unreal hardcode this value to a constant. But if we do that we would have to guide those users who really need to tweak this to clone the engine source and edit the shader in the docs.

2. I see that show in editor for motion blur is a project setting. I wonder if it should be editor setting. Thoughts? If it's project setting it will be synced across collaborators on a project with git.

Nice catch. You're right on this.

vec2 current_uv = uvn + vec2(float(i) / render_size.x, 0);
vec4 velocity_sample = textureLod(velocity_sampler, current_uv, 0.0);

// If the depth at the potential dominant velocity is infinity (background or skybox)
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.

this comment should be changed to reflect that it's part of our code base now

<member name="editors/3d/view_plane_rotation_gizmo_scale" type="float" setter="" getter="">
The scale of the outer circle of the rotation gizmo as view plane rotation in the 3D editor. If set to [code]2.0[/code], the outer circle has twice the radius of the XYZ rotation gizmo sphere.
</member>
<member name="editors/3d/viewport_visuals/show_motion_blur_in_editor" type="bool" setter="" getter="">
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.

Needs a description

youfch added a commit to youfch/godot that referenced this pull request Mar 26, 2026
@AThousandShips
Copy link
Copy Markdown
Member

Please use the batch suggestion feature to not create a ton of unnecessary commits and noise

@HydrogenC
Copy link
Copy Markdown
Author

@AR-DEV-1 You can squash all suggestion commits locally and then force push.

@AThousandShips
Copy link
Copy Markdown
Member

After applying the remaining changes

@QbieShay
Copy link
Copy Markdown
Contributor

Related issue, posting it here since motion blur will likely have the same issue. #54518

@sphynx-owner
Copy link
Copy Markdown

sphynx-owner commented Mar 29, 2026

yep, tile size is in pixels, so at higher resolutions, the blur's dilation range would be relatively smaller. This is described in the documentation and expected. The effect itself should still be consistent in other aspects.

Co-Authored-By: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
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.

Port community motion blur addon