-
-
Notifications
You must be signed in to change notification settings - Fork 97
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
Add support for motion blur #2933
Comments
I thought I'd made such a proposal, but apparently not. Seconding. |
Yes I also thought I'd seen a proposal for this but couldn't find one Is Godot 4.0 meant to be feature-complete by now? If so then I think this will probably be implemented in 4.1 since temporal stuff doesn't really work well in a forward renderer |
Feature Complete only when it gets to Beta, still in pre alpha stage.. |
Per-object motion blur requires the rendering backend to expose motion vectors, which is not planned for 4.0 but for a future 4.x release. |
TAA and motion vectors are now available |
Indeed, but I don't think motion blur will be implemented in 4.0 unless a contributor steps up to do the required work. It's more likely to happen in a future 4.x release. |
Additionally, current motion vectors implementation is incomplete: no motion vectors for skinned meshes and blend shapes, which defeats the purpose of per-object motion blur. |
There will be motion vectors for those eventually 🙂 |
Some technical considerations if anyone is interested in implementing motion blur in Godot:
There's a slideshow about implementing motion blur in Call of Duty: Advanced Warfare. This is also the same slideshow that was used as a reference to implement interleaved gradient noise for shadow map dithering in Godot 4. |
This comment was marked as off-topic.
This comment was marked as off-topic.
@gnat Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead. |
Would also be a good idea to allow subtracting only rotation, or only translation, from motion blur: for first person/third person games for example it's usually good to remove camera rotation motion blur, but you want to keep camera translation motion blur to keep the sensation of speed when sprinting or moving in a vehicle.
This isn't really a solution to the issue - you'll still see the problem happen on the edges of the screen. Regardless, it'll be good to implement this anyway because some games prefer this over subtracting camera motion blur. Destiny 2 does this I think. IIRC the true solution to this is a dot product clamp.
Yes, absolutely, this. Something many many games get wrong, even AAA ones (although in their case probably just not bothering because you can just assume consistent FPS on consoles) |
Did some experimenting and it seems a simple dot product clamp removes most of the objects you're trying to aim at become blurred with camera motion blur artifacts, but some artifacts do remain 🤔
Normal.mp4
Cancelled.mp4
Cancelled.With.Clamp.mp4 |
For reference, here is the objects you're trying to aim at become blurred with camera motion blur problem depicted in engines that have per pixel motion blur (The engine used in the videos is Unity, but this problem happens in all engines that don't explicitly fix this issue, it happens in Unreal as well for example) Normal motion blur: FPS.Normal.Motion.Blur.mp4Camera rotation cancelled motion blur: Fps.Camera.Cancelled.Motion.Blur.mp4Normal motion blur: Platformer.Normal.Motion.Blur.mp4Camera translation cancelled motion blur: Platformer.Camera.Cancelled.Motion.Blur.mp4 |
No absolutely not, this is the exact opposite of how to correctly tackle this. Game framerates especially on PC will vary immensely (often in realtime), and even on consoles they'll differ based on whether performance mode or quality mode is selected. Your motion blur should look consistent regardless of what framerate the game is running at - this is especially important for gamers running the game at lower framerates like 30 FPS - their game shouldn't turn into a smearfest (compared to 60 or 120 FPS) just because they can't run the game at higher FPS.
This is wrong again, an overwhelming majority of (current) games actually implement framerate dependent motion blur. (This is the most straightforward implementation - framerate independent motion blur requires extra effort.) This is easy to confirm on PC by how much smearier and blurrier the motion blur gets on most games, the lower the framerate gets. Unreal is actually the exception - Unity, for example, has no framerate independent motion blur option.
This is probably your (and most gamers) main point of contention - when framerate independent motion blur is implemented, motion blur remains blurry and thick even when you're running at high framerates. And that is an issue that plagues the industry - but the solution for that is for game developers to stop trying to emulate "cinematic" 24 FPS shutter speeds, but rather emulate a high shutter speed, high framerate look, especially in gameplay. But I understand your concern: considering the game industry's track record, what'll probably happen if framerate independent motion blur becomes the industry default is that we'll all be stuck with super blurry smeary "24 FPS" motion blur, even when we're running the game at 240 FPS. Really, the motion blur frame rate/shutter speed should ideally be user controllable. But I know even that's probably asking for too much. 🤷
This is at the heart of our disagreement. You're 100% right about everything you said here - motion blur is not some gimmick but rather a fundamental artifact of any optical system that captures light in a finite amount of time, and shutter speed is absolutely tied to framerate. What you (and many gamedevs) get wrong is that the renderer's framerate is not the same as the framerate of the "camera" you're "shooting" the game with. Computer generated imagery looks fundamentally "wrong" by default¹, so we reintroduce artifacts like depth of field and motion blur. The characteristics of these artifacts are (or should be) based off a conceptual, imaginary "camera" whose attributes we base the look of these artifacts off of. These attributes are identical to the attributes of an actual, real camera. Godot actually has a framework for defining these attributes. That means the framerate and shutter speed of this imaginary "camera" are independent of the renderer's framerate! The renderer could be running at 120 FPS, but if the "camera" is set to 24 FPS, the motion blur should look similar to an actual camera shooting at 24 FPS. The converse is also true: even if the renderer can only run at 30 FPS, if the "camera" is set to 120 FPS, the motion blur should look similar to an actual high frame rate camera shooting at 120 FPS. The renderer's attributes, such as resolution and framerate, are borne out of technical limitations, not out of artistic choice. In an ideal world, games would be rendered at, I dunno, 64k resolution at 20k FPS or something. Your game should retain its look as much as possible independent of resolution or FPS. Otherwise, if your depth of field is resolution dependent, it'll practically disappear when your game renders at 64k! If your motion blur is framerate dependent, it'll practically disappear at 20k FPS! ¹CGI (of which games count as also) conceptually is like filming with a camera that has an infinitesimally small focal length, capturing light in an infinitesimally small amount of time. That's why raw CGI is aliased, perfectly focused at all ranges, and perfectly clear in motion. This isn't realistic and no such camera exists, so we explicitly simulate and add in artifacts like depth of field and motion blur to make it look correct to our eyes. |
I am not just a game developer. I've spent quite a long time working as a CG Generalist: https://www.artstation.com/rawalanche And when I worked at VFX studio, we ran into MB related issues quite often. Ultimately, the only thing that worked reliably was always avoiding mismatch between displayed image framerate and framerate the motion blur is computed for, regardless what that framerate is, and even if that framerate changes within one movie/video. For consoles, the fixed FPS is sometimes fine, if you target specific framerates, but for PC, in vast majority of the games, you have only two options. Either having your game be as you say smearfest regardless of framerate, even if you run at 120+FPS, or just turn off motion blur altogether and get less natural image. Dynamic framerate introduces the "smearfest" only when the FPS drops severely, instead of at all times. And at such extremely low framerates, where motion blur becomes apparent, (usually under 40FPS), the smearing is actually helpful as it covers up lack of motion smoothness. What I mean by helpful is that if you play a game at 30FPS, if you disable motion blur, people will usually not consider it to be an improvement in terms of image clarity and sharpness. It will usually be to the detriment of apparent motion smoothness. On the other hand, if you have 30FPS Fixed motion blur and your game runs at 120FPS, turning it off will result in absolutely massive improvement in clarity and sharpness of image in motion. One more thing to consider is that heavily fluctuating framerates aren't desired behavior. Even for wide range of possible hardware performances, you'd usually want the framerate fluctuation of the game to stay at least within reasonable bounds. Having dynamic framerate would mean that regardless of if player playing the game averages 50FPS or 150FPS, they are getting optimal visual motion blur experience. So the idea here is to not have to choose between lesser evils And I am currently working on a RTS game with semi realistic graphics, which uses dynamic framerate based motion blur to great success: https://www.youtube.com/watch?v=oJAYC5lcC4E There are currently 3 options:
1A. If you set the fixed framerate too low, to 30FPS, the game will just appear smeary and blurry to most players, so turning off motion blur in the settings will be what the majority of them does as the very first thing. Anytime you see almost any streamer try a new game, you can see their entire community shouting at them in the chat to open settings and turn off MB.
I've just made a comparison: Bottom line is that fixed framerate motion blur can never solve the problem of players hating motion blur and turning it off as soon as they install the game. At that point, why even bother and add motion blur to our games? The players almost feel like we're taunting them. Anyway, I am fine with having both fixed and dynamic framerate option as long as the default is the right one. |
I made a quick proof of concept: https://github.com/Calinou/godot/tree/add-motion-blur motion_blur_wip.mp4Testing project: test_motion_blur.zip (requires the branch linked above) It's pretty incomplete and needs a lot of fixes before it can be production-ready though (see commit message). |
I think the discussion has been conflating two completely different use cases for blur.
I think that while both cases should be easy to support with the same implementation, the required minimum or defult should be to implement the practical one (2). This both to keep default settings neutral in regard to stylization, and because for a custom implementation it'd be harder for developers to deal with framerate fluctuations. It's also more likely for the stylistic effect to necessitate reimplementing just for the sake of customization. An intensity multiplier ("shutter speed") should of course be available and tunable at runtime, and with a very conservative default.
This is a good point, and even if risking to clutter the interface with unintuitive knobs I think worthwhile to provide some. Should be fine in advanced project settings.
Far from required and should be good for later consideration. I also see space for cleverness and taking them off the users hands with magical guesswork for both, but again even lower priority. Of course these shouldn't affect rate-independent/stylistic blur.
And while we're on nice-to-haves, this I think is a good option to have on top of everything else and at least in the case of stylistic blur even default to, to simulate the effect of foveated vision that would affect it if the monitor covered more of our field of view. Maybe not disabling it altogether in the middle but a 1.0-0.5 scale, better yet taking a density map like VRS. |
Motion blur will still be applied per frame... frame rate independent motion blur just scales the blur length based on frame rate
I need to clarify, while it's bewildiringly rare in the industry, frame rate independent motion blur is not actually some difficult task that requires advanced integrals or anything like that, as John Chapman outlined it's actually braindead simple: In fact Hugo seems to have already accounted for it in his proof of concept So framerate dependent motion blur will just be framerate independent motion blur will just be |
I'm imagining raw delta leading to whole-screen flashing artifacts on frame drops for this, without some kind of smoothing. Unsure if that's already handled elsewhere in the engine before passing it there. |
in case it's useful for anyone i wrote an implementation of this for my game as a compositor effect. it's not perfect but it suits my game: godot_43_motion_blur_v7.zip. had no idea this proposal existed and there was already a proof of concept impl here, maybe there's room to combine their ideas. @fire also did up a port of my work on this this morning over here https://github.com/V-Sekai/godot/tree/vsk-motion-blur-4.3-beta1
update (v7): fixed edge fading logic to scale the blur instead of mixing the final color |
@shakesoda i... i love you... you're amazing... ok all joking aside i tested the V-Sekai branch and it's an absolutely fantastic implementation. it's not quite production ready, but it's like 90% of the way there; seriously impressive for a first implementation. all the core aspects seem to be there: camera motion blur: Camera.mp4per object motion blur: Object.mp4skinned mesh motion blur: Skinned.mp4pertinent issues: object and skinned mesh motion blur seem to be bugged in some sense, (object) motion blur length seem to be very limited even when intensity is set to very high values foreground objects seem to not be able to "smear" over background objects some artifacting in the motion blur effect itself, hard to describe but they look like pointed streaks within the effect itself the skybox doesn't seem to be affected by the motion blur of course i don't have the wherewithal to figure out if any of these bugs are in the motion blur implementation itself or maybe godot feeding bugged motion vectors into the motion blur, for example but yeah, this is amazing, thank you so much for this. after 3 years of waiting Godot finally has actual motion blur. i could cry 😅 |
🎉 🎉
this is an inherent limitation of the way i implemented it, i can think of some alternative approaches that might handle it better but they'd definitely cost more frame time, likely more than i can spare on my hardware.
i think this was fixed (or at least reduced) when i switched to @Calinou's sample weighting approach, update: the branch is now updated
godot's just not giving correct motion vectors for the sky, seemingly, i noticed this and some other quirks with them - looked unrelated to the effect itself.
glad to be of help, godot's new compositor api is a really big deal for us finally being able to implement these kinds of things! |
Have to agree with @Jamsers, it's very noticeable that the silhouette isn't blurred, seems to be worth more frame time Thanks for working on this! |
Yeah, a little blur in the silhouette would do the trick |
|
i'm looking into adding another pass to deal with the silhouettes based on this paper, although it's not a priority item for me at the moment (as-is, my impl does what my game needs in the time i need it done). i can't spare the frame time for my current games, but i fully agree the option would be really valuable. |
Due to popular demand, discussion has moved in the VFX server https://discord.gg/4JBkykG |
For cross-referencing https://github.com/sphynx-owner/JFA_driven_motion_blur_demo is one of the newer motion-blur experiements. |
Describe the project you are working on
3D project
Describe the problem or limitation you are having in your project
Godot doesn't support TAA or any other temporal effects so quick motion of objects looks unrealistic and too fast.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Motion blur would alleviate this by giving a more realistic and predictable look when objects move fast
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This could be added in the WorldEnvironment but more logically the new CameraEffects resource in a Camera.
If this enhancement will not be used often, can it be worked around with a few lines of script?
There is a shader for motion blur https://github.com/Bauxitedev/godot-motion-blur but it doesn't take into account moving objects, only the movement of the camera.
Is there a reason why this should be core and not an add-on in the asset library?
it is core
The text was updated successfully, but these errors were encountered: