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

Camera2D renders the position of the previous frame. #74203

Closed
luckyabsoluter opened this issue Mar 2, 2023 · 4 comments · Fixed by #84465
Closed

Camera2D renders the position of the previous frame. #74203

luckyabsoluter opened this issue Mar 2, 2023 · 4 comments · Fixed by #84465

Comments

@luckyabsoluter
Copy link

luckyabsoluter commented Mar 2, 2023

Godot version

4.0.stable.official (92bee43)

System information

Windows 10, Mobile

Issue description

[Godot 4.0] Camera2D renders the position of the previous frame.
Therefore, when Camera moves, sub-nodes moved on screen.
It is reproducted on Windows and Android.

Steps to reproduce

Setting

image
image

Test 1

extends Camera2D

func _process(delta):
	position.x += 500

image

Test 2

extends Camera2D

var b = true
func _process(delta):
	if b :
		position.x += 500
	b = !b

녹화_2023_03_02_11_32_07_920

Test 3

extends Camera2D

func _ready():
	position.x += 500

image

Test 4

extends Camera2D

func _ready():
	position.x += 500
	process_mode = Node.PROCESS_MODE_DISABLED

image

Minimal reproduction project

camera render position issue reproduction project.zip

@AdamGaskins
Copy link

I don't know enough to say this is the same issue as #28492, but the same solution (adding force_update_scroll()) worked for me. So to fix Test 1 above:

extends Camera2D

func _process(delta):
	position.x += 500
        force_update_scroll() # adding this line fixes the delay

@phantomdesvin
Copy link

I have the same issue. The force_update_scroll() workarround worked for the lerp, but not for the tweens.

@thygrrr
Copy link
Contributor

thygrrr commented Nov 5, 2023

Here's a reproduction project from me that cycles through all VSYNC modes.
jittery-vsync-bug-repro.zip

Just hit play, it will cycle through each with 5 seconds in between each switch.

Result (tested on 60 and 120 Hz display, the bug is consistent)

  • VSYNC_DISABLED: smooth ✅
  • VSYNC_ENABLED: judders ❌
  • VSYNC_ADAPTIVE: judders ❌ (frequency varies - perhaps wrong complement of frame time fraction used?)
  • VSYNC_MAILBOX: smooth ✅

There are 2 objects because I had one of them calculate its own delta time from microseconds, suspecting a delta time issue - there is one, but it is unrelated to the visual judder.

(Windows) Video of VSYNC_ENABLED, judder visible

(recorded at 8x slow motion on 120 Hz display, note the peculiar motion at 3 and 6 seconds, which almost seems like the object is jumping forward and back again; it may be an optical illusion caused by a simple frame skip, but read my theory at the end of the post)

vsync-jitter.mp4

(Windows) Video of VSYNC_MAILBOX, very smooth

(also 8x slow motion & 120 Hz, looks similar for VSYNC_DISABLED, including that there is never any discernible tearing which would be expected: Thus, VSYNC_DISABLED may erroneously be using a fence/semaphore somewhere in the render process or driver. However, G-Sync is turned off, and there's also no tearing on my second monitor, which is a 60 Hz non-VRR model)

mailbox-smooth.mp4

Interestingly, the engine-delta object (using delta from _process) will start lagging in the vsync and adaptive vsync modes (I would expect it to be ahead, or equal), yet it will mysteriously catch up when mailbox is on, or vsync is disabled. I cannot explain this, if there was a discrepancy introduced during the vsync mode switches, that error would just stay and accumulate, not go away again. (due to how the code is written - time just accumulates individually for each object, and is never reset)

You also can't record this with the builtin recorder, because that messes with delta as well.

There's also a slight amount of drift you may observe over time, which probably shouldn't be there in a perceptible fashion, either.

Not a bug: If you move the window, put it on another screen, or anything that causes delta to get frozen vs. the wall clock / Time.usec value, then it will go totally out of sync - one might argue that there either the delta or usec value is wrong in that case. This is probably due to _provess delta being clamped to a maximum value, so works as expected.

Theory?

Perhaps an out-of-order image is submitted to the swap chain. That might explain the weird "back & forth" jitter one seems to perceive. If the "back & forth" is an optical illusion (and is only a "lag/skip" judder with catchup), then the theory would be that an image simply isn't submitted to the swap chain at all, or doesn't make it through presentation. Either assumption could also begin to explain why the wallclock (custom delta ) dependent object also jitters.

@5ro4
Copy link

5ro4 commented Dec 23, 2023

Still happening in Godot 4.2.1

@akien-mga akien-mga added this to the 4.3 milestone Jan 15, 2024
@akien-mga akien-mga changed the title [Godot 4.0] Camera2D renders the position of the previous frame. Camera2D renders the position of the previous frame. Jan 15, 2024
@akien-mga akien-mga added the bug label Jan 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants