All Oculus Quest developers MUST PASS the concept review prior to gaining publishing access to the Quest Store and additional resources. Submit a concept document for review as early in your Quest application development cycle as possible. For additional information and context, please see Submitting Your App to the Oculus Quest Store.
Fixed Foveated Rendering (FFR) renders the edges of your eye textures at a lower resolution than the center. The effect lowers the fidelity of the scene in the viewer’s peripheral vision, and is nearly imperceptible. This reduces the GPU load as a result of the reduction in pixel shading requirements. In addition, apps using FFR can dramatically increase the resolution of the eye texture, improving the image shown in the headset. Complex fragment shaders also benefit from this form of multi-resolution rendering.
Note that unlike some other forms of foveation technologies, Oculus Quest’s fixed foveation system is not based on eye tracking. The highest-resolution pixels are “fixed” in the center of the eye texture.
A detailed look at the benefits of using FFR can be found in our Optimizing Oculus Go for Performance blog post.
First, if you want to check if the device supports foveated rendering. Check the system property
VRAPI_SYS_PROP_FOVEATION_AVAILABLE, which will return
VRAPI_TRUE if foveated rendering is supported.
Then, to use FFR, call the following to set the degree of foveation:
vrapi_SetPropertyInt( &Java, VRAPI_FOVEATION_LEVEL, level );
level can be 0, 1, 2, 3, or 4:
The foveation level can also be configured to be automatically adjusted based on the GPU utilization. Dynamic foveation can be enabled with:
vrapi_SetPropertyInt( &Java, VRAPI_DYNAMIC_FOVEATION_ENABLED, true );
Dynamic foveation is disabled by default. When dynamic foveation is enabled, the foveation level will be adjusted automatically with a maximum level set to
VRAPI_FOVEATION_LEVEL. Foveation levels 3 (high) and level 4 (high top) are treated as the same level under dynamic foveation. Which of these two levels is chosen coincides with the
VRAPI_FOVEATION_LEVEL selection. For example, if
VRAPI_FOVEATION_LEVEL is set to level 4, dynamic foveation will vary between levels 0, 1, 2, and 4 exclusively.
Because dynamic foveation uses GPU utilization to increase or decrease foveation level, it’s fairly reactive and the level should increase before a stale frame is created in comparison to a fixed FFR level, but if increased stale frames are noticed in specific levels, dynamic FFR can be enabled and disabled in those areas. Use of dynamic FFR is highly recommended.
In the following images, the resolution in the center white areas is native: every pixel of the texture will be computed independently by the GPU. However, in the red areas, only 1/2 of the pixels will be calculated, 1/4 for the green areas, 1/8 for the blue areas, and 1/16 for the magenta tiles. The missing pixels will be interpolated from the calculated pixels at resolve time, when the GPU stores the result of its computation in general memory.
High Top FFR
You may choose to change the degree of foveation based on the scene elements. Apps or scenes with high pixel shader costs will see the most benefit from using FFR. Apps with very simple shaders may see a net performance loss from the overhead of using FFR. Proper implementation of FFR requires testing and tuning to balance visual quality and GPU performance.
Many developers simply use the high FFR setting for their entire app as a general solution for performance, which some have found to have a very noticeable impact on visuals. Here are some tips and best practices on better tuning the FFR settings in-game:
debug.oculus.foveation.levelis a system-wide FFR setting override that can be used to quickly test different FFR settings without changing/reinstalling/restarting the app, with 0 = Off, 1 = Low, 2 = Medium, 3 = High, 4 = High Top (for example,
adb shell setprop debug.oculus.foveation.level 2will set the FFR level to medium).
FPS=72,Prd=45ms,Tear=0,Early=67,Stale=0,VSnc=1,Lat=1,Fov=3,CPU4/GPU=2/2,1651/414MHz,OC=FF,TA=0/0/0,SP=N/N/N,Mem=1017MHz,Free=1576MB,PSM=0,PLS=0,Temp=27.0C/0.0C,TW=2.25ms,App=5.51ms,GD=0.77msshows an app running at 72 fps (FPS=72), with the app’s GPU rendering time at 5.51ms (App=5.51ms), and FFR on high (Fov=3). Regardless of visuals, in this case there is more than enough room to turn the FFR level down for a general improvement in the visual quality.