Frame Pacing is a system that restricts an application to rendering frames at a lower framerate than a device's native refresh rate. This enables the application to prioritize consistency and stability in rendering, providing for a smoother user experience compared with letting the framerate run uncapped. In Unreal Engine 4 (UE4), frame pacing can be set on a per-device basis using the Device Profiles contained in your project's configs.
Editing Frame Pacing Settings in Device Profiles
Frame pacing can be controlled through CVars in the DeviceProfiles.ini
file containing your desired devices.
For iOS devices, you can add device profiles under
[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
For Android devices, you can add device profiles under
[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
The parameters that control frame pacing are as follows:
Parameter |
Usage |
Description |
||
---|---|---|---|---|
|
|
If set to true, allows any frame pacing. |
||
|
|
If set to true, allows 120Hz on capable devices. |
||
Available in 4.24 and earlier |
||||
|
|
Legacy variable for 4.24 and older for setting the refresh rate of frame pacing. Assumes a 60Hz refresh rate for a value of 1. |
||
Available in 4.25 and later |
||||
|
|
New method recommended for iOS and Android in 4.25. Sets the refresh rate directly to the value provided. |
||
|
|
Set to 0 by default. Setting this value to 1 will enable Google's Swappy frame pacing solution in place of the standard UE4 frame pacer for Android devices. Swappy uses the same CVars as the UE4 frame pacer. |
Guidelines for High Refresh Rates
The maximum refresh rate for frame pacing is normally capped at 60Hz, but enabling bEnableDynamixMaxFPS
increases this limit to 120Hz. Mobile devices supporting refresh rates greater than 60 Hz include the following:
Samsung Galaxy S20
OnePlus 7T
Google Pixel 4
iPad Pro 2nd generation and newer
Swappy Frame Pacing for Android
In addition to the legacy frame pacing system, Unreal Engine 4.25 integrates Google's Swappy frame pacer from the Android Game SDK.
Android hardware normally uses a frame buffer to display past frames when late frame submissions are detected, which prevents screen tearing. However, games' renderers are often unaware of this process and out of synch with it, causing them to get ahead of the displayed frame. This causes the display time for frames to vary wildly and creates significant input latency with touchscreen controls, as stalls will usually occur after input has been sampled.
Swappy is an Android-specific frame pacing solution designed to stabilize this behavior, providing not only the benefits of frame pacing, but also enabling a game's render cycle and Android devices' refresh cycle to communicate more effectively. This is an alternative to the legacy UE4 frame pacer that is used for all other hardware.
Enabling Swappy
As of 4.25, Swappy is not currently the default frame pacer for Android projects in Unreal due to a need for more testing, but it nets consistently smoother performance compared to the legacy frame pacer. Enabling it is recommended, and we are planning to use Swappy as the new default frame pacer for Android in future versions of the engine.
To enable Swappy for your Android projects, add a.UseSwappyForFramePacing=1
to the Android profiles you would like to use it. You can add it to Android_Default
to activate it for all Android devices.
Controlling Frame Pacing in C++
To control frame pacing in C++, you can call static functions from the FPlatformRHIFramePacer
interface. Frame pace is passed as a 32-bit integer when used as a parameter in these functions.
FPlatformRHIFramePacer::SupportsFramePace
checks whether the specified frame pace is compatible with the current device's refresh rate. FPlatformRHIFramePacer::SetFramePace
sets the pace to a specified integer value, and FPlatformRHIFramePacer::GetFramePace
returns the current frame pace.