Oculus Go is a new standalone VR headset. It is compatible with the same Mobile SDK, Unity, and Unreal SDKs that power Oculus applications on Samsung Gear VR, and most Gear VR apps will run unmodified on Oculus Go. This post details our recommendations for developing Oculus Go apps and details some of the new tools and technical features we've built into this device.
Gear VR Compatible
Oculus Go is binary-compatible with Gear VR for most applications, and your existing Gear VR app can be deployed to an Oculus Go device and can usually be launched without modification. (Further below we discuss how to review and correct compatibility issues). However, there are a few areas where Oculus Go and Gear VR differ that are worth considering.Recommended Development Environment
We recommend developing for Oculus Go and Gear VR with the following tools:
Note that Oculus Go applications do not require “osig” files to run on retail devices. However, turning on access to adb to push application builds to an Oculus Go device requires “Developer Mode” be turned on, which in turn requires that you have created an Organization on the Oculus Developer Dashboard.
Fixed Foveated Rendering and other New Features
Oculus Go contains some unique features and improvements, including Fixed Foveated Rendering, Dynamic Throttling, and 72 Hz mode. Optimizing Oculus Go For Performance contains detailed technical discussion of these features. For lots more thoughts about using fixed foveated rendering, check out Oculus graphics engineer Rémi Palandri's OC4 talk at https://youtu.be/pjg309WSzlM?t=1671.
Here's a quick overview of the APIs involved.
Fixed Foveated Rendering
In Unity fixed foveated rendering can be enabled or disabled using the OVRManager.tiledMultiResLevel
property.
OVRManager.tiledMultiResLevel = OVRManager.TiledMultiResLevel.{Off/LMSLow/LMSMedium/LMSHigh};
In Unreal, this functionality is available in the 1.21 release of the Oculus branch for 4.18, as well as in 4.19 upstream. To enable fixed foveated rendering, call:
void UOculusFunctionLibrary::SetTiledMultiresLevel(ETiledMultiResLevel level)
Native developers should call:
// 0 - off, 1 - low, 2 - medium, 3 - high
vrapi_SetPropertyInt(&m_jni.m_java, VRAPI_FOVEATION_LEVEL, {0/1/2/3})
You can check to see if fixed foveated rendering is helping your application by inspecting the total GPU utilization with the feature on or off. Note that FFR will not help applications that do not have high GPU utilization. If your utilization is low, we recommend increasing the size of the eye buffer (see below) to 1280x1280 or higher. GPU utilization is reported by the operating system once per second in logcat. The log looks like this:
11-08 18:46:58.860 1698 1762 I UtilPoller: GPU Util 0.713356 / CPU Util 0.938144 (avg 0.839895)
Code provided here is available for use under the Oculus Examples License
Dynamic Throttling
Oculus Go includes a new approach to heat and battery management called Dynamic Throttling (described in the Optimizing Oculus Go For Performance document linked above). Dynamic Throttling does not require any new API--it uses the existing CPU Level and GPU Level interface to define a minimum clock level. However, for performance debugging it is useful to turn Dynamic Throttling off so that it does not interfere with performance timing. You can do this via adb:
adb shell setprop debug.oculus.adaclocks.force 0
The system will remain off until you restart the device or turn Dynamic Throttling back on by setting the above property to 1.
If you are using Oculus Go is your primary dev kit, we recommend turning dynamic throttling (and fixed foveated rendering) off to find the correct CPU and GPU levels for Gear VR.
72 Hz Mode
Oculus Go can optionally run at 72 frames per second rather than the normal 60 frames per second for increased brightness and color clarity. In Unity, you can turn on 72 Hz mode via the displayFrequency
property in OVRDisplay. You can also use OVRManager.display.displayFrequenciesAvailable
to get a list of display frequencies that the device supports.
OVRManager.display.displayFrequency = 72.0f;
In Unreal, the SetDisplayFrequency
Blueprint node will set the display frequency (use GetAvailableDisplayFrequencies
to see what the device supports). You can also call ovrp_SetSystemDisplayFrequency()
if you prefer.
For native code developers, vrapi_SetDisplayRefreshRate()
can be used to set the refresh rate.
vrapi_SetDisplayRefreshRate( app->GetOvrMobile(), 72.0f );
The available refresh rates can be queried with vrapi_GetSystemPropertyInt()
using VRAPI_SYS_PROP_NUM_SUPPORTED_DISPLAY_REFRESH_RATES
to get the number of supported rates, and vrapi_GetSystemPropertyFloatArray()
with VRAPI_SYS_PROP_SUPPORTED_DISPLAY_REFRESH_RATES
to get an array of the actual rates that are supported.
Performance Tuning
As with Gear VR applications, there are a few basic settings that should be enforced for all Oculus Go applications:
You can use OVR Metrics Tool to render a real-time performance graph overlay in the headset. Using OVR Metrics Tool on Oculus Go requires setting some system properties (via the adb shell setprop command
) to alter the displayed information for the performance HUD. These are as follows:
debug.oculus.omms.enableGraph
(true|false) - show or hide the overall performance graph debug.oculus.omms.enableGraph2
(true|false) - show a more detailed set of graphs for some stats. debug.oculus.omms.enableStats
(true|false) - show or hide stats display. debug.oculus.omms.pitch/.yaw/.distance/.scale
(number) - control the HUD position debug.oculus.omms.headLocked
(true|false) - whether to head lock the hud or position it in space Here are a few more system properties that can be useful for tuning performance, particularly for observing the impact of increased eye buffer resolution and fixed foveated rendering without having to rebuild an app for every test.
debug.oculus.textureWidth
(number) - set the default eye buffer width. Applications must be restarted to see the effect. Default is 1024.
debug.oculus.textureHeight
(number) - as above, but for default eye buffer height.
debug.oculus.foveation.level
(0/1/2/3) - turn fixed foveated rendering on at the specified level (or 0 for off). Can be toggled in real time as the app is running.
By combining these commands with the utilization information found in adb logcat referenced above, you can quickly tune both eye buffer size and fixed foveated rendering level based on the GPU load. Here's an example:
First, before launching the app, we can change the default eye buffer to 1280x1280 and make sure fixed foveation is off:
adb shell debug.oculus.textureWidth 1280
adb shell debug.oculus.textureHeight 1280
adb setprop debug.oculus.foveation.level 0
Now we launch the app and scan the log for performance information.
adb logcat | grep -e UtilPoller -e VrApi
This yields:
GPU Util 0.916190 / CPU Util 0.640000 (avg 0.543814)
FPS=42,Prd=47ms,Tear=0,Early=0,Stale=39,VSnc=1,Lat=1,CPU2/GPU=2/3
This means we're running at 42 fps and we're at ~91% GPU utilization, so we are GPU-bound. Now, while the app is running, we can turn on fixed foveated rendering and see what happens:
adb setprop debug.oculus.foveation.level 1
adb logcat | grep -e UtilPoller -e VrApi
Which results in:
GPU Util 0.591578 / CPU Util 0.625000 (avg 0.506702)
FPS=60,Prd=47ms,Tear=0,Early=0,Stale=0,VSnc=1,Lat=1,CPU2/GPU=2/3
In this case, even the lowest level of fixed foveation has brought the GPU utilization down to ~60% and pushed the frame rate back up to 60. Once the FFR and eye buffer values have been tuned I can modify my application to set these values on startup.
Submitting Apps and Updates for Oculus Go
Oculus Go application submission and updates are performed through the existing Oculus Developer Dashboard for Gear VR. Pushing an update to an application will push it both to Oculus Go and Gear VR users, and the process for new app submission remains largely the same. Here are a few new things to keep in mind when submitting apps or updates: