Device Performance Optimization

Accommodate performance-intensive augmented reality apps by setting different camera modes in Unity and native. 

If the device becomes too hot, the operating system may throttle the app to avoid overheating. Therefore, Vuforia allows you to set the video mode of your device in response to the app’s runtime requirements. You can balance runtime performance against computational load and power consumption, giving you control of your app's performance characteristics.

Performance Mode

When developing apps for Microsoft HoloLens or other video see-through devices there may be situations where the AR experience should last for a longer duration or you need to minimize Vuforia Engine’s impact on the CPU to allow your own algorithms more time. To limit the extent that the experience may be cut short by battery depletion or performance throttling, a performance mode can be set in the Vuforia Engine API and in the Unity inspector.

Enumerator for CameraMode/VuCameraVideoModePreset

Unity MODE_DEFAULT

Native VU_CAMERA_VIDEO_MODE_PRESET_DEFAULT

Best compromise between speed and quality.

Unity MODE_OPTIMIZE SPEED

Native VU_CAMERA_VIDEO_MODE_PRESET_OPTIMIZE_SPEED

Minimize Vuforia Engine impact on the system.

Unity MODE_OPTIMIZE_QUALITY

Native VU_CAMERA_VIDEO_MODE_PRESET_OPTIMIZE_QUALITY

Optimize for Vuforia Engine performance. Application performance could go down.

The _DEFAULT is used if nothing else is set. Change the mode to _OPTIMIZE_SPEED if the Vuforia Engine performance in this mode meets your needs. If you expect the target to be moved continuously, we recommend using the default mode. 

Focus Mode

If the target is out-of-focus in the camera view, the camera image frame can be blurry, and the detection and tracking performance can be negatively affected.
It is recommended to make use of the appropriate Camera Focus Mode to ensure the best camera focus conditions.

Focus mode enum FocusMode/VuCameraFocusMode

Behavior

Unity FOCUS_MODE_NORMAL

Native VU_CAMERA_FOCUS_MODE_NORMAL

Sets the camera into the default mode as defined by the camera driver.

Unity FOCUS_MODE_TRIGGERAUTO

Native VU_CAMERA_FOCUS_MODE_TRIGGERAUTO

Triggers a single autofocus operation.

Unity FOCUS_MODE_CONTINUOUSAUTO

Native VU_CAMERA_FOCUS_MODE_CONTINUOUSAUTO

Lets you turn on driver-level continuous autofocus for cameras. This mode is recommended as it guarantees that the camera is always focused on the target.

Unity FOCUS_MODE_INFINITY

Native VU_CAMERA_FOCUS_MODE_INFINITY

Sets the camera to infinity, as provided by the camera driver implementation. This mode will set the camera to always focus on the background elements in the scene. (not supported on iOS)

Unity FOCUS_MODE_MACRO

Native VU_CAMERA_FOCUS_MODE_MACRO

Sets the camera to macro mode, as provided by the camera driver implementation. This mode provides a sharp camera image for closeups of approximately 15 cm, rarely used in AR setups. (not supported on iOS)

We encourage using  _CONTINUOUSAUTO in your applications whenever it is available on the device. Set this mode with CameraDevice.SetFocusMode() in Unity and cameraConfig.focusMode for native in your application.

If the _CONTINUOUSAUTO is not available, the next best option is to implement a 'touch to focus' behavior in your app using the  _TRIGGERAUTO value. The camera will then focus each time the user touches the screen. The disadvantage of this behavior is that most camera drivers pick a random direction to focus (near or far), so you have a 50% chance that the image will defocus and then focus on the target. Under certain conditions the tracking can be lost for a moment until a sharp image is provided again.

INFINITY and _MACRO are usable in certain application scenarios, as described above.

_NORMAL sets the camera into the default mode as defined by the camera driver.

See Camera API Overview on how to change the performance settings in native via the camera configuration or with the Camera Controller.

See Working with the Camera in Unity for more information on setting the focus mode and camera.

Setting Performance Mode and Framerate in Unity

The performance mode is found in Unity under Camera Device Mode in Vuforia Configuration in the Inspector Window of the ARCamera GameObject. Locate the Camera Device Mode dropdown menu and select one of the three possible modes.

Recommended Framerate Settings in Unity

The Vuforia Engine API for Unity provides the CameraDevice.GetRecommendedFPS() method to obtain and set a recommended render framerate based on your app's rendering and performance requirements. To set a target framerate, call these methods when initializing the app.

The getRecommendedFPS() returns the recommended framerate setting based on the device’s settings.

For video see-through devices, the below table shows the GetRecommendedFps() available on various device types. Generally, rendering on the HoloLens always needs to be at 60 fps, while AR rendering on a mobile handheld device can be at 30 fps or at 60 fps, depending on the device.

Eyewear/Mobile Device

Target Render
FPS

HoloLens 60
Magic Leap 60
Android Devices 30
iOS Device 60 (on most devices)

Set the Framerate in Unity

The following code block queries Vuforia for the recommended frame rate and sets it using Unity’s Application.targetFrameRate API:

using UnityEngine;
using Vuforia;

public class FrameRateSettings : MonoBehaviour
{
    void Start()
    {
        VuforiaBehaviour.Instance.OnVuforiaStarted += OnVuforiaStarted;
    }
    
    void OnVuforiaStarted()
    {
        // Query Vuforia for recommended frame rate and set it in Unity
        var targetFps = VuforiaBehaviour.Instance.CameraDevice.GetRecommendedFPS();

        // By default, we use Application.targetFrameRate to set the recommended frame rate.
        // If developers use vsync in their quality settings, 
	 // they should also set their QualitySettings.vSyncCount
        // according to the value returned above.
        // e.g: If targetFPS > 50 --> vSyncCount = 1; else vSyncCount = 2;
        if (UnityEngine.Application.targetFrameRate != targetFps)
        {
            Debug.Log("Setting frame rate to " + targetFps + "fps");
            UnityEngine.Application.targetFrameRate = targetFps;
        }
    }
}