Mysterious broken 2D polygons with Forward+ renderer _only on some monitors_

Godot Version

4.3 up to 4.7

Question

I finally managed to record this behaviour with my phone. It only happens with Vulkan (windows 11) on some monitors.
As you can see in the recording, my OBS studio never caught the broken-up polygons:

This is one of the reasons I keep pushing for 2D antialiasing for Compatibility (the other being web builds).

What is happening? Is this a known thing with Vulkan on Windows? Is this some capability issue with the monitor itself?

Thanks for any good intel.

Vulkan can be quite buggy on Windows and mobile.

Try switching to the D3D12 driver for the Forward+ renderer

Cheers !

Thanks, I will try it! It is still a bit weird to me that this registers on the monitor, but not in recording software somehow. Interestingly, it does not seem to matter which one I pick: Both Vulkan and D3D12 show the same sharded polygons in 2D.

It may be the hardware, though.. For 2D I simply get a way smoother experience with opengl.

same scene, opengl renderer.

Oh, must be a vsync issue, your eyes catching a partially rendered frame. Try it with vsync off and on. The capture software might only grab synced frames or something.

Cheers !

Make sure your monitor is in “Game mode” if it’s present, that should disable any “motion smoothing” and reduce input delay. It’s pretty rare for a computer monitor to have motion smoothing features, it’s much more prevalent on consumer TVs, and I haven’t seen it churn out such a blocky mess but motion smoothing is kind of what the problem looks like to me.

Yes! That’s it!

That makes me really happy @OleNic! It works for both d3d12 and Vulkan - and looks great. My phone camera can’t even keep up anymore:

Now how to I re-record all my old videos with this sage advice? :smiley:

Anyway. What problems does vsync solve that I reintroduce by disabling it? I read up on it way back, but I keep forgetting. Must’ve been 3D stuff.

Could turning off vsync have fixed that as well?

These are cheap office dell monitors, but what I have at home isn’t top of the line either. :smiley:

Without V-Sync the game makes frames as fast as it can and tries to display them immediately, interrupting if the screen is mid-way through displaying an image, you can see a line form in the middle or sometimes if the game runs much faster than the screen multiple lines will form. These lines are “tears” in the screen

This video is purely black and white vertical bars moving side to side, the thumbnail examples what a screen tear would look like, the top half of the screen is the last frame and the bottom half is the new frame, in-between the vertical bars look torn. If you play the video you probably won’t see a screen tear, since v-sync is usually on for web browsers, but your game could produce a similar effect.

By disabling v-sync the game runs as fast as possible, there are other ways to achieve this like Mailbox or Adaptive v-sync, but the benefit is that theoretically when your inputs are processed more responsively; the last input you pressed will be “closer” to the rendered frame. This mostly comes up in competitive games like counter strike and fighting games where a 16 millisecond delay in your button press could be a win or loss. But that’s up to a 16ms delay, and there could be some engine optimizations that push input polling later in the process/rendering cycle too.

No I’m probably just wrong about motion-smoothing, you may still get lower latency in a Game mode if present, but I highly doubt my initial statement is correct or relevant.

Ah, now I remember. I ran into this using pygame with SDL on unaccelerated cpu graphics (320x240 @ 24 bits), especially noticable with side scrolling.

So last question: is vsync commonly problematic for lower end hardware that you’re aware of?

Games often expose it optionally, right? At least BG3 and Valheim made it optional, I think..

I don’t think it’s problematic for lower end hardware, as in it should have zero performance impact. However, a side effect of waiting for the screen’s signal is if you miss the v-sync time your frame will have to wait for the next one. If your game hits only 59fps, and can’t reach the screen’s 60fps then your frames will be delayed all the way down to 30fps. Similar to the input polling mailbox v sync should help with this allowing the render to continue while waiting on v-sync signal so a 59fps may display the same frame twice, but not always.

You typically always want to have vsync enabled if the GPU can render above the monitor refresh rate. Otherwise it’ll do more work than necessary.

So, just out of curiosity: how would one go about determining this automatically at, say, boot time of a game?

(I know, losing track of the original question a little here)

Best not to bother with it imo. Just enable it by default and provide an option for the player to disable it.

At boot time is impossible.

At runtime is ill-advised since enabling or disabling would be based on the framerate versus monitor refresh rate, but enabling or disabling will affect the framerate so a naive implementation could flip-flop especially as the machine warms up or if other programs are running.

Yea, optimizing out inefficient polygon unions by not doing unions at all is way more fun:

It’s almost Schrödinger’s cat (is it Ok to mention them here?)