Stuttering frame rate in nearly empty scene (Quest 2)

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?

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 ====

1 Like

I discovered that overdraw seems to be the issue here. When looking at the overlapping planes, the average fill percentage (OVR Metrics Tool Stats Definition Guide: Unity | Oculus Developers) 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.

2 Likes

Hello, do you have any update please ? i have the exact same issue with an almost empty scene (only XR Rig added)

…

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!

1 Like

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 :slight_smile:

1 Like

Could u tell me what you did? I am sure that it could help others too