godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.55k stars 20.63k forks source link

Sprite2D jumps back and forth (maybe also its physics object) #81727

Open tedbarth opened 1 year ago

tedbarth commented 1 year ago

Godot version

v4.1.1.stable.mono.official [bd6af8e0e]

System information

Linux Mint 21 (Vanessa) - Vulkan (Mobile) - integrated Intel(R) Graphics (ADL GT2) () - 12th Gen Intel(R) Core(TM) i7-12700H (20 Threads)

Issue description

I have a problem with 2D movements of a rigidbody2d bound Sprite2D. It is jumping back and forth. You can clearly see it from time to time when slowing down play speed of the following video:

https://monobyte.uber.space/jitter.webm

Sprite jumps back and forth. You can see this all the time. In second 12, when it goes up, you can notice it is even jumping forward in time and back. This could also mean it is delayed the whole time but in second 12 it is correct.

using Godot;

public partial class hello : Node2D {
  private Vector2 force = new Vector2(0, 100);
  private RigidBody2D _player;

  public override void _Ready() {
    _player = GetNode<RigidBody2D>("player");
  }

  public override void _PhysicsProcess(double delta) {
    if (Input.IsKeyPressed(Key.W)) {
      _player.ApplyImpulse(-force); // No difference when using ApplyCentralForce()
    }
  }
}

Steps to reproduce

Minimal reproduction project

game.zip

image image

QueenOfSquiggles commented 1 year ago

(On mobile, so bear with me if I misunderstood something)

I'm wondering if altering the physics time step could produce different (better?) results. Docs Link

Alternatively, tweaking the Jitter Fix setting might help. Docs Link

I apologize if these are fruitless. I'm not terribly familiar with any lower level physics engine things. Just stuff I've tried for my own projects to fix these kinds of things

Calinou commented 1 year ago

Please go through the Fixing jitter, stutter and input lag page from the documentation. You will probably want to use a physics interpolation solution as described on that page, or at least increase physics FPS to 120.

tedbarth commented 1 year ago

Thanks for the input. It is jitter then. You can clearly see the jumping into future and back in this slow-mo video:

https://monobyte.uber.space/jitter2.mp4

After doing Engine.PhysicsJitterFix = 0; (in my _Ready() method) everything is butterly smooth!

I still don't get the source of the problem. How can a desynchronized render / physics loop cause the object to jump forward in time, then jump back and than furth again while it should simply advance forward 'linearily'? The only thing I could think of is that (if not a bug) there is some double-buffering involved and what I think is the normal movement is actually the delayed movement, which just 'accidentally' becomes correct for a brief moment. This sounds more like a bug for me, no? Here I don't get, why it usually happens when changing the state of applying the force to on or off (via W key). Do you have any more insights in this than documented in these awsome two docs you two posted?

tedbarth commented 11 months ago

I just checked with latest 4.2.0-dev and the problem appears to be much more present (default physics tick rate). It is less visible on my 144 Hz monitor but brutally visible on my 59,93 Hz laptop display. Hurts the eyes on both.

59,93 Hz: https://monobyte.uber.space/jitter4.mp4

Engine.PhysicsJitterFix = 0; seems to have no effect at all.

tedbarth commented 11 months ago

I thought about this for quiet some time now and still can't understand how this could happen: The rigid body (or at least its sprite) jumps to a future position occasionally, just to jump back to its expected position the very next frame(s). Or it is always on an old position (like 10ms behind) the whole time and just appears at its correct position for a one or some frames, occasionally.

If it is just a physics server being out of sync with the game, it would not jump back. Are there maybe two physical objects controlling the same visual node, transparently? Is there a fault double-buffering involved or so?

This jumping obviously can't be solved with interpolation between physic frames.

I tried with godot-box2d physics and get the exact same results.

Calinou commented 11 months ago

Did you try https://github.com/lawnjelly/smoothing-addon? It automatically disables the jitter fix when enabled. Remember that you can't fix this issue without interpolation as 60 (the default physics tick rate) is not a divisor of 144.

You also want to be careful about movement speed to make sure the effective speed in viewport pixels per second is a multiple of the monitor's refresh rate. This will ensure that the camera moves at the same speed every frame without any jitter.

Cyangmou commented 11 months ago

I tested this, it's most likely a problem with the V-Sync results of the tests can be found in this thread here:

Issue #81727