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

Jitter when using KinematicBody #8

Open
bottomupadvent opened this issue Aug 20, 2020 · 10 comments
Open

Jitter when using KinematicBody #8

bottomupadvent opened this issue Aug 20, 2020 · 10 comments

Comments

@bottomupadvent
Copy link

Scene structure:-
Interp_cam_outside

  • World Scene is the main scene where player and block scenes are instanced.
  • Target for InterpolatedCamera node is CameraFollow node.

Player Script:-

extends KinematicBody
var constant_speed: Vector3 = Vector3(0, 0, -29)
func _physics_process(delta):
    constant_speed = move_and_slide(constant_speed)

Block Script:-

extends RigidBody
func _ready():
    linear_velocity = Vector3(0, 0, -29)

Output:-
Interp_cam_outside_short

As seen in the output the Small cube = Player (Kinematicbody) is causing jitter, the Bigger Block = RigidBody is fairly stable.

I tried putting the Interpolated camera as a child of Smoothing node which gives me the following result:-

Interp_cam_inside

Output:-

Interp_cam_inside_short

Here, the Small cube = Player (Kinematicbody) is smooth but the Bigger Block = RigidBody is causing jitter.

Now the problem doesn't exist if both bodies are Rigidbody.

minimal reproduction project:-
kinematic_smoothing_prob.zip

@Calinou
Copy link
Contributor

Calinou commented Aug 20, 2020

I wouldn't rely on InterpolatedCamera as it was removed in the master branch already (i.e. what will become 4.0 in the future).

Instead, you can write your own camera translation/rotation smoothing with a few lines of code using lerp() calls in _process() to asymptotically reach the target translation/rotation.

@lawnjelly
Copy link
Owner

lawnjelly commented Aug 20, 2020

I'm just taking a look. It is quite interesting.

I think it may be due to an order of operations problem. I suspect that interpolated camera is using an internal_process notification which is coming before the scene tree gets _process (or possibly also _physics_process messages).

As @Calinou says it is probably solvable by using your own camera node and using _process.

It did make me wonder whether we should be using internal_process for the smoothing node updates, but I don't think that would work, because the whole point is to update the smoothing node AFTER everything else gets a chance, i.e. user scripts run with _process and _physics_process. If it was run before there would be a tick delay.

I'm still not absolutely sure on this. Will update when I have more info. 👍

EDIT:

  • Yes interpolating camera is updating in INTERNAL_PROCESS
  • INTERNAL_PROCESS gets sent to all the nodes before they have a chance to update

scene_tree.cpp, line 524

	_notify_group_pause("idle_process_internal", Node::NOTIFICATION_INTERNAL_PROCESS);
	_notify_group_pause("idle_process", Node::NOTIFICATION_PROCESS);

This could actually be a problem with interpolated camera. It might be better doing its processing on a regular process (but then maybe it can't run user scripts on process).

As it is, interpolated camera would seem to have a frame delay on its updates. This might possibly account for some unrelated jitter bugs we have seen on the main godot github (nothing to do with the addon).

@bottomupadvent
Copy link
Author

I wouldn't rely on InterpolatedCamera as it was removed in the master branch already (i.e. what will become 4.0 in the future).

Instead, you can write your own camera translation/rotation smoothing with a few lines of code using lerp() calls in _process() to asymptotically reach the target translation/rotation.

I just tried using normal Camera node as a child of Smoothing node but the output is the same, where the player (kinematicbody) is smooth but the rigid body has jitter.
I'm sorry is there something I'm not understanding ??

@lawnjelly
Copy link
Owner

lawnjelly commented Aug 20, 2020

I just tried using normal Camera node as a child of Smoothing node but the output is the same, where the player (kinematicbody) is smooth but the rigid body has jitter.
I'm sorry is there something I'm not understanding ??

I can't seem to replicate this, can you make a project zip file so I can see what you mean? 🤔

Also BTW, try turning the physics tick rate down to e.g. 10 tps in the project settings (physics->common->physics_fps). It can make it much easier to see what is happening / when there are errors.

@bottomupadvent
Copy link
Author

bottomupadvent commented Aug 20, 2020

I just tried using normal Camera node as a child of Smoothing node but the output is the same, where the player (kinematicbody) is smooth but the rigid body has jitter.
I'm sorry is there something I'm not understanding ??

I can't seem to replicate this, can you make a project zip file so I can see what you mean? thinking

  • I've provided the zip file in the original post. The only difference is in the Player scene which is removal of InterpolatedCamera and CameraFollow node and addition of Camera node as a child of smoothing node.

This is how the player Scene looks like. Rest all is the same:-
2020-08-20-200343_192x162_scrot

  • Also I forgot to mention in my original post but the problem doesn't exist when the physics_fps = 5 as you said.

@lawnjelly
Copy link
Owner

lawnjelly commented Aug 20, 2020

I just tried using normal Camera node as a child of Smoothing node but the output is the same, where the player (kinematicbody) is smooth but the rigid body has jitter.
I'm sorry is there something I'm not understanding ??

I can't seem to replicate this, can you make a project zip file so I can see what you mean? thinking

  • I've provided the zip file in the original post. The only difference is in the Player scene which is removal of InterpolatedCamera and CameraFollow node and addition of Camera node as a child of smoothing node.
  • Also I forgot to mention in my original post but the problem doesn't exist when the physics_fps = 5 as you said.

Ah this explains things. 👍

The smoothing node can fix some sources of jitter (due to aliasing with physics ticks), however, there are multiple sources of jitter in Godot, especially in windowed mode on desktop. You may well be seeing some of these other sources.

Usually if you can export and run in full screen at a low resolution and it looks mostly good, it is fixed as best it can be (with current Godot). I will try and link post where we discussed some other sources of jitter.

godotengine/godot#30791
godotengine/godot#33145

@bottomupadvent
Copy link
Author

Ah this explains things. +1

The smoothing node can fix some sources of jitter (due to aliasing with physics ticks), however, there are multiple sources of jitter in Godot, especially in windowed mode on desktop. You may well be seeing some of these other sources.

Usually if you can export and run in full screen at a low resolution and it looks mostly good, it is fixed as best it can be (with current Godot). I will try and link post where we discussed some other sources of jitter.

godotengine/godot#30791
godotengine/godot#33145

Looks like I have a lot of reading to do 😄. Also I'm using arch (with compositing disabled) as my operating system and my game will be exported only on mobile devices, so if there is anything else relevant to it that you know of, do let me know. Thanks.

@lawnjelly
Copy link
Owner

Good news is that mobile devices tend to be much better in terms of stability of deltas than desktop (in my experience anyway), much like consoles, so it is often easier to get a smooth result. It's those fancy operating systems on desktop doing all their silly effects that can muck up timing for games (and media players).

Anyway don't hesitate if you have more questions. I wrote quite a bit of code last year for various smoothing tasks, including delta smoothing working in core, which is very handy for this kind of thing, and used it in my last couple of games, but never made a PR due to lack of interest in this area from the rest of the godot team. Unfortunately delta smoothing requires recompile of the engine though.

Also semi fixed timestep PR. There is a chance we will get to address some these areas for Godot 4.x, when juan gets to spend some time on physics.

There are also some newer APIs for getting better frame timings on android and vulkan which we may get to use eventually.

@victorbstan
Copy link

victorbstan commented Aug 22, 2020

I see the same issue, as I use a player character that uses kinematic body in similar setup as the original poster. I also use a 144hz monitor and the project physics is set to 60hz. This plugin does not seem to effective in this case. Because setting the target as the KB does not seem to have the same benefits as setting it to a RB. However, I have see improvement to jitters when setting the project physics tic to the monitor refresh rate (144hz). This alleviates most obvious issues. I realize for someone with a monitor refresh rate that is higher, the issue will come back; at the moment, my work-around is to set both the Physics and FPS of the project at the same value.

@lawnjelly
Copy link
Owner

I see the same issue, as I use a player character that uses kinematic body in similar setup as the original poster. I also use a 144hz monitor and the project physics is set to 60hz. This plugin does not seem to effective in this case. Because setting the target as the KB does not seem to have the same benefits as setting it to a RB. However, I have see improvement to jitters when setting the project physics tic to the monitor refresh rate (144hz). This alleviates most obvious issues. I realize for someone with a monitor refresh rate that is higher, the issue will come back; at the moment, my work-around is to set both the Physics and FPS of the project at the same value.

Aside from the other sources of jitter (which are very real):

If you are getting different results for a kinematic body than a rigid body, this suggests an order of operations problem. Double check that your smoothing node is not a child of the physics rep branch (i.e. that all it's parents / grandparents will have no (identity) transform), and that the smoothing node is AFTER the target node in the scene tree, so that it will be processed after the kinematic body.

There may also be problems introduced by the Godot implementation of kinematic body, I don't know the physics code well.

If you can include this in a separate issue I will have a look and try and work out what is going on.

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

4 participants