Version: 2020.3
Language : English
Single-Pass Stereo Rendering for Android
Building and using plug-ins for Android

Vulkan swapchain pre-rotation

If your application’s framebuffer orientation doesn’t match the display’s native orientation (portrait, for most devices), Android needs to apply an additional rotation every time a rendered frame appears on the screen. This additional rotation might incur a performance cost, depending on the device’s hardware capabilities.

In most cases, you can apply this rotation during renderingThe process of drawing graphics to the screen (or to a render texture). By default, the main camera in Unity renders its view to the screen. More info
See in Glossary
with very little overhead. To do this, navigate to the Android Player SettingsSettings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary
(see also: PlayerSettings.vulkanEnablePreTransform) and enable Apply display rotation during rendering.

Note: The rotation only applies when Unity renders directly to the backbuffer. It has no effect when rendering to a Render TextureA special type of Texture that is created and updated at runtime. To use them, first create a new Render Texture and designate one of your Cameras to render into it. Then you can use the Render Texture in a Material just like a regular Texture. More info
See in Glossary
.

To apply the rotation, Unity modifies the projection matrix (UNITY_MATRIX_MVP, UNITY_MATRIX_P). This means that the rotation itself is applied in the vertex shaderA program that runs on the GPU. More info
See in Glossary
.

The preTransform setting doesn’t affect the behavior of Unity’s C# API. For example, the value of Screen.width doesn’t change because of the preTransform setting. The same applies to viewportsThe user’s visible area of an app on their screen.
See in Glossary
and scissor rects. Unity adjusts these as needed, and also handles readback operations from the backbuffer such as Grab Pass, ReadPixels, or Screenshot.

Unity provides utility macros to handle special cases in shaders (for more information, see the Known limitations section below).

The macro UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION is only defined if all of the following conditions are true (otherwise, it’s undefined):

  • preTransform is enabled in the Player Settings
  • the platform is set to Android
  • the graphics API is set to Vulkan

UNITY_DISPLAY_ORIENTATION_PRETRANSFORM is a constant that is set to the current preTransform rotation. Its value is one of the following:

  • UNITY_DISPLAY_ORIENTATION_0
  • UNITY_DISPLAY_ORIENTATION_90
  • UNITY_DISPLAY_ORIENTATION_180
  • UNITY_DISPLAY_ORIENTATION_270.

If UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION is undefined, or when rendering to a Render Texture, the value of UNITY_DISPLAY_ORIENTATION_PRETRANSFORM is UNITY_DISPLAY_ORIENTATION_0.

UNITY_DISPLAY_ORIENTATION_PRETRANSFORM is translated into a Vulkan specialization constant, which makes it efficient to use in if or switch statements.

Known limitations

In the following cases, it’s likely that enabling preTransform requires additional modifications to your Unity Project before you can use it:

  • Shaders that don’t use Unity’s projection matrix
  • Shaders that depend on the current pixelThe smallest unit in a computer image. Pixel size depends on your screen resolution. Pixel lighting is calculated at every screen pixel. More info
    See in Glossary
    position in the fragment shader (SV_Position)
  • Shaders that use screen space derivatives (ddx, ddy)
  • Native rendering plugins that use the Vulkan swapchain image might need to be modified
  • Use of backbuffer with Unity RenderPass API in an MRT setup together with other Render Textures

These cases only apply when rendering directly to the backbuffer.

Additional resources

Single-Pass Stereo Rendering for Android
Building and using plug-ins for Android