Search Unity

Resolved Stuttering frame rate in nearly empty scene (Quest 2)

Discussion in 'VR' started by Rory_B, Aug 21, 2021.

  1. Rory_B

    Rory_B

    Joined:
    May 6, 2017
    Posts:
    4
    I am running the latest XR packages installed as described in the replication instructions below. My scene has hardly anything in it, and yet I am having regular frame stuttering/drops (5-10 times per second).

    When you run the build I describe below on the Quest 2 (while connected to the build computer), you should see profiling data rolling in, in particular the frame rate chart.
    When pointing the headset almost anywhere, the CPU usage is around 14 ms (72fps). *** Except *** When looking down at the 5+ planes and the XR interaction rays, the CPU usage doubles to around 28 ms (36fps) every 8 frames (although it will happen more frequently if there is more geometry in the scene).

    In this scene, render profiling shows only 12 batches and 3,730 triangles per frame, which is much less than the recommendations of 50-100 batches and 50,000-100,000 triangles per frame that Oculus suggests for 72 fps. These batch and triangle values in the profiler do not vary across frames even when the frame drops are occurring.

    What can I do about this?

    Screen Shot 2021-08-21 at 12.32.58 PM.png

    Additional observations:
    The frame drops occur in simple scenes when post-processing effects are used (try putting an XR Rig into the default URP scene).
    The frame drops occur in this scene when the oculus is set to target 120 fps. In that case, the frame drops occur more often, resulting in an actually worse average fps than when the target is 72 fps.
    The frame drops occur in scenes even when development build is turned off.
    The frame drops occur in even when the XR Ray Interactors are not present, you just need to add a few more planes.
    Multi-pass vs. multi-view rendering has no effect on the frame drops.

    Since the rest of the calls each frame are completed within 2-3 ms, it doesn't look like it should be running out of CPU time, and if it was the geometry in the scene, it seems like it would lag on every frame, not every 8 frames.

    The main issue seems to come from the render thread, which shows a PlayerEndOfFrame call causing all of the extra lag. Turning off multithreaded rendering shows an additional call under PlayerEndOfFrame called FrameEvents.XREndFrame .



    ==== Minimal instructions to replicate problem ====

    New Unity project (2021.1.15f1.2775)
    3D template

    Enable pre-release packages
    Install XR Interaction Toolkit
    Install XR Plugin Management

    Go to Project Settings -> XR Plug-in Management
    Enable (under android) Oculus

    Remove default camera from scene
    Add XR -> XR Rig (Action-based) to scene
    Set XR Rig tracking origin mode to floor (suggested, but frame drops still happen if you don't do this step)
    Add 5+ planes to the scene (add more for exaggerated effect!)

    Go to Build Settings
    Switch target to Android
    Set Development Build
    Set Autoconnect Profiler
    Add the open scene
    Select the Quest 2 run device
    Click Build And Run
    Wait for the build to run on the Quest 2

    Point Quest 2 towards the sky, and observe steady frame rate in profiler
    Point Quest 2 towards the planes (& xr interaction rays, if you only added a few planes), and observe regular frame drops in profiler

    ==== End instructions ====
     
    Last edited: Aug 21, 2021
    kaliatech likes this.
  2. Rory_B

    Rory_B

    Joined:
    May 6, 2017
    Posts:
    4
    I discovered that overdraw seems to be the issue here. When looking at the overlapping planes, the average fill percentage (https://developer.oculus.com/documentation/unity/ts-ovrstats/) reaches 700-800% and causes the stuttering. In this scene, preventing the planes from overlapping fixes the problem. I am not sure why it is still a problem in my other scenes, but at least I now have a good starting point.

    I am looking forward to Unity GPU profiling support for Quest 2, because that would have made finding this problem a lot faster! The OVRMetrics / ovrgpuprofiler helped me track this problem down, but I feel like I just got lucky that it had a metric for exactly my problem.
     
    DevDunk and JoeStrout like this.
  3. GabrielTargo

    GabrielTargo

    Joined:
    Jan 2, 2023
    Posts:
    3
    Hello, do you have any update please ? i have the exact same issue with an almost empty scene (only XR Rig added)




    ....
     
  4. Rory_B

    Rory_B

    Joined:
    May 6, 2017
    Posts:
    4
    Hi! I am no expert and it has been quite a while since I thought about this, so I won't be of much help. But I can try to offer some suggestions of things to look at.

    Overdraw is the likely culprit if you are having the same problems that I did. The GameDev Guru has an article about overdraw that does a decent job explaining it, but the short version is: "overdraw is what happens when you draw the same pixels more than once (in a frame)".

    Here are some of the sources of overdraw that I frequently encounter:
    • Does your scene have post-processing? I am in the habit of removing all post-processing from my VR scenes, since it recalculates much of the screen, potentially several times.
    • Do you have UI elements over a large portion of the screen? The reason I discovered this issue in the first place was a hand-held UI object that, when held close to my face, covered most of the screen. The UI alone caused a ton of overdraw due to it being composed of several transparent and overlapping pieces.
    • Do you have a lot of transparent objects? Any pixels that are part of transparent objects need to be drawn at least twice -- once for the background and once for the transparent object. I think the XR Rig interaction rays might use a transparent shader since they made my overdraw issue worse, but I have not confirmed this.
    • Do you have overlapping geometry? In the example scene from my original question, the 5 planes were at the same exact location so the headset was forced to draw all of them rather than just the closest one. This resulted in 5x overdraw for every pixel in the planes.
    I suspect post-processing is your issue, since you say your scene is almost empty. I would try turning off (or completely removing) any post processing first, since that is a quick and easy fix. If that doesn't work, I would try looking at different parts of the scene with your headset, such as in my example where the problem only occurs when actually looking at the planes. If you can find a section of your scene that causes the problem, it can help narrow down a solution.

    Hope that helps!
     
    DevDunk likes this.
  5. GabrielTargo

    GabrielTargo

    Joined:
    Jan 2, 2023
    Posts:
    3
    Hello my friend, I finnaly found the problem, it was a mesh optimization & texture issue, it was quite complicated to debug because i had only one mesh in my scene and it works perfectly on Quest 2 ...
    I just learned that the number of triangle that can be displayed on quest 1 vs 2 is multiplied by almost 10.

    Anyway thanks for your help :)
     
    DevDunk likes this.
  6. hanisherif1997_unity

    hanisherif1997_unity

    Joined:
    Jun 25, 2021
    Posts:
    14
    Could u tell me what you did? I am sure that it could help others too