Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to make sure a frame renders...?

Discussion in 'Editor & General Support' started by justin_kasowski, Oct 16, 2021.

  1. justin_kasowski

    justin_kasowski

    Joined:
    Jan 14, 2020
    Posts:
    45
    I have code that attempts to make a strobe effect and basically does this:

    Code (CSharp):
    1. if( Time.realtimeSinceStartupAsDouble - lastDisplayFrame < pulseRate)
    2.    Graphics.Blit(blackScreen, destination);
    3.  
    4. else{
    5.    DisplayStuff();
    6.    lastDisplayFrame = Time.realtimeSinceStartupAsDouble;
    7. }
    But it's dropping frames. This wouldn't be a big deal if it was dropping black frames, but it seems to consistently drop the frames I need to be displayed (probably because these take longer to process?).

    I believe this is because the framerate doesn't match the refresh rate of my monitor. I'm coding in VR and I'm not really sure how that all works when my monitor is 60hz but my headset is 90hz. It looks like the OpenVR SDK will set the framerate at 90hz if I disable some of the graphics processing to get a max framerate. Even when it's at the 90hz max, it still fails to render the frame sometimes.

    Is there a way to inhibit Unity from dropping a frame? I'd rather force it to wait a few milliseconds to finish the calculation than have it drop the frames. Either that, or some way to tell the next frame that the previous frame never rendered so it can be displayed one frame late.

    As always, help is appreciated!!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    If you actually want frame-to-frame guarantee of a strobe light (as in don't want to miss it), just count frames or time in Update() and when it's time, show a frame of white, then take it down the next frame, OR... wait until a certain amount of time has passed before removing it. This ensures that a transition to doing it will NEVER be missed.

    Beware that any extremely-narrow timeband phenomena is likely to have some kind of artifacting when the sampling interval approaches the bandwidth of the phenomena. This has to do with the Nyquist rate in digital signal processing:

    https://en.wikipedia.org/wiki/Nyquist_rate

    What I mean by this is someone running at 60hz is going to see a brighter one-frame strobe than someone running at 70hz because it will "dwell" in their vision for 1/60th of a second versus 1/70th of a second.

    If you decided to go to 2 frames of 70hz (and 1 frame at 60hz), you would be at 1/35th of a second, which is WAY brighter than 1/60th.
     
  3. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,907
    People don't get motion sickness in VR anymore we need to trigger epilepsy too? :D (sorry)
     
    Kurt-Dekker likes this.
  4. justin_kasowski

    justin_kasowski

    Joined:
    Jan 14, 2020
    Posts:
    45
    I hadn't thought about timing how long it's up, that's a very simple solution and seems like it should work :D
    That's a very good point about the perceived brightness... I'll have to keep that in mind moving forward. I'm going to implement a timer and will come back to post once it's working (hopefully!).
     
  5. justin_kasowski

    justin_kasowski

    Joined:
    Jan 14, 2020
    Posts:
    45
    I think it ended up being a problem with my shader being too much to handle. It works with lower resolution and simple settings but is still flickering pretty badly if I raise the graphics up... It's strange because it's telling me it's processing at 90FPS but that just doesn't seem to be true. I'll work on debugging a bit more tomorrow
     
    Kurt-Dekker likes this.