Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

On Demand Rendering new in a7

Discussion in '2019.3 Beta' started by HonorableDaniel, Jun 26, 2019.

  1. HonorableDaniel

    HonorableDaniel

    Joined:
    Feb 28, 2007
    Posts:
    2,844
    I noticed the following release note:
    • Graphics: On Demand Rendering. Ability to set the rendering speed independently from other engine updates.
    I would like to know more about it. Any more information? How do you use it? Why was it created?
     
    jhocking, Gekigengar, jGate99 and 2 others like this.
  2. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    181
    Plus one. More info please :)
     
  3. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    4,218
    An use-case I was always interested to implement, which requires this new feature:

    On a mobile device...
    • If there is little going-on animation wise and no user input, I wanted to reduce the frame-rate a lot, such as to 10 fps for example. This is to save battery power.
    • If the user touches the display again, I wanted to immediately increase the frame-rate again, so the game feels responsive.
    However, because rendering and input update rate can't be specified independently (in earlier Unity versions), as soon as I make the game run at 10 fps, input lags and you can't reliably detect immediate input changes.

    If the rendering speed is separated from the other engine parts, I just could reduce the rendering speed to 10 fps but keep the rest of the game, such as input, at 30 fps and the game will stay responsive and allows me to immediately detect input changes to increase the rendering speed again.
     
  4. HonorableDaniel

    HonorableDaniel

    Joined:
    Feb 28, 2007
    Posts:
    2,844
    Do you know how to start using it? What's the API?
     
  5. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    4,218
    Nope, I also wasn't able to find "On Demand Rendering" in the 2019.3 script reference yet.
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    5,553
  7. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,194
    I'm actually more curious what that GetRenderFrameInterval() does (I mean technically the steps, it's obvious from the name what it returns) and if it would be possible to expose it.
     
  8. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    209
    Two questions come to mind:
    * Is this approach similar to using the scriptable player loop to separate rendering functions from other subsystems?
    * If not, does this work on WebGL where rendering is done on the same thread as everything else?
     
    tcmeric likes this.
  9. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    907
    Same here
     
  10. davidro_unity

    davidro_unity

    Unity Technologies

    Joined:
    Apr 18, 2019
    Posts:
    10
    Hey all, just found this thread now after Hackweek.

    I believe that we're going to do a blog post about this feature at some point but I'll start off here with some details and answer any questions that you may have.

    First I want to say that Peter77 is spot on about what this feature is and why we created it.

    The API consists of only three properties in the namespace UnityEngine.Rendering.

    OnDemandRendering.renderFrameInterval

    This is the most important part. It allows you to get or set the render frame interval which is a dividing factor of Application.targetFrameRate or QualitySettings.vSyncCount to define the new framerate. For example, if you set Application.targetFrameRate to 60 and OnDemandRendering.renderFrameInterval to 2 only every other frame will render. Yielding a framerate of 30 FPS.

    OnDemandRendering.effectiveFrameRate

    An estimate of the frame rate that your application will render at. The estimate is determined using the values of OnDemandRendering.renderFrameInterval, Application.targetFrameRate, QualitySettings.vSyncCount and the display refresh rate. Of course this is just an estimate and not a guarantee and your application may render slower than this if the CPU is bogged down by work from other things such as scripts, physics, networking, etc.

    OnDemandRendering.willThisFrameRender

    This simply tells you if the current frame will be rendered to the screen. You can use non rendered frames to do some additional CPU intensive work such as heavy math operations, loading assets or spawning prefabs.

    The gist is that the rendering portion of the update loop is just skipped entirely on frames that don't need to be rendered.

    You probably can do something similar with the scriptable player loop. I have not personally tried though.

    It does work with WebGL! In fact it works on all platforms and render systems.
     
  11. HonorableDaniel

    HonorableDaniel

    Joined:
    Feb 28, 2007
    Posts:
    2,844
    Great, this sounds exciting! Any chance that you will add the ability for us to cause the render, similar to Camera.Render(). Often I have nothing moving on the screen until user input is detected, would be nice if it didn't render at all.
     
  12. davidro_unity

    davidro_unity

    Unity Technologies

    Joined:
    Apr 18, 2019
    Posts:
    10
    No plans currently. However you may be able to have that kind of control with the scriptable render loops(both light and high def).
     
    HonorableDaniel likes this.
  13. Inter-Illusion

    Inter-Illusion

    Joined:
    Jan 5, 2014
    Posts:
    472
    Can that be accomplished by setting OnDemandRendering.renderFrameInterval to a large value when nothing is moving, and then to 1 when we want the next frame to render?
     
    Yozaro and HonorableDaniel like this.
  14. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    693
    Is culling (and hence the culling callbacks) performed when rendering is not? If not, that would be useful as an optional feature to ensure script determinism regardless of the rendering interval.
     
  15. davidro_unity

    davidro_unity

    Unity Technologies

    Joined:
    Apr 18, 2019
    Posts:
    10
    Yeah you can absolutely do this. The change in to the rendering speed takes effect on the next player loop update so it's nearly instantaneous.
     
  16. davidro_unity

    davidro_unity

    Unity Technologies

    Joined:
    Apr 18, 2019
    Posts:
    10
    It looks like the answer is no, they will not be performed on update frames when rendering is not being done. The same is also true for WaitForEndOfFrame.
     
  17. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    693
    Hm, the former just means being careful with anything non-visual being triggered by those callbacks, which is not that much of an issue. WaitForEndOfFrame being skipped is a bit more of a concern. Isn't there any way for this feature to force it, so that there is a valid callback after LateUpdate?
     
  18. davidro_unity

    davidro_unity

    Unity Technologies

    Joined:
    Apr 18, 2019
    Posts:
    10
    I'm not quite sure how to handle that yet. The docs for WaitForEndOfFrame do specify that it is called at the end of a frame when camera and UI are rendered so it makes sense that it wouldn't occur on non-rendered frames. But I can definitely see how that could be an issue. I'll keep investigating to see if I can find a solution.
     
    Peter77 likes this.
  19. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    693
    Cool. Generally, I use https://docs.unity3d.com/Manual/ExecutionOrder.html as the holy bible of event order, and that always had that callback outside the rendering block, so if it cannot be raised it might just be a case of updating the diagram.
     
    Noisecrime likes this.
  20. Shikshen

    Shikshen

    Joined:
    Feb 21, 2015
    Posts:
    15
    I can confirm that this is a viable solution. What we did is, if nothing has changed since last frame (e.g. no calls to a custom RenderNextFrame() function), the current one will be rendered to an offscreen buffer that will be blit to the screen on every frame until something changes (skipping culling and rendering entirely).

    You have to be careful about the few cases where you need to render the frame even if nothing has changed (typically the screen/window size changed). There are a few other potential issues, for example it seems that Unity uses the culling phase to do other work, such as updating the particle systems. If you skip culling completely, they will not be updated at all. It is unlikely to be a problem, but this caused a few oddities in our project.
     
  21. HonorableDaniel

    HonorableDaniel

    Joined:
    Feb 28, 2007
    Posts:
    2,844
    I noticed that, seems the Animator acts odd when culling is shutoff. Hopefully Unity will address these culling-related issues in a future update.
     
  22. OCASM

    OCASM

    Joined:
    Jan 12, 2011
    Posts:
    266
    So I just found this thread and just wanted to say that you could do this sort of thing before by simply rendering manually into a RenderTexture with Camera.Render() and having another camera display the texture.
     
  23. Obsurveyor

    Obsurveyor

    Joined:
    Nov 22, 2012
    Posts:
    276
    Nope, input was still tied to framerate, so you'd still have to draw it 60 times a second if you wanted responsive input.
     
    HonorableDaniel and Prodigga like this.
  24. OCASM

    OCASM

    Joined:
    Jan 12, 2011
    Posts:
    266
    Only the camera displaying the rendertexture does so at 60fps, the camera that actually renders the scene (into the rendertexture) can be set to render to 1fps if you want to.
     
  25. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    786
    Which is the very problem that this feature solves. Rendering a full screen render texture at 60fps is not free. Not to mention that your frame time using your method would be slower overall since after the scene is rendered you then need to do additional work to blit that result to the frame buffer.
     
  26. CyRaid

    CyRaid

    Joined:
    Mar 31, 2015
    Posts:
    83
    Is this usable in 2019.2? I'm about to build an application that would definitely need a feature like this.
     
    Last edited: Nov 17, 2019 at 4:07 AM