-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Add option to sync frame delta after draw #48555
Conversation
Investigations have showed that a lot of the random variation in frame deltas causing glitches may be due to sampling the time at the wrong place in the game loop. Although sampling at the start of Main::Iteration makes logical sense, the most consistent deltas may be better measured after the location likely to block at vsync - either the OpenGL draw commands or the SwapBuffers. Here we add an experimental setting to allow syncing after the OpenGL draw section of Main::Iteration.
Thanks! |
Should the setting be enabled by default during the betas? This way, we can get some real world testing on it. |
We did set on for the default for |
Catching up on the work done with great interest after the 3.4beta2 release. On this topic and on the delta smoothing thing, I wonder what is a sensible way of evaluating the result. It looks like the appreciation boils down to the visual perception of some project, which is subjective. Would it be possible to let Godot measure that for us more precisely and report via debug options? The smoothing logic goes to great length at computing things, so some additional debug on std deviation, counting spikes above a threshold and the like be detected and reported for a configurable time window would probably be a good additional debug toolset. And you would be able to appreciate the results by getting those numbers. Then I read the discussion about (verbose) logging possibly getting in the way. Some guidance on how to test (relevant options on/off) would be nice. I’d be happy to test this thing but am am really unsure how I would report anything objective on both subjects beyond the obvious “I can see better with glasses than without” 😊 which I can hardly quantify any further. So again, what is a sensible way of testing these? |
There are some debug options for the smoothing that require a recompile. I did consider putting in some kind of debugging output, or at least a way of querying whether the smoothing was active (sync after draw is always active if you switch it on). Two points though:
Some typical output on my system is:
Then once it has settled and estimated the refresh rate, here are the deltas:
You can try running this with delta smoothing on / off and sync after draw on / off (and combinations). If sync after draw gives more consistent deltas even with smoothing off, then it is helping on your system. If you aren't getting a consistent delta after say 30 seconds with delta smoothing, then it hasn't settled and your system doesn't have a consistent enough refresh rate - for example you have variable refresh rate, or you are not keeping up to the vsync consistently. Bear in mind also that the actual act of printing the logs will affect the deltas at that point in time, so you might want to sample over a larger number of frames, and ignore results which are clearly wildly out. |
Inconclusive results from me, testing 3.4B2 with various delta_after_draw/delta_smoothing/jitter_fix combos against a 3D gridmap maze project on my Intel NUC (BOXNUC7PJYH4, Linux Ubuntu/MATE 20.04.2, Mesa Intel UHD Graphics 605 GLK 3), at fullscreen 960x540 with VSync. The only thing I might infer from this limited testing is that the combo [jitterFix_0.5, deltaSmoothing_OFF, deltaAfterDraw_ON] seems to be worst performing on my NUC rig. And curiously, my best run was with the old settings: [jitterFix_0.5 deltaSmoothing_OFF deltaAfterDraw_OFF]. By the way, I'm not sure how the metrics can show me averaging 60 fps when _process seems to be averaging way above 16 ms in most of these tests. That doesn't make much sense to me. UPDATE: Oh, right, I see it. It's the huge fps lag spike at start of runtime throwing the _process averages off, presumably. EDIT: chart snapshots removed because they were not reflective of results. See my updated chart link in a later comment. |
We should probably make it so the first 2 seconds of runtime are always ignored in the profiler and when using |
I just checked and the debug monitor doesn't display the delta that is sent in to the game, it is using a separately measured delta. So any graphs above should not show anything different (or at least nothing relevant) - the profiled delta will be full of the usual random fluctuations. That actually might be something worth changing. I have to admit I didn't even look at this section (the profiling code is below where it does the actual ticks), or consider whether it would be worth changing at the time - my bad, this was an oversight. Currently if you want to see the actual delta supplied to the game at the moment, you need to use a script like the one I posted earlier. Let me know thoughts on this, it would be fairly easy to get the profiler showing the smoothed input delta if that is desired. 👍 🙂 |
I'm a big fan of both ideas! A Project parameter to set the e.g. "Monitoring delay start" (default 2s) would let users adjust for each project, where some projects need no delay and others need some delay to account for ignore-able startup activities that would otherwise skew the monitor charting. Adding smoothed delta to the Monitor charts, if that feature is active in Project settings, is of course desirable because what good is Monitoring if it's not accurate? Here are my corrected results for same setup described earlier, using the logging script. Conclusions for my testing:
It's pretty clear that the new Delta Smoothing has a PROFOUND effect on getting uniform delta. |
Yes the The idea with Yeah when
Your resultsThey are quite interesting, mostly in line with expectations .. this would be my interpretation: Delta after drawI'm not sure there is a significant difference on your machine (I don't know whether those extra peaks are just sampling error, although it could be the other sampling point is slightly better in this case). The most likely explanation is that your GPU / OS does not block after the SwapBuffers call (moving the sync point to here will presumably only help if the blocking occurs there, rather than randomly). SmoothingWorks as expected. |
See the PR above for a little more discussion. I fixed a small bug in the So for now it remains that the profiler measures wall clock timings, not the actual deltas passed to |
Investigations have showed that a lot of the random variation in frame deltas causing glitches may be due to sampling the time at a sub optimal place in the game loop.
Although sampling at the start of
Main::Iteration
makes logical sense, the most consistent deltas may be better measured after the location likely to block at vsync - either the OpenGL draw commands or the SwapBuffers.Here we add an experimental setting to allow syncing after the OpenGL draw section of
Main::Iteration
.Notes