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

get_global_transform_interpolated() may return wrong value when FPS < physics ticks per second #102142

Open
matmas opened this issue Jan 29, 2025 · 3 comments

Comments

@matmas
Copy link
Contributor

matmas commented Jan 29, 2025

Tested versions

  • Reproducible in v3.6.stable.official [de2f0f1]
  • Reproducible in v4.4.dev1.official [28a72fa]
  • Reproducible in v4.4.beta1.official [d33da79]
  • Reproducible in v4.4.beta.custom_build [a013481]

System information

Godot v4.4.beta (a013481) - CachyOS Linux #1 SMP PREEMPT_DYNAMIC Mon, 20 Jan 2025 21:26:55 +0000 on Wayland - X11 display driver, Multi-window, 1 monitor - Vulkan (Forward+) - integrated Intel(R) HD Graphics 620 (KBL GT2) - Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz (4 threads)

Issue description

When FPS drops below physics_ticks_per_second the function get_global_transform_interpolated() sometimes returns wrong value.

When calling get_global_transform_interpolated() in a _process() I expect to get the most recent interpolated transform regardless of how many physics ticks happen between successive process frames. I think the actual returned value may be interpolated transform only after 1 physics tick that occurred directly after the previous process frame.

The issue is about functionality introduced to 4.4.dev1 in #92391 but it is also reproducible in 3.6 version of physics interpolation.

Steps to reproduce

Run the MRP and notice NinePatchRect is constantly jittering.

In order to reproduce the issue the project has max_fps set lower than physics_ticks_per_second.

If needed I can provide even more simplified MRP without the usage of Camera3D.unproject_position().

Minimal reproduction project (MRP)

Godot 4.x project:
test-physics-interpolation-maxfps.zip

Godot 3.x project:
Test Physics Interpolation max_fps Godot3.zip

@lawnjelly
Copy link
Member

lawnjelly commented Jan 29, 2025

Related #94060.

UPDATE:
Ah! I think I understand the difference here, maybe the timeout is not working. There should be a timeout which prevents this. Will investigate.

@lawnjelly
Copy link
Member

lawnjelly commented Jan 29, 2025

You are absolutely right, I must have subconsciously assumed the frame rate would be higher than the tick rate, because it only updates the previous transform during the frame call. I'll put in a mechanism to fix this. 👍

UPDATE:
Turns out there is already a mechanism to deal with tick rate higher than the frame rate, and it is working fine in a test project. So there is something special about your MRP which is causing the behaviour seen, still investigating.

Modifying your project so the target is not a physics object seems to work fine (as in my MRP), so it looks to be something to do with the timing that the physics engine is updating the Ball, relative to when the interpolation records it. Will probably have to look more tomorrow.

@lawnjelly
Copy link
Member

lawnjelly commented Jan 30, 2025

Think I've got it, the client interpolation pump was being updated before the physics had called back to update the item transforms during the iteration. This seemed not to be a problem when the frame rate was higher than tick rate, but caused a glitch the other way round when there was more than 1 tick per frame.

It looks fairly simple to fix by moving the point in the iteration we update the client interpolation pump.

Well done for spotting this! 👍

Also likely it was missed because most of the testing was on non-physics objects (to simplify things).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants