Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Application.targetFrameRat It doesn't work in versión 2020.2.0b5.3233

Discussion in '2020.2 Beta' started by Eck0, Oct 4, 2020.

  1. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    I see, don't worry it's my fault of thinking that beta may be stable. I was hoping for 2-3 weeks but in this case ill go back to 2020.1.

    Btw I have to say targetFrameRate works a lot better in 2020.2. 240fps lock looks a lot smoother.
     
  2. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
  3. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Tried but it seems like the issue isn't only tied to Camera space canvas. Tried the workaround but it only makes freezes occur a bit less - I have to click switch fullscreen ~15 times instead of ~3 to reproduce.
     
  4. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Yeah I'm confused about that too. I'm following up with QA to make sure they are seeing the same thing as you are.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Kamyker likes this.
  7. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    This is fixed in 2020.2.0b14. Can you give it a shot?
     
    Kamyker likes this.
  8. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
  9. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Pretty sure, at least on the project you submitted in the bug report. Which exact 2020.2 beta build are you on?
     
  10. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    - installed from hub
     
  11. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    I'll take a second look.
     
  12. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    I've tried both my project and that test case. Same results.
     
  13. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    My apologies, looks like a merge tooling snafu. The fix got merged at 2020.2.0b14.3670: two revisions after 2020.2.0b14 was cut. I'm not sure why the version number wasn't bumped (still trying to figure out why), and that's why I thought it landed to 2020.2.0b14.

    The fix will be in 2020.2.0b15, which is scheduled for early-mid next week.
     
    cxode and Kamyker like this.
  14. neuroKir

    neuroKir

    Joined:
    Jan 18, 2017
    Posts:
    3
    @Tautvydas-Zilys Could you offer some insight into how OnDemandRendering.renderFrameInterval interacts with vsync when it's enabled? I noticed through my testing and reading through the docs, that setting
    Application.targetFrameRate = Screen.currentResolution.refreshRate;
    is practically required in order for it to work correctly?
    Will this cause any issues since targetFrameRate isnt -1?

    Our goal is having the lowest possible input latency, while also being able to reduce the rendered framerate to exactly 60fps (for research & analytics).

    Unity 2020.2.0b14 with "maxQueuedFrames = 1" has tested out great for us. Big improvement over the older versions. Our only remaining concern is if
    OnDemandRendering.renderFrameInterval can be combined with all these improvements, without sacrificing any input latency or consistency.
     
  15. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Which platform are you targeting?
     
  16. neuroKir

    neuroKir

    Joined:
    Jan 18, 2017
    Posts:
    3
    Primarily Windows, and OSX secondary
     
  17. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    OnDemandRendering pretty much requires disabling VSync, and use alternative frame limiting mechanisms. Usually, when your app runs too fast, ensures that you can only pump out one frame every refresh cycle. However, if you're using OnDemandRendering, you aren't rendering frames so VSync can't be your frame limiter.

    OnDemandRendering is mainly intended for reducing the power consumption/thermals on mobile devices.

    You mentioned that you want to render at 60 fps: why are you using OnDemandRendering? Generally it's used in cases where you want to render at low frame rate like 5 but poll input at update frame rate. It doesn't sound like that's what you want, right?

    I suspect OnDemandRendering will add 1 extra frame of latency because it takes time to re-establish GPU rendering pipeline once you resume it.
     
  18. Bordeaux_Fox

    Bordeaux_Fox

    Joined:
    Nov 14, 2018
    Posts:
    589
    I voted for your bug report but somehow I get redirected to the main page of the issue tracker automatically. Had to click the vote button very fast before the page reloads. Weird.

    As far as I followed the thread, we should never set targetFramerate and have Vsync enabled and need Unity 2020.2.b15 at least. Other settings will cause stutter and input lag?
     
    Kamyker likes this.
  19. neuroKir

    neuroKir

    Joined:
    Jan 18, 2017
    Posts:
    3
    Thanks, that clarifies some stuff.
    We're just experimenting with recreating an accurate 60fps visual experience since displays can vary a lot these days, while also maintaining high input precision.
    We have historical data we're trying to stay consistent with.
     
  20. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Having VSync disabled isn't bad per se, but it should be an option in the game as opposed to a default. As for targetFrameRate: if you use it as your main frame limiter, you will see higher frame time variance (and input latency variance for that matter) than if you used VSync at the same frame rate. I think that's a good way to summarize it given everything that was discussed in this thread :).
     
    cxode likes this.
  21. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    The fix is live in 2020.2.0f1, can you please try it out?
     
  22. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Yep, waiting for it to be available to download.
     
  23. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    My bad, I thought it was already pushed. It should be out tomorrow.
     
  24. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    3,136
  25. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Trying rn, seems to work pretty well, thanks! Can't wait to start working on VR version of the game :) (just have to get gear).

    Few quick fps samples (ignore min values, they are from menu switching):

    maxQueued = 1
    Exclusive:


    FullscreenWindow:


    maxQueued = 2
    Exclusive:


    FullscreenWindow:
     
    Tautvydas-Zilys likes this.
  26. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,526
    @Tautvydas-Zilys
    Do you know if I need to set target frame rate to 120 if I want to use that on ipad pro?
    Or is it enough to enable promotion in the playersettings?
     
  27. michaeleconomy

    michaeleconomy

    Joined:
    Aug 28, 2018
    Posts:
    58
    I only run the LTS release so sorry to thread crash, but is there a way to limit framerate in the editor?


    Application.targetFrameRate and QualitySettings.vSyncCount don't seem to work but maybe i'm missing something? (it still says 500+ FPS)

    When unity is in play mode even a really dumb game will chew up a lot of CPU on a mac book pro which makes it heat up, (and uncomfortable for being in your lap) and spins the fan up (making it harder to hear other things).

    I haven't done a lot of testing but i worry that the release version of my game will behave similarly. (with anyone on a laptop wondering why a very primitive game is pushing their $2000 laptop to its limits).
     
  28. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    It doesn't work but you can do it with: https://www.guru3d.com/files-details/rtss-rivatuner-statistics-server-download.html
     
    michaeleconomy likes this.
  29. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Hey, I wanna return to this - is it possible to leverage WAITABLE_OBJECT mode when running 2019.4.x on Windows 10 under D3D11? PresentMon reports Hardware Composed: Independent Flip so this should be True Independent mode as far as know. However, due to the fact Unity's default built-in framelimiter is very jank on that version by default I was curious if we can reduce Vsync render latency using WAITABLE_OBJECT somehow on that Unity version? This ideally should reduce it to absolute possible minimum but as of righ now on 80Fps/80hz I get around 29ms (calculated, 42ms predicted average) latency - that's a lot.
     
    Last edited: Jan 13, 2021
  30. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    We are leveraging waitable object on 2019.4, and its behavior can be controlled using QualitySettings.maxQueuedFrames. The lowest setting is "1" and the default setting is "2". You can calculate the added engine latency as "refreshInterval * (QualitySettings.maxQueuedFrames + 1.5)". Unity 2020.2 changes quite a bit of frame synchronization code so now your engine latency is "refreshInterval * (QualitySettings.maxQueuedFrames + 1)".
     
  31. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Okay, this makes sense, and the formula is relatively close to what I was getting on average when custom WAITABLE object flag was forced via SpecialK. maxQueuedFrames=1 should behave similarly
     
  32. l_racher

    l_racher

    Joined:
    Sep 1, 2018
    Posts:
    12
    I know I am kind of necroing this thread but in all this time nobody ever addressed this early statement.
    This might be commonly known but it took me a long time to figure this out myself. The issue with sleep being inaccurate can be largely addressed at least on windows with another windows API, namely timeBeginPeriod and timeEndPeriod.
    https://docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
    By setting the period to 1ms before calling sleep you usually get within 1-3ms accuracy when using Sleep() but leaving it set that low causes some overhead in the windows thread scheduler as I understand it. So you only want to set it for the Sleep call itself.
     
  33. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    We already use it, but as you say it's still within 1-3 ms accuracy which is not enough to provide a stable frame rate.
     
    l_racher likes this.
  34. ruudvangaal

    ruudvangaal

    Joined:
    May 15, 2017
    Posts:
    27
    Note that timeBeginPeriod() has been revised at some point in Windows 10 to behave mostly per-process, instead of systemwide. So that's a bit better now.
     
    l_racher and ROBYER1 like this.
  35. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Since my last post, we've moved to using high precision waitable timers when available (which means an updated Windows 10 machine), which doesn't depend on "timeBeginPeriod()" and provides 0.5 ms of accuracy. That makes Application.targetFrameRate behave pretty well but still not as good as VSync.
     
    l_racher and PeachyPixels like this.
  36. NotEvenTrying

    NotEvenTrying

    Joined:
    May 17, 2017
    Posts:
    43
    Finding the thread and going through it, I find it really disappointing to see Unity's team constantly making assumptions on their own and silently removing older features and choice from the developer; in this case the ability to cap the frame rates on standalone platforms, based on the assumption that nobody would want to cap their fps if their machine is capable of going higher, simply because it would introduce negligible amounts of input delay that not all games/players care about.

    Outside of fast paced difficult games, <30ms of input latency is practically unnoticeable. On the other hand, having your resources eaten up by a game that you're not playing exclusively, is very noticeable, because it makes other applications slow to a crawl. Our computers aren't consoles hooked up to a single TV - many of us multi-task even while playing a game, and a significant portion of people who own a computer in this day and age have more than one display/monitor, with multiple applications running and visible across different displays. In my current use case, I'm trying to test some networking issues by running multiple clients on the machine, but it's incredibly painful because the build jumps up to 144 fps, and my editor slows to <10fps, while the build is the focused application. With the other way around, Application.targetFrameRate still works as it used to a few years ago on the editor at least, and its not too bad, but its still unstable on the build as it tries to reach 144 when my gpu can't drive it at 144 while rendering another instance at 60fps.

    TL;DR there needs to be a way to limit the frame rate, even if its only on development builds, such a basic feature being removed by Unity on baseless assumptions is downright insulting. Premature optimisations of input delay like this is not a concern when the frame rate is intentionally capped - your "optimisations" need to be an opt-in, not a "we think group x wants it, so we'll #*@# over group y who don't need it, by replacing a feature group y needs to implement the feature group x needs". I've seen this happening a lot in other parts of Unity as well over time, and it's really frustrating as your customer to see you treating your tool as if only the use cases you've directly seen in your limited view are used in practice.
     
  37. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    I think you have misread this thread quite a bit. Nothing has been removed from Unity. Application.targetFrameRate is still there, and nowadays works even better than it did before. However, it's still not a great mechanism to limit frame rate. QualitySettings.vSyncCount is there as well, and provides a better experience the person playing the game comapred to Application.targetFrameRate. So you can still absolutely do it, I'm just saying I don't recommend it.
     
  38. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    I completely disagree, vsync still adds noticeable latency (2021.3 lts).

    I did small experiment, set up a way to randomly change vsync and tried to guess which one is it. That was easier than I thought, after 3 sec of playing (moving mouse) I knew exactly which one it is. In fps games crosshair is few frames behind making it a bit floaty, makes aiming and overall experience pretty bad.

    I have no idea why @Tautvydas-Zilys says vsync is better, it's terrible.
     
  39. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Is that testing it in the player running borderless fullscreen? Are you comparing it to uncapped frame rate or one limited with Application.targetFrameRate? Both should be adding input delay but I had the impression vsync one should be better (when limiting to the same FPS).

    In general, vsync seems better because it limits frame rate to a multiple of monitor's refresh rate, so you will not get into situations where you're limiting it to a number that causes it to stutter because the refresh rate it's running on is a weird number (for instance, 85 Hz display and a 60 FPS limit). That's why I think that if you choose to limit frame rate to something low, vsync should theoretically give a smoother picture.

    Of course, if your refresh rate is 60 Hz, and you're limiting from 1000 fps to 200 fps, the 200 fps version will definitely have better input latency than 60 Hz VSync.

    I'd love to see your test project if you don't mind sharing!
     
    Last edited: Oct 30, 2022
  40. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Yes borderless (FullScreenWindow not exclusive), 240hz monitor so 240 fps limit (targetFrameRate).

    Not a test project but my game, can send you a steam key.
     
  41. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    And btw my nvidia settings:


    On/off vsync option in the game sets it to 1/0
     
  42. l_racher

    l_racher

    Joined:
    Sep 1, 2018
    Posts:
    12
    The thing with Vsync is that it really depends on how it's implemented. In most cases, it uses at least double buffering but more commonly triple buffering which essentially means that the frame you see is on average one or two frames behind even in the best case. I don't really know how exactly unity implements this but there are quite a few examples of games that have ridiculously bad input lag with fullscreen Vsync on compared to Vsync off in windowed mode (which essentially just uses windows desktop Vsync). Even 3A titles get this wrong all the time.
    Furthermore, most games have trouble reliably hitting their frame targets, especially in unity where it can be surprisingly hard to run heavy operations off the main thread, and every frame that misses its window leads to an additional frame of input lag. So not only does it cause input lag but it can also lead to inconsistent input lag which is arguably even worse.
    Visually this is not a big deal especially with tripple buffering but our perception of the delay between our action and what we see on the screen is much more sensitive as VR demonstrates very strikingly.

    So using Vsync as a tool just to limit framerate is always going to be a very tricky proposition because it comes with all this extra baggage nobody wants or needs. This is also the reason why people are so insistent that Application.targetFrameRate should work "better". But as you already pointed out it indeed is much better than it was in the past.
    Ideally, I would personally like to have more fine-grained access to configure this stuff to fit the needs of specific games. Delaying the render of the next frame until the current frame has been grabbed from the buffer seems like it might be something to consider but we don't have any good way of doing that. With inconsistent frame times, no tearing and low input latency are just not possible at the same time, but given stable frame times, delaying the next frame-render to finish as close to the following screen refresh as possible is the way I wish fps limiting would work.

    Something that is quite strange about this discussion is how some commenters keep coming back to "smoothness" as a desirable metric. People that care about good framerate limiting want low input latency. They already have a "smooth experience". People that want smooth visuals are the ones that struggle with tearing which has nothing to do with framerate limiting. To reiterate, limiting framerate has nothing to do with combatting tearing or smoother visuals so can we please keep these two things separate?
     
    Last edited: Nov 25, 2022
  43. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    You can run extra code by overriding TimeUpdate portion of the player loop (just don't forget to call the original implementation after running your code or everything will "freeze"): https://docs.unity3d.com/ScriptReference/LowLevel.PlayerLoop.SetPlayerLoop.html

    You can achieve this by setting QualitySettings.maxQueuedFrames to 1. If you do that, Unity will not start a new frame until the previous is visible on the display.
     
  44. l_racher

    l_racher

    Joined:
    Sep 1, 2018
    Posts:
    12
    I think you still somehow missed the point.
    Custom player loops give you finer control over what happens on the CPU side but they don't provide any control over the actual rendering on the GPU as I understand it. But I haven't worked with custom player loops beyond a few experiments so maybe I missed something?

    maxQueuedFrames is a completely different mechanism that also affects input latency but is not related to fps limiting at all and I would expect anyone that is trying to reduce latency has already set this to 1 in the first place.
    I worded "grabbed from the buffer" poorly because that is not really what happens. What I meant to express was waiting for the GPU to push the completed (or maybe not completed) frame buffer to the screen.

    You can do this very easily with flush in OpenGL without any additional buffer latency so it is strange this is not possible in unity despite being potentially very useful. Most modern screens support variable refresh rate so just syncing up with the frame push should entirely bypass the issue of missing a frame window with Vsync and the consequent input lag.
    Unity has to implement at least part of this and provide some sort of high-level access to it as there is probably no good way to expose a general custom low-level API for stuff like this.

    This is not supposed to be a personal feature request. I don't actually need super low latency in my current main project but I just wanted to point out that this is something that is strangely absent and that Vsync is not the solution to the somewhat spotty targetFrameRate problem.
     
    Last edited: Dec 12, 2022
  45. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    upload_2022-11-25_9-11-42.png

    this is what the profiler looks like for me in my game
    - 144hz monitor (with variable sync support if that matters, but game fps is higher than the hz)
    - unity 2021.3.14f1
    - maxQueuedFrames 1
    - vsync off
    - windows 10

    The orange GfxDeviceD3D11.WaitForLastPresent sounds exactly like what @l_racher is talking about above with

    > What I meant to express was waiting for the GPU to push the completed (or maybe not completed) frame buffer to the screen.

    Also note that the frames do not line up with vsync intervals, it's quite steady at ~5 ms frames instead of the 6.9 ms you'd get with vsync. Consistently waiting about 2.3 ms on LastPresent.

    PS: I should've just linked to the docs lol

    > GfxDeviceD3D11.WaitForLastPresent
    > Samples with this marker appear when the main thread waited for the GPU to flip the frame number to the screen (Time.frameCount - QualitySettings.maxQueuedFrames + 1). This means that if QualitySettings.maxQueuedFrames is greater than one, this time is spent waiting for the GPU to flip a frame that your application requested to render in a previous main thread frame.

    https://docs.unity3d.com/Manual/profiler-markers.html
     
  46. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Yes, that's exactly what it is. And it's executed in the TimeUpdate portion of the player loop. If you override this TimeUpdate, you can add additional logic to frame limiting. Yes, the code will run on the CPU side but you can write code to wait until whatever condition you want.

    But Unity already by default waits for previous frames to be flushed/appear on the screen before starting the next frame.
     
  47. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    My players complain about rare random stutters, I'm trying to find the issue. My game is heavily optimized to not allocate etc.

    Found only this single spike so far:



    Do you have any ideas what it could be @Tautvydas-Zilys?

    Settings: Vsync off, targetFrameRate = -1, maxQueueFrames = 2

    Timeline:


    With Gpu Profiler below, I'm not seeing any lag spike there:
     
    Last edited: Jan 24, 2023
  48. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Also happens with target framerate = 360:

    A bit weird that there's still wait for target fps (isn't in the next frame greyed out):

    I this case there was spike on gpu also:
     
  49. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    I've tried maxQueuedFrames = 1 and it made it a lot worse (tried with and without fps limit, no difference):
     
  50. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,090
    Here's vsync also, kinda the worst:


    Similar issue with target for framerate then swapchain: