Search Unity

rendering without using requestAnimationFrame for the main loop?

Discussion in 'Web' started by john_Mindblown, Dec 11, 2015.

  1. john_Mindblown

    john_Mindblown

    Joined:
    Dec 11, 2015
    Posts:
    2
    Hi there,

    We made a webgl build using 5.3.0, and we are getting this error when our game loads up. It doesn't crash our game, but our frame rate definitely is lowered.

    Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!

    Anyone has a clue as to how to fix this?

    Thank you.
     
    Novack likes this.
  2. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Are you using Application.targetFrameRate to lower the FPS? If yes, then this message is expected.
     
    ailuropoda0, Novack, noemis and 3 others like this.
  3. john_Mindblown

    john_Mindblown

    Joined:
    Dec 11, 2015
    Posts:
    2
    Yep, we added #if !UNITY_WEBGL for our FPS lock, and now the error is gone. Thank you!
     
    ailuropoda0, Novack and Nolex like this.
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Is there any actual harm setting the application framerate for WebGL apps? If we only want our game to run at (for example) 30fps will this cause issues? (for WebGL builds in general)
     
    Fenikkel, Novack, kefrens and 3 others like this.
  5. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    243
    I also got this because I set the framerate through a script for WebGL as we're targeting different platforms.
    So why is this an error? Is this doing any harm??
     
    Novack likes this.
  6. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    The backstory here is that in web browsers, there are two JavaScript APIs that could be used to implement animation: requestAnimationFrame() and setTimeout() (there's also setInterval() which is essentially the same as setTimeout(), and also setImmediate(), which unfortunately had trouble ever getting standardized).

    From the perspective of the browsers, requestAnimationFrame() is superior in comparison to setTimeout() when implementing animation, since requestAnimationFrame() hints towards the browser that the update ticks intend to perform continuously animated rendering for two reasons:
    - requestAnimationFrame() firing rate can match display's refresh rate (30Hz/60Hz/90Hz/120Hz/144Hz are all possible, depending on what kind of gaming display one is running on, though last I checked, only Firefox implemented these rates, Chrome using fixed 60fps even if desktop was set to 120Hz). With setTimeout() one cannot know the display refresh rate, and has to guess/choose fixed 60Hz.
    - rAF() calls are also synced to display's vsync interval, giving smoother animation since there is a smaller chance that vsync intervals would be missed. setTimeout() is used on the web for arbitrary/general timers, and browser cannot deduce that those would need to be vsync locked.
    - rAF() calls hint to the browser that the callbacks are about rendering animation, so when the tab is not visible, browsers can optimize power usage e.g. by stopping rAF() callbacks until tab comes back to foreground. In general, rAF()s do not run when page is on the background or browser is minimized.

    In Unity, if Application FPS is set to 60, then rAF() is used to render. If any other FPS setting is used, then setTimeout() ticks are used to implement the custom FPS timer, since rAF() only works for 60fps.

    However because of the way how setTimeout()s are not scheduled with respect to display vsync like rAF() is, using setTimeout() to animate results in stuttering animation in browser. This is what the message "You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!" is about. The message originates from the Emscripten compiler that Unity uses, so it unfortunately reads a bit off from the perspective of Unity project settings UIs.

    If you want to render at a lower rate than 60fps, then there is no harm about this message. If you want to render at native display refresh rate, then you should set the FPS setting to 60. Using a value like 30 should be ok, although using a value like 59fps will probably yield horribly stuttering animation compared to 60.

    As a sidenote, there may be a possibility to get smoother animation rates from rAF() by decimating the calls, i.e. 60fps/2=30fps, 60fps/3=20fps, 60fps/4=15fps.. though this has not been extensively experimented with yet. (If you'd like, you can manually intercept requestAnimationFrame() implementation in JS code before the Unity app is loaded to experiment with this kind of decimation)
     
    Roy-Hu, patrickk2, Fenikkel and 7 others like this.
  7. hk1ll3r

    hk1ll3r

    Joined:
    Sep 13, 2018
    Posts:
    88
    Thats a detailed answer jukka. So what would be the BEST (getting the highest vsynced FPS) value to set for target frame rate in Unity for a webgl build?
    This page from manual suggests -1:
    https://docs.unity3d.com/Manual/webgl-performance.html
    You seem to say 60...

     
    Novack likes this.
  8. Swah

    Swah

    Joined:
    May 13, 2015
    Posts:
    80
    @jukka_j any answer on what the recommended setting for webgl builds? -1 or 60?
     
    Novack and zt3ff3n like this.
  9. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,266
    The problem with 60fps for webgl is PCs will punch up their GPU fans (!) which is unusual for browser content and indeed I am sure Safari will complain whatever (Apple hates web apps).
    30 fps seems to lead to choppy frame rates in chrome though I need more testing.

    A solution for easing browser-strain would be good...

    Getting red messages in console logs isn't ideal...
     
    Novack, amateurd and JoeStrout like this.
  10. Doomlaser

    Doomlaser

    Joined:
    Dec 9, 2013
    Posts:
    24
    Waiting for the canonical answer to this for webgl builds in the latest versions of Unity.

    Should we use:
    Application.targetFrameRate = 0
    Application.targetFrameRate = 60
    Application.targetFrameRate = -1

    or avoid it altogether?
     
    ExNinja and Novack like this.
  11. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    The default setting Application.targetFrameRate = -1 is the best, it will give vsynced 60hz updates as long as the performance is adequate.
     
    ExNinja, RoboDrone and Novack like this.