Oculus Performance in Unity Part 2: Tools and Baseline Measurements

Now that I have set up a test island environment in Unity that I can explore in virtual reality using an Oculus Rift, I will set up tools for measuring performance. I will measure baseline performance to determine how far the island scene is from acceptable VR performance.

A good summary of relevant performance tools is described in the Oculus Development Center. There are a lot of tools to consider. To stay focused, let’s keep in mind the important performance goals for smooth VR:

Unity Stats displayUnity ProfilerOculus Performance HUD
Frames per SecondGame Window onlyCPU ProfilerPerformance Summary
CPU timeGame Window onlyCPU Profiler
GPU timeGPU Profiler
draw callsRendering Profiler
triangles / verticesGame Window onlyRendering Profiler
dropped framesPerformance Summary

From this table we can see that we can get all the measurements we need using the Unity Profiler and the Oculus Performance HUD. There are many other tools that are helpful for specific purposes, but we will focus on these two for VR performance tuning. These tools are well documented, so I am not going to repeat that information in this blog; it is easy to find how to use the tools themselves. What I will do is list out a step-by-step recipe for using these tools to gather the needed measurements.

I won’t use the Unity Stats display because it only runs in the Unity Game Window. For accurate performance measurements, I will use compiled game builds rather than running in the Unity Editor.

Recipe for Collecting Performance Measurements

In Unity Player Settings, I set the Fullscreen Mode to be Windowed so that the application does not take over the full screen. I want to be able to see the Unity Profiler as we run. I check “Resizable Window” for this to work. I also turn off Mac Retina Support, since I am not using a Mac for this.

Configure Unity to display the environment in a window (not fullscreen).

Of course XR settings must be configured for Oculus Rift. I just accepted the defaults. Perhaps importing the Oculus Integration into Unity set this up already.

Unity XR Settings

In Unity Build Settings, I select the PC, Mac & Linux Standalone platform and include the island scene. Also very important, I click on Development Build and Autoconnect Profiler.

Unity Build should Autoconnect to the Profiler

Then I build the application, the Island test scene.

Next, I open the Unity Profiler window with these Profilers enabled: CPU, GPU, and Rendering.

Empty Unity Profiler

I then start the Oculus Debug Tool as instructed in its documentation. I set the Visible HUD to Performance and the Mode to Performance Summary.

Using the Oculus Debug Tool to show the Performance HUD

After all this setup, I start the built compiled scene executable via the Oculus Debug Tool’s File -> Launch App… menu item.

I then run the test scene from within the Oculus. Using the arrow keys I am able to move through the island environment. The Oculus Performance HUD appears superimposed over what I see using the Oculus.

Downward spikes in performance lower fps and result in dropped frames.

Observations:

  • The frames per second usually stays close to 90 fps, which is good.
  • However, the Performance Headroom intermittently goes negative. When that happens, fps dips down and frames are dropped. Clearly there are issues.

Next, I would like to get some metrics from the Unity Profiler. The Profiler captures a continual trace of data while the application is being used. To freeze a trace for inspection, I need to toggle off the Record button on the Profiler. This is a bit tricky while wearing the Rift.

Spikes in CPU and GPU profiles.

In the CPU Profiler I see that:

  • CPU time is usually about 11ms / frame, but with occasional spikes. One cause of spikes is XR.WaitForGPU. While this is happening, the GPU seems to be taking longer than usual with Device.Present. Another cause of CPU spikes is simply Camera.Render which indicates that there is just too much to draw.
  • GPU time is usually about 8ms but with occasional spikes.
  • Numbers of triangles and of vertices per frame is about a million each, which is within Oculus’ guidelines.
  • Number of draw calls per frame 3600-4000, which far exceeds Oculus’ guideline of 50-100.

Here is a table to summarize all the baseline measurements:

Frames per SecondCPU timeGPU timedraw calls / frametriangles, vertices / framedropped frames
Goal90 consistentlyat most 11 msat most 11 ms50 - 1001-2Mrare, maybe a few at scene transitions
Baseline90 but with downward spikes11 ms but with upward spike8 ms but with upward spikes3600-4000about 1Ma bunch during spikes

In summary, there are far too many draw calls and spikes in performance. Also, these measurements are for the environment only, not the many objects and scripts that will implement Sharkferno within the environment, so just considering the island environment, I need to achieve the performance goals with room to spare. The good news is that I now have baseline measurements so I will know when I have made improvements.

The next series of blog entries will each try a specific change to the Unity environment and then re-measure the performance. These will be experiments to find out how much different types of changes help achieve the performance goals. Of course I hope to discover that a few easy changes will result in the performance we need for a smooth VR experience. We will see…