Version: Unity 6.5 (6000.5)
Language : English
Foveated rendering shader compatibility workflow
Adapt custom shaders for foveated rendering

Enable and control foveated rendering

To enable foveated rendering in your project, enable it in your project’s XR provider plug-in settings, then set the foveated rendering level at runtime with a script.

Note: Enabling the project setting on its own has no effect, and Unity ignores the runtime value if you don’t enable the project setting.

On devices that track the user’s eyes, you can also allow gaze-based foveated rendering at runtime. You can read the current device’s capabilities to find out what it supports.

Prerequisites

Before you begin, make sure that your project, XR provider plug-in, and target device meet the conditions in Foveated rendering support reference.

Enable foveated rendering in project settings

An option to enable foveated rendering appears in the settings section for each plug-in that supports it. Refer to the documentation of the XR provider plug-in for information about the available settings.

To enable foveated rendering for a Unity project:

  1. Go to Edit > Project Settings.
  2. Select the XR Plug-in Management section.
  3. Enable foveated rendering in the settings section for your XR provider plug-in.

After you enable the setting, set the foveated rendering level at runtime, as described in Set the foveated rendering level.

Note: XR platforms can provide different levels of control for foveated rendering. For example, when you use Metal rendering on visionOS, fixed foveated rendering is always at full strength when you enable it. On Meta Quest devices, the value selects one of several discrete foveation levels rather than a continuous strength.

Set the foveated rendering level

The foveatedRenderingLevel property of XRDisplaySubsystem takes a value between zero and one. A value of zero disables foveated rendering, so it doesn’t affect rendering.

To set the foveated rendering level:

  1. Get the XRDisplaySubsystem from the SubsystemManager.

  2. Wait three frames, because the XRDisplaySubsystem can take up to three frames to fully initialize before you access its properties and methods.

  3. Assign a value between zero and one to the foveatedRenderingLevel property:

    public void SetFoveatedRenderingLevel(XRDisplaySubsystem xrDisplaySubsystem, float strength)
    {
        xrDisplaySubsystem.foveatedRenderingLevel = strength;
    }
    

After you set a level greater than zero, the device renders the periphery of the display for each eye at a lower resolution. If rendering doesn’t change, check that you enabled foveated rendering in your provider plug-in settings, because Unity otherwise ignores the runtime value.

Check what the current device supports

To find out what the current device supports, read the foveatedRenderingCaps property of SystemInfo:

using UnityEngine.Rendering;

FoveatedRenderingCaps caps = SystemInfo.foveatedRenderingCaps;

For the values this property reports and what each one means, refer to Foveated rendering support reference.

Allow gaze-based foveated rendering

On devices that support eye-tracked, or gaze-based, foveated rendering, the foveatedRenderingFlags property of XRDisplaySubsystem allows the feature. You can set this property on devices that support it even if you choose fixed foveated rendering at runtime.

Some devices require the user’s permission before you can access eye-tracking data.

To allow gaze-based foveated rendering:

  1. Request any permission the platform requires to access eye-tracking data.

  2. Set the foveatedRenderingFlags property on the active subsystem:

    // xrDisplaySubsystem is the active XRDisplaySubsystem instance
    xrDisplaySubsystem.foveatedRenderingFlags = XRDisplaySubsystem.FoveatedRenderingFlags.GazeAllowed;
    

The following example enables foveated rendering at 50% strength and sets the rendering flags to allow gaze-based foveation. The example uses a coroutine to wait three frames, to make sure the subsystem is ready. It also shows how to request eye-tracking permission for the Android-based Meta Quest Pro device. Other XR devices and platforms use different permission strings, APIs, or other mechanisms for requesting permissions.

using UnityEngine;
using UnityEngine.Android;
using UnityEngine.XR;
using System.Collections.Generic;
using System.Collections;
public class FoveationStarter : MonoBehaviour
{
    [Range(0,1)]
    public float foveationStrength = 0.5f;
    public bool AllowGaze = false;

    List<XRDisplaySubsystem> xrDisplays = new List<XRDisplaySubsystem>();

    void Start()
    {
        StartCoroutine(WaitForXRDisplay());

        if (AllowGaze)
        {
            // Request eye tracking permission for Quest devices
            Permission.RequestUserPermission("com.oculus.permission.EYE_TRACKING");
        }
    }

    IEnumerator WaitForXRDisplay()
    {
        yield return new WaitUntil(() => Time.frameCount >= 3);

        SubsystemManager.GetSubsystems(xrDisplays);
        if (xrDisplays.Count == 1)
        {
            xrDisplays[0].foveatedRenderingLevel = foveationStrength;
            if(AllowGaze){
                xrDisplays[0].foveatedRenderingFlags =
                    XRDisplaySubsystem.FoveatedRenderingFlags.GazeAllowed;
            }
            Debug.Log($"Foveated rendering set to {xrDisplays[0].foveatedRenderingLevel}.");
        }
        else
        {
            Debug.LogWarning($"Couldn't find an XRDisplaySubsystem for foveated rendering.");
        }
    }
}

After you set the flag, the highest-resolution area of the screen follows the user’s gaze on devices that support eye tracking. Devices that don’t support eye tracking, and devices on which the user denies permission, continue to use fixed foveated rendering.

Additional resources

Foveated rendering shader compatibility workflow
Adapt custom shaders for foveated rendering