-
-
Notifications
You must be signed in to change notification settings - Fork 80
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
Jittery camera movement when physics tick rate doesn't match FPS #241
Comments
Actually, just tried out the Screen.Recording.2024-03-27.at.12.57.01.AM.movFollowing the Feel free to close this issue if it doesn't provide any value; I'd say that the upcoming release fixes the bug. |
Will keep this issue open until the release is out. Every test for this makes a difference, so thanks for sharing the MRP :) |
I experienced some jitter when I tested out 0.6 with 2D camera. Given this comment I wanted to test 0.7 as well, turns out it was much worse. Video of jitterjitter2d.webmSorry for the bad recording, the jitter did not show up with my screen recorder software, so I had to use my phone. |
The way the system works in 0.7 requires a bit of extra setup. So if you're only assigning the Would stay tuned for the release notes of 0.7, which covers what to do in more detail. |
I used the same setup as stated in the docs for 0.6, with the target being a CharacterBody2D. Looking forward to the release! |
In case it helps, I turned the pixel perfect setting on the camera off and changed the _process in the camera and host gd scripts to _physics_process and it works well with both the characterbody2D and rigidbody2D. |
Don't recommend moving the logic to the Would suggest following the steps mentioned in the FAQ |
That was the first thing I tried but 1. It didn't work for pixel perfect cameras and 2. the solution is not the ideal one if the user needs to use the same smoothing paradigm for networking rollback etc which will make the plugin more awkward to use. The fundamental issue IS the tick rate in which the camera is moving if the target is a physics object. Cinemachine solves this by allowing the brain to execute its processes in FixedUpdate as well as LateUpdate (This is important as right now it seems the camera interferes with velocity/position as it locks the rigidbody/transform in place if set up incorrectly) or it has a SmartUpdate feature which will dynamically pick between the two depending on situation. |
After reading your release note I understand the problem you are facing. It can be solved by having an enum that lets the code run in either physicsprocess or process then you can extend that with a smart update by detecting the phantom camera target’s node type and auto switch between the two. |
I won't pretend like I know what, how and most importantly why Cinemachine does all the things it does, so correct me if I'm wrong. Conceptually, cameras (and, by extension, phantom cameras) shouldn't ever be physics objects. Every game object (i.e. ones that interact with the world) you want to render to your game's window should have a) a physics representation and b) a visual representation. There is then a clear separation of concern with a) handling where the physics representation should be after interacting with other physics objects at physics tick intervals (i.e. in In this case, correctly handling networking rollback, or even the object teleporting instantly, is up to b) (albeit obviously with some help from your networking code, etc.). Having a separate node handling solely where the object should be rendered is beneficial for many reasons. As an example, imagine you have a 2D game, and you want a true pixel-perfect camera (i.e. no pixel misalignments - even for moving objects). However, you have a moving object, intentionally with no friction, with a vector of As another example, you can have the physics engine running at 20 ticks per second (wink), and still have smooth motion of objects on the screen at 1000+ fps if b) uses techniques such as interpolation using frame times. So then cameras - objects that should concern themselves with only the visual representations of objects - should update at frame rate intervals (i.e. in Sorry for the wall of text 🤓. |
To back up what @audeck says, jittery in this context isn't an issue with the physics node being jittery as it moves around, but rather the thing that visually represents it, i.e. the Sprite / Model inside of it. I could not for the life of me record actual examples of how Each project includes 2 example scenes, one for 2D and one for 3D, which can be found in the root directory. More concretely, the The 2D and 3D scenes both contain a node, Both projects use an identical project setup of:
The observation from the above projects with those settings should show the one using the If you modify the So I am not confident that a dynamic system that sets the camera to move in |
I understand. I think the issue stems from Godot not having any underlying interpolation for physics. 3.5 had this but is yet to be implemented from what I have read. The engine itself should be responsible for this interpolation under the hood in process_physics but as of 4.2 I still don’t think that has happened. Essentially doing what you guys are doing with smoothing, this should be happening between the rigidbody node and the sprite node with the user having no idea. When it does eventually happen, mimicking the way cinemachine handles this would work. |
Just found out that 2D physics interpolation has been implemented for godot 4.3 godotengine/godot#88424 |
100%, it ideally shouldn't be on the user to figure out how to set it up correctly — as most will be confused until looking it up otherwise. Should hopefully just be a case of waiting for the engine to add that in to improve that usability.
Good idea, will try to run some tests with that and Jolt out at some point. |
I am on the 4.3 Dev 6 snapshot and the issue is still happening when using https://godotengine.org/article/dev-snapshot-godot-4-3-dev-6/ |
@blai30 Did you enable the settings mentioned in the PR?
|
@Nohac Yes, that did not seem to help |
@blai30 Fixed the repository's 2D dev scene for
What's important is not mixing the previous manual interpolation (using either the project's From the upstream discussions it seems that the Godot team wants to prioritize making things as easy as possible for people just getting into Godot/game dev in general. @ramokz To support your previous comment, I think this addon should mirror that and support using |
I tested this now, and it does not work out of the box as @blai30 says, applying @audeck solution fixes it. So I'm not completely sure what the interpolation actually does. With @audeck changes and interpolation disabled, it is a bit more jittery, but it's not terrible. It would be nice to get the godot devs to give an "official" recommendation of what to do in this case. |
Tried out the 4.3 dev6 build as well. @Nohac if you comment out the following code in func _process(delta) -> void:
_player_visuals.global_position = _physics_body_trans_last.interpolate_with(
_physics_body_trans_current,
Engine.get_physics_interpolation_fraction()
).origin This code exists as a manual solution to the lawnjelly's |
Have attached a short demo of having the physics_interpolation_demo.mp4To go back to what @ipinzi proposed, do agree that with this change in Godot 4.3, and assuming it works consistently for others, the |
Yes. The built-in physics interpolation's inherent limitation is that it makes the game's physics run 1 tick behind (in reality it now runs 2 ticks behind, but that's irrelevant for this), since instead of just calculating the physical position and setting the object's That means that during So say we have three physics ticks - #0, #1 and #2 - with the game just after finishing #2. Inbetween #2 and the next tick, the physics node is interpolating between positions at #1 and #2, while the visual node is interpolating between positions at #0 and #1. It is then very easy to introduce jitter with any sort of discrepancy in these positions (mainly due to differing tick rates and FPS), since the camera is following the "invisible" physical node, while the sprite is lagging behind at different distances each frame.
So yes, I'm pretty sure it does, as long as the visual representation isn't trying to do the same thing as well, but with different data. On another note, with the dev scene using physics interpolation, the camera position seems to lag behind the player position by 1 tick (noticeable on very low physics tick rates), but that's material for a separate issue after 4.3. |
That's great news! I'm glad this came together so quickly. It should also help the camera not fight against the interpolation of other physics systems. |
Now we just need the same interpolation to come to 3D 😉 |
Have made a draft PR with the changes to support the Godot 4.3 It technically all works and supports both 4.2 and 4.3, but due to an issue (described in the PR) I won't be merging this in until that gets resolved. From the test included in the PR description, it points to it being a bug in the current Godot implementation of the physics interpolation. |
The PR should now be updated to resolve the aforementioned issue(s). Testing in Godot 4.2 would also be beneficial, mainly just to confirm that there's no regression. |
|
To be clear: is it possible to get a jitter free setup for third person in 3d? The smoothing addon helps, but there is still a vibrating jitter that is very hard on the eyes. I'm unsure if this is at all possible, or simply user error. I'm currently in version 4.3rc1. |
There is jitter for me in the MRP posted by TranquilMarmot, even after upgrading phantom_camera to the latest release: v0.7.2.1. phantomcamtest.mp4 |
Yes, the approach should be no different for any of the follow modes.
That shouldn't happen. Would you be able to share a project that contains the scene, or a video capture of your hierarchy structure and property assignment, specifically the |
Hello! I've also tested this without Phantom Camera, that is, by simply updating a Camera3D's position to the position of a smoothing node, which is following a CharacterBody3D. The behavior is the same as when Phantom Camera is used. I downloaded TranquilMarmot's MRP, updated the phantom_camera addon folder to the current release, updated the script references, then hit play, It doesn't always jitter, but it will always eventually jitter after moving around for a short amount of time. 2024-07-30.16-20-13.mp4 |
Yeah I've noticed a lot of the "jitteriness" is back in my game as well with the recent updates. Since Godot 4.3 added native physics interpolation and the |
So, if I'm reading it correctly, you're experiencing jitter even when not using a Phantom Camera setup; where you're manually updating the position of the
I tried downloading the MRP project as well and updating the addon to the latest release in Godot 4.3 rc1. From the tests I've seen, and even with a 241-07-31.mp4Rerunning the scene with a
Important to note that |
Yep, I've read the Godot issues and have to admit that I don't fully understand what's going on. In your test, why does the jitter clear up after a few frames? Should the jitter be expected to come back when the system is under load? The physics ticks are low, but if things are synced, then it should be jitter free regardless of the physics tick, shouldn't it? Regardless, it sounds like this issue is unrelated to PhantomCamera and that I likely need to wait for Godot 4.4 for further improvements. Thank you for giving this a test! Edit: to clarify, I am using the smoothing addon but am still getting jitter |
Can't say for sure. Could be anything from an initial addon calculation to the physics system reacting to initial changes happening in a scene for optimization reasons that's only really noticeable when the physics tick is low. When physics is involved, especially when it's only for a few frames, it becomes difficult to pinpoint the underlying cause. Given you're seeing the same behaviour without the addon, I'm tempted to suspect that it has something to do with the engine's physics. |
It may help to set the node process and physics priority on your camera controller (i.e., phantom-camera instance) to something higher than 100. This is not to be confused with camera priority; this is the process and physics priority listed farther down the inspector, under the "Node" category. 100 is the value used by the smoothing addon—set on I've seen a custom camera controller stutter a lot on startup and calm down to occasional twitching, and setting the process and physics priority above the smoothing node's 100 solved it. Specifically, I chose 300. But, anything above your smoother (or any custom interpolator) should be fine. In my case, I also needed to disable automatic processing of a custom boom arm node and force its update to be executed at a more ideal time by calling a function from my camera controller instead. But, with that extra fix in place, I did test and confirm afterward that switching back to camera controller node process priorities of 0 reintroduced the stuttering and twitching. And, setting it back to 300 fixed it again. I don't use phantom-camera (I just followed a mention from a Godot PR). But, the universal idea is that the entire chain of execution orders must be explicit when one thing is intended to closely follow another. |
@OhiraKyou, funnily enough, was chatting with @m4rr5 about this exact thing the other week. The main thing that has been holding the change back, and why I have been unsure about adding it in, is that I've had trouble replicating the particular stutter myself, so have never been able to verify the changes' effect. Given two people have independently suggested the change as addressing stutter they've seen, that makes me a lot more comfortable adding it in. Am expecting to introduce that in the upcoming 0.8 release. |
My feedback on this exact same jitter issue I've been experiencing ever since I installed phantom cam addon a year ago on my 3D projects and never got around investigating in depth until now: Note: the issue isn't present using just a godot Camera3D node hardcoded following in _physics_process or as child. Would be happy to provide any required details, maybe on a new ticket (I may open eventually). Video of the jitter symptoms (clean, no solutions applied): minimal reproduction project I use for testing the jitter issue with phantom camera (has all dependencies except smoothing addon) (clean, no solutions applied): The issue can also be reproduced in certain environments, in some/all of the test scenes, such as in I have 2 laptops side by side (A/B). A very rarely displays jitter (at least with sample project, on my main project it's even more frequent), B displays the issue almost constantly (on both sample and main projects). One notable difference between my sample and main projects is that in sample the phantom camera targets the player visual, while on my main, I target a moving node3D used as target pivot which I move to wherever required. FAILED SOLUTIONS I TRIED: (note, minimal reproduction project doesn't have these applied, I tried them locally and then discarded, but if you pull it as it was last pushed, the issue can be reproduced in certain environments)
All failed solutions mean there was still jitter after applied. PENDING TRYING:
|
Does someone have a public 3rd person phantom camera setup that doesn't jitter, that I could pull for verifying if it jitter from this commonly jittery PC? |
I'm sure the Okay, so because of these changes I need to add a new "PlayerVisuals" However, this workflow breaks down for me when trying to follow a ragdoll. When simulating a skeleton with physical bones, you don't have a single physics body that you're interpolating your top-level "visual node" towards. I'm forced to stick with ragdoll2.mp4 |
Like with 2D, there is a plan to support 3D physics interpolation when it gets released in Godot 4.4, which addresses the workaround complication — can read that discussion further up the page. As for the reason the system is the way it currently is, that is explained in the 0.7 release notes, specifically under the section “Logic Moved to _process”. It's worth highlighting that jitter has been a general problem in Godot for a very long time. It's for example, the reason the smoothing-addon exists, which is an alternative solution to the steps you mentioned. I don't disagree with what you're saying, I fully agree that the user experience should be as simple as possible without any quirky workarounds. But it's worth remembering that the change wasn't an accident and that it was a compromise that was made to support as many use cases as possible given the technical engine limitations. |
3d-physics-interpolation.mp4With the addition of 3D Physics Interpolation support in v If anyone still experiences jitter, please submit a new issue so that can be investigated. |
Please read follow-up comment; this may be able to just be closed!
Issue description
phantom-camera
version:0.6.4
Godot v4.2.1.stable - macOS 14.1.1 - Vulkan (Forward+) - integrated Apple M1 - Apple M1 (8 Threads)
This is a bit of a duplicate of #173 but I think that there may need to be some updated docs around it for some best practices. I spent the whole day debugging physics jitters and found out that it was the camera that was the source of it 😅
I think this comment is very relevant: #179 (comment)
(hi, it's me, people thinking something is fundamentally broken 😄 )
The setup I have is like...
CharacterBody3D
(RigidBody3D
)CollisionShape3D
Smoothing
(fromsmoothing-addon
)MeshInstance3D
PhantomCamera3D
(follow mode "Simple", follow targetMeshInstance3D
above)For testing purposes, I've set
Physics Ticks per Second
to10
in the project settings.Using a static camera, you can see that the
smoothing-addon
is working as intended. The mesh follows the collision shape smoothly, even though the physics update is slow:Screen.Recording.2024-03-27.at.12.16.40.AM.mov
However, if you set this to follow mode "Simple", the camera movement is jittery even if you follow the mesh instance that's a child of the
Smoothing
node.Note that this behavior exists even with
damping
turned on! It also happens no matter what child of the rigid body you follow. It's surprising to me that this behavior happens when following theMeshInstance3D
since it should be smoothed (but maybe this is happening in_physics_process
so the smoothing is done before the camera updates?)Screen.Recording.2024-03-27.at.12.15.43.AM.mov
There even appear to be issues when using
smoothing-addon
with the physics tick rate much higher than the FPS. Here's an example of a physics tick rate of 144, zoomed in so that you can see the "vibration" of the camera following the object:Screen.Recording.2024-03-27.at.12.22.11.AM.mov
That same vibration is not present with the static camera, so it's something in the way that the camera is following the object:
Screen.Recording.2024-03-27.at.12.23.44.AM.mov
I wonder if there should be a setting to switch whether you want a specific camera to update inside of
_process
or inside of_physics_process
?Minimal reproduction project
Reproduction project: https://github.com/TranquilMarmot/phantom-camera-jitter-repro
See README for details.
The text was updated successfully, but these errors were encountered: