How to achieve a good performance in a VR game

Performance VR

What we learned developing in Unity for this platform and what tools we use

Working at etermax as developers we usually find ourselves developing video game applications for mobile devices running on Android and iOS. However, during 2022 we decided to target a new platform in the virtual reality field: Oculus Quest 2.

At the beginning we found the great advantage that it was not only a single device, unlike what normally happens to us when working for mobile applications, but also that it ran Android applications, and this gave us many advantages. However, we were presented with new challenges, one of which was performance. Within the VR world, having a good constant frame rate, 72 FPS being the recommended value by Meta, is a basic necessity for the user experience to be pleasant.

At the same time, we did not want to sacrifice visual quality, so we had to work together — developers and artists — to take full advantage of the device’s resources.

From there, we began to investigate various sources and we came up with a series of guidelines to follow in order to achieve a good performance in a VR game.

Below, you will find some of the data we gathered and followed in order to achieve this goal:

Use of tools

At etermax we almost always use Unity as a tool for our developments. Something very positive for our workflows was that many of the internal tools we use could be reused, since we used Unity as the engine for our VR application.

Researching tools that could help us during this application’s development process was fundamental to us. For example, the well-known Unity Profiler and other more specific development tools in the Oculus Quest 2. Let’s go through the tools we decided to use one by one.

Profiler: This classic Unity tool is useful to identify excessive uses of resources in some specific cases. It’s great because we can see the source of those resource expenses. However, the biggest extra use that we can give it is Bridge Profiling.

Bridge Profiling: It’s perhaps the tool that was used the least at the beginning, but later proved to be very useful. It involves keeping the device connected and creating a build for it. Once it’s ready, it allows us to take the performance metrics in the profiler directly from the device. This is a great advantage over doing Profiler in editor, since the Profiler is used less in terms of performance, it messes up the evaluation much less, and most importantly, the application is tested directly on the device with the resources and its normal behavior.

Frame Debugger: It’s also another tool provided by Unity which we use mainly to analyze the amount of draw calls we had per frame. One of the main pieces of information that this tool provides us with is the reason why a draw call could not be batched with the previous one. This allows us to look for another possible solution regarding the use of materials, for example.

OVR Metrics: It’s one of the Oculus-specific tools to analyze the current use of the device. One practice the team started to follow was to always have OVR Metrics enabled in overlay to look for performance drops or strange behaviors. Over time, as we use VR on a daily basis, many of us developed a higher resistance to motion sickness so our perception regarding possible framerate drops is biased. Keeping an eye on these metrics helps us to better visualize these problems.

The tool allows us to visualize, among other things, the frame rate, CPU and GPU usage, early and stale frames. Mainly from here we use the frame rate information to meet the Meta requirement and the CPU and GPU usage to not use resources unnecessarily all the time. It is important to use these resources as little as possible to guarantee more battery life.

RenderDoc: One of the most complete tools — if not the most complete — that takes a screenshot of an application with all its models, textures, materials and draw calls among others and allows us to inspect them to find problems or failures. Although we don’t use it daily as we do other tools, RenderDoc is the one that helps us find problems that are difficult to identify.

Project Auditor: This tool is developed by Unity and is available from the Package Manager but we haven’t used it extensively yet. We found that the tool quickly generates a report with all kinds of performance issues within the project.

These issues it identifies are problems in the practices within the code, configurations that can be improved in Project Settings, improvements that can be made to the use of assets, information about the shaders that are being used and an analysis of the build time and final size.

All these tools are proving useful to us when developing for VR in Unity, which requires so much care for performance. Some were easier and more intuitive to implement and ask the whole team to use — such was the case of OVR Metrics — while others like RenderDoc are currently used by specialized team members, mainly technical artists. Regardless of the case, we want the whole team to ensure performance, as we learned and believe that it is essential when developing any application, but mainly in VR.

Power Management

During our research, we discovered that we could modify the processing power of the device. This is important for several reasons.

First, all Android devices are typically affected by the processing power of the device and its ability to dissipate the heat it generates.

There are two things at play here that we want to keep in balance. One is that we need to have as many resources available as possible, since we need to be able to maintain a good frame rate. On the other hand, this plays against us when looking for a good optimization in general because it increases the temperature of the device — affecting performance — and consumes more battery usage, since Meta specifically requires the disconnected device to have a minimum of battery life while the application is open.

Because of this, we had to find a balance between how much we wanted to ask for resources in each situation, and the reality is that there is no magic or predefined number. In fact, the default number if this value is not modified is to use the maximum of all resources constantly.

We could not assign a specific value for these resources from the Oculus SDK since, at the time of writing this article, it’s out of date. What can be done, however, is to assign a suggestion to the CPU and GPU of the value we expect to use.

The available values, going from lowest to highest usage, are: PowerSavings, SustainedLow, SustainedHigh and Boost. Based on these, we decided to do a couple of tests assigning SustainedLow to both the CPU and GPU:

OVRManager.suggestedCpuPerfLevel = OVRManager.ProcessorPerformanceLevel.SustainedLow;

OVRManager.suggestedGpuPerfLevel = OVRManager.ProcessorPerformanceLevel.SustainedLow;

From there, testing with the application and OVRMetrics open, we found that the framerate itself was unaffected, making it unnoticeable to the user. Moreover, we noticed that for the CPU most of the time it was at SustainedLow and only occasionally went up when necessary, while for the GPU it was mainly at SustainedHigh and momentarily went up to Boost.

We also noticed a minimal drop in framerate more marked when having to load things due to the change in device resource usage levels, but as it was only for a few seconds during a loading screen we decided to prioritize keeping a low value and let the device adjust the rest.

Conclusion

During all this time of development in Unity for the VR platform we learned not only about the importance of performance, which becomes fundamental and more complex in this type of projects, but we also learned how to really take care of it.

It was no longer only about ensuring texture dimensions are a power of two, using atlases and low-poly. We learned about the use of tools extensively beyond the profiler and created practices at the team level to be able to work together on how to identify these problems and then solve them.

It is also important to think about performance not only as not causing generic errors, but also to think about what is necessary for the platform we develop. Researching how the specific hardware works, taking advantage of its uniqueness, is something fundamental when the goal is to squeeze all the resources of the device.

In summary, the recommendation when developing in VR is to do a thorough research on how the device works and the recommendations to take into account regarding the performance of the device. Then, to acquire the necessary tools to be able to make those measurements and learn how to use them. And throughout the development, transfer ownership of watching those performance metrics to the team to identify problems as soon as possible and fix them to avoid problems in the long term.

, ,