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

Jittery camera movement when physics tick rate doesn't match FPS #241

Closed
TranquilMarmot opened this issue Mar 27, 2024 · 42 comments
Closed

Comments

@TranquilMarmot
Copy link

TranquilMarmot commented Mar 27, 2024

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)

Have been trying to find a way that meant you didn't need to use the smoothing-addon, but it might not be a feasible thing to automatically solve for this addon alone. Though there is still a jitter issue when you disable the damping and have a PhysicsBody a target. The obvious solution would be to use the visual representation (mesh/sprite) node as the Follow Target, but wonder if there's a way to still allow the PhysicsBody to be used as a target. Obviously, it's a fairly minor thing and won't lose any sleep over it.

This current solve does also mean that the requirement of the smoothing-addon needs to be communicated, especially to those just picking up the addon / Godot, as to not cause people to think something is fundamentally broken. Which is probably my biggest concern.

(hi, it's me, people thinking something is fundamentally broken 😄 )

The setup I have is like...

  • CharacterBody3D (RigidBody3D)
    • CollisionShape3D
    • Smoothing (from smoothing-addon)
      • MeshInstance3D
  • PhantomCamera3D (follow mode "Simple", follow target MeshInstance3D above)

For testing purposes, I've set Physics Ticks per Second to 10 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 the MeshInstance3D 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.

@TranquilMarmot
Copy link
Author

TranquilMarmot commented Mar 27, 2024

Actually, just tried out the 0.7 branch in the reproduction project and it seems to work as expected!!! 🎉 I didn't realize that #179 wasn't released yet 🤦

Screen.Recording.2024-03-27.at.12.57.01.AM.mov

Following the RigidBody3D is jittery, but following instead the MeshInstance3D works totally fine.


Feel free to close this issue if it doesn't provide any value; I'd say that the upcoming release fixes the bug.

@ramokz
Copy link
Owner

ramokz commented Apr 2, 2024

Will keep this issue open until the release is out. Every test for this makes a difference, so thanks for sharing the MRP :)

@Nohac
Copy link

Nohac commented Apr 27, 2024

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.
The game is running at 100fps and the physics are unchanged. I tried changing camera processing mode from Idle to Physics which has helped with standard godot camera jitter, but didn't change anything in this case. Forcing the game to run at 60fps fixes it completely (it actually looks better/smoother then standalone godot camera).

Video of jitter
jitter2d.webm

Sorry for the bad recording, the jitter did not show up with my screen recorder software, so I had to use my phone.

@ramokz
Copy link
Owner

ramokz commented Apr 27, 2024

The way the system works in 0.7 requires a bit of extra setup. So if you're only assigning the Follow Target to the character, which I'm guessing is a CharacterBody2D(?), then by default jitter, yes, is to be expected.

Would stay tuned for the release notes of 0.7, which covers what to do in more detail.

@Nohac
Copy link

Nohac commented Apr 27, 2024

I used the same setup as stated in the docs for 0.6, with the target being a CharacterBody2D.
Tried adding the camera as a child of the CharacterBody2D, which removed the jitter, but then non of the settings worked.

Looking forward to the release!

@ipinzi
Copy link

ipinzi commented Apr 27, 2024

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.

@ramokz
Copy link
Owner

ramokz commented Apr 28, 2024

Don't recommend moving the logic to the _physics_process for the reasons mentioned in the 0.7 release notes.

Would suggest following the steps mentioned in the FAQ

@ipinzi
Copy link

ipinzi commented Apr 28, 2024

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.

@ipinzi
Copy link

ipinzi commented Apr 28, 2024

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.

@audeck
Copy link
Contributor

audeck commented Apr 29, 2024

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 _process_physics for Godot), and b) handling where a visual representation is depending on only where it's corresponding physics representation is at frame rate intervals in (i.e. in _process).

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 (0.3, 0) getting applied every physics tick. If you had only a) and a camera tracking it, you'd be forced to round the position of a) down every physics tick, essentially eliminating it's motion. Once you introduce b), you can let a) keep track of it's position with decimal precision, and let b) handle the rounding down/up.

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 _process). Allowing cameras to update in _physics_process is possible, but it hides an underlying issue with how we structure and think about our game objects, as I understand it.

Sorry for the wall of text 🤓.

@ramokz
Copy link
Owner

ramokz commented Apr 30, 2024

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 _process and _physics_process differs as the exports always smoothed out the result, so have instead attached 2 nearly identical projects — one using the current approach with _process, and another that uses _physics_process to move the camera.

_process_example.zip

_physics_process_example.zip

Each project includes 2 example scenes, one for 2D and one for 3D, which can be found in the root directory. More concretely, the _physics_process project has all the camera movement done in the _physics_process and a disabled repositioning of the PlayerVisual inside the player_controller.gd (attached to the playable character nodes). The last bit is how the smooth visual representation gets achieved in the _process project.

The 2D and 3D scenes both contain a node, Sprite2D and MeshInstance3D respectively, that moves back and forth using a built-in Godot Tween animation. Code can be found inside scripts attached to their respective scene's root node.

Both projects use an identical project setup of:

  • PhantomCamera3D Node
    • Follow Target = PlayerVisual
    • Follow Damping = true
    • Follow Damping Value = Vector3(0.1, 0.1, 0.1)
  • Project Settings
    • Physics Ticks per Second = 31
    • Viewport Window (width/height) = 1920 x 1080

The observation from the above projects with those settings should show the one using the _physics_process has very jittery animation, particularly when it comes to the Tweening node in the background. Whereas the scenes from the project that runs in the _process should be a lot smoother.

If you modify the Physics Tick per Second to be, say, 60 in the project settings for the _physics_process project, then that should smooth out the player movement. But what it doesn't resolve is anything that is animated using the _process such as any Tween animations, which will remain jittery if you move while they're moving.

So I am not confident that a dynamic system that sets the camera to move in _process or _physics_process depending on its target type will resolve the underlying issue of it impacting other animations that might be happening in a scene.

@ipinzi
Copy link

ipinzi commented May 1, 2024

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.
You could test the theory by testing it out with a more sophisticated physics system like rapier2D. That should have underlying physics interpolation. (Don’t know for sure haven’t tried it yet)

@Nohac
Copy link

Nohac commented May 1, 2024

Just found out that 2D physics interpolation has been implemented for godot 4.3 godotengine/godot#88424
I'm just going to hold out on using this addon until that is released

@ramokz
Copy link
Owner

ramokz commented May 1, 2024

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.

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.

When it does eventually happen, mimicking the way cinemachine handles this would work.
You could test the theory by testing it out with a more sophisticated physics system like rapier2D. That should have underlying physics interpolation. (Don’t know for sure haven’t tried it yet)

Good idea, will try to run some tests with that and Jolt out at some point.

@blai30
Copy link

blai30 commented May 1, 2024

I am on the 4.3 Dev 6 snapshot and the issue is still happening when using PhantomCamera2D. I tried changing Camera2D's Process Callback to Physics, Physics Interpolation Mode from Inherit to On, still seeing the issue. If I remove PhantomCamera2D and PhantomCameraHost from the scene entirely, the issue is gone.

https://godotengine.org/article/dev-snapshot-godot-4-3-dev-6/

@Nohac
Copy link

Nohac commented May 2, 2024

@blai30 Did you enable the settings mentioned in the PR?

Make sure to enable the project setting physics/common/physics_interpolation and set physics/common/physics_jitter_fix to 0.0 when testing.

@blai30
Copy link

blai30 commented May 2, 2024

@Nohac Yes, that did not seem to help

@audeck
Copy link
Contributor

audeck commented May 2, 2024

@blai30 Fixed the repository's 2D dev scene for 4.3 dev6 with physics interpolation on audeck/physics-interpolation-fix (don't mind the first commit). Basically, I changed the following:

  • Inside project settings (as per @Nohac):
    • Changed physics/common/physics_interpolation to true
    • Changed physics/common/physics_jitter_fix to 0
  • Inside phantom_camera_2d.gd:
    • Changed _process to _physics_process
    • Changed every occurence of get_process_delta_time to get_physics_process_delta_time to get follow_damping working
  • Inside phantom_camera_host.gd:
    • Changed _process to _physics_process
  • In the dev_scene_2d.tscn scene:
    • Set the active PlayerPhantomCamera2D's follow target to just the main CharacterBody2D player node, not the PlayerVisuals node
  • In the playable_character_2d.tscn scene (i.e. the player scene):
    • Moved the PlayerSprite so that it's parent is the main CharacterBody2D node, not the PlayerVisuals node

What's important is not mixing the previous manual interpolation (using either the project's PlayerVisuals or lawnjelly/smoothing-addon) with the physics one.

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 _physics_process as well (with a switch and/or auto-detection to decide, as @ipinzi already mentioned). Not a pressing matter, as only dev6 is out so far, but it'd be nice to have a major release prepared before the official release of 4.3.

@Nohac
Copy link

Nohac commented May 2, 2024

I tested this now, and it does not work out of the box as @blai30 says, applying @audeck solution fixes it.
What I don't understand then, shouldn't physics interpolation (fixed timestep interpolation) sync physics "movement" with the "visual" representation (_process)?

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.

@ramokz
Copy link
Owner

ramokz commented May 3, 2024

Tried out the 4.3 dev6 build as well.
By the looks of it, the change in Godot 4.3 appears to resolve the issue I posted earlier.

@Nohac if you comment out the following code in addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd, or select the script attached to the playable character, that should solve the jittery character movement as well.

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 smoothing-addon, so it likely interferes with the other setup.

@ramokz
Copy link
Owner

ramokz commented May 3, 2024

Have attached a short demo of having the physics_interpolation (inside Project Settings) enabled and, at the end, disabled — the difference is very stark. It's obviously only a tiny test sample, but so far, it looks like it addresses the issue.

physics_interpolation_demo.mp4

To go back to what @ipinzi proposed, do agree that with this change in Godot 4.3, and assuming it works consistently for others, the PCam2D and PCamHost should support automatically applying its movement logic in the _physics_process rather than the _process if it follows a physic-based node.

@audeck
Copy link
Contributor

audeck commented May 3, 2024

This code exists as a manual solution to the lawnjelly's smoothing-addon, so it likely interferes with the other setup.

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 global_position to it, now the calculated position is where it should be and the actual global_position needs to interpolate to the calculated one inbetween the current and the next tick.

That means that during _physics_process, the global_position getting read in player_character_body_2d.gd is effectively 1 tick in the past. The script then interpolates the visuals to that position; but since it is inherently constrained in the same way the built-in physics interpolation is, the visuals' position ends up being 1 additional tick behind.

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.

... shouldn't physics interpolation (fixed timestep interpolation) sync physics "movement" with the "visual" representation (_process)?

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.

@ipinzi
Copy link

ipinzi commented May 3, 2024

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.

@TranquilMarmot
Copy link
Author

Now we just need the same interpolation to come to 3D 😉

@ramokz
Copy link
Owner

ramokz commented May 7, 2024

Have made a draft PR with the changes to support the Godot 4.3 phyiscs interpolation #294

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.

@ramokz ramokz pinned this issue May 11, 2024
@ramokz
Copy link
Owner

ramokz commented May 11, 2024

The PR should now be updated to resolve the aforementioned issue(s).
Any help testing the changes in 2D projects for Godot 4.3 would be greatly appreciated!
PR can be found in #294

Testing in Godot 4.2 would also be beneficial, mainly just to confirm that there's no regression.

@audeck
Copy link
Contributor

audeck commented May 28, 2024

Now we just need the same interpolation to come to 3D 😉

godotengine/godot#92391

@sci-comp
Copy link

sci-comp commented Jul 30, 2024

Now we just need the same interpolation to come to 3D 😉

godotengine/godot#92391

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.

@sci-comp
Copy link

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

@ramokz
Copy link
Owner

ramokz commented Jul 30, 2024

To be clear: is it possible to get a jitter free setup for third person in 3d?

Yes, the approach should be no different for any of the follow modes. Third Person doesn't do anything magical by comparison to the others.

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.

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 Follow Target value?

@sci-comp
Copy link

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

@TranquilMarmot
Copy link
Author

TranquilMarmot commented Jul 31, 2024

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 smoothing-addon isn't needed anymore, it might be worth trying out that MRP again in Godot 4.3 with that turned on...

@ramokz
Copy link
Owner

ramokz commented Jul 31, 2024

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.

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 Camera3D?

It doesn't always jitter, but it will always eventually jitter after moving around for a short amount of time.

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 physics_ticks_per_second set to 10, I'm only seeing a slight jittery movement for a few frames at the very beginning after running the scene, but clears up shortly thereafter (see video example below).
Considering the physics tick being as dramatically low as it is, that doesn't surprise me too much.

241-07-31.mp4

Rerunning the scene with a physics_ticks_per_second of 27 removed that one occurrence I saw.

Since Godot 4.3 added native physics interpolation and the smoothing-addon isn't needed anymore, it might be worth trying out that MRP again in Godot 4.3 with that turned on...

Important to note that physics interpolation is only working for 2D scenes in Godot 4.3. So it won't affect anything for the 3D scenes we're looking at here. So the smoothing-addon or the alternative approach, mentioned in the docs, are still needed until, likely, Godot 4.4 it out.

@sci-comp
Copy link

sci-comp commented Aug 1, 2024

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 Camera3D?

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

@ramokz
Copy link
Owner

ramokz commented Aug 1, 2024

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?

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.

@OhiraKyou
Copy link

OhiraKyou commented Sep 2, 2024

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 _ready() by the smoothing node's script, to ensure that it processes later than what it's following. And, your camera controller should process even later than that.

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.

@ramokz
Copy link
Owner

ramokz commented Sep 2, 2024

@OhiraKyou, funnily enough, was chatting with @m4rr5 about this exact thing the other week.
The current plan is to let the PCamHost node trigger the process for the active PCam, rather than the active PCam executing its own process, so the execution order is persistent. That in addition to setting the process priority, like you mentioned.

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.

@Mangonels
Copy link

Mangonels commented Oct 9, 2024

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):
https://youtu.be/g28cqfCHZCM

minimal reproduction project I use for testing the jitter issue with phantom camera (has all dependencies except smoothing addon) (clean, no solutions applied):
https://github.com/Mangonels/character_movement

The issue can also be reproduced in certain environments, in some/all of the test scenes, such as in 3d_look_at_example_scene.tscn

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)

  • Smoothing addon node as parent for target graphic (or loose node pivot on my main project).
  • Godot 3.6+ (4.3) settings > physics > common > Physics Interpolation true + Physics Interpolation Mode "On" for the target node.
  • Process > Priority and Physics Priority for the PhantomCamera3D set to 100+
  • Updating to phantom camera github release 8 (from 7.2), which somehow displays in plugins as "0.7.9" (combined with some of previous solutions).
  • Ensuring PhantomCamera3D and the target object are both being processed in _physics_process. Of course, this means messing around with the original phantom cam code to ensure it, with potentially unexpected results. Also, there are still jittery moments (maybe less pronounced and perceptible).

All failed solutions mean there was still jitter after applied.

PENDING TRYING:

  • Setting smoothing addon target.

@Mangonels
Copy link

Mangonels commented Oct 10, 2024

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?

@levidavidmurray
Copy link

levidavidmurray commented Oct 21, 2024

I'm sure the 0.7.0 changes were made for a good reason, but forcing users to separate visuals and physics in order to use this plugin makes the API consumption a non-starter at worst and cumbersome at best.

Okay, so because of these changes I need to add a new "PlayerVisuals" Node3D that contains all the visual representations that are children of my CharacterBody3D. Sure, easy enough. Now just set that visual node as top_level and interpolate the visual node's transform as described here. Very annoying to have to do this for any physics body you want to follow, but fine, I guess I can accept that.

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 0.6.4 for this reason. Regardless of if some workaround exists, I feel like the amount of friction for getting something like this setup is very likely to prevent user adoption. Is there any plan to make following physics bodies as easy as it was prior to the 0.7.0 release?

ragdoll2.mp4

@ramokz
Copy link
Owner

ramokz commented Oct 21, 2024

Is there any plan to make following physics bodies as easy as it was prior to the 0.7.0 release?

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.

@ramokz
Copy link
Owner

ramokz commented Dec 7, 2024

3d-physics-interpolation.mp4

With the addition of 3D Physics Interpolation support in v0.8.1 for Godot 4.4, the original post has now been resolved.

If anyone still experiences jitter, please submit a new issue so that can be investigated.

@ramokz ramokz closed this as completed Dec 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants