Version: 2021.3
Graphics for Android
Vulkan 交换链预旋转

Single-pass stereo rendering for Android

Unity supports single-pass stereo rendering for Android devices that support multiview. Multiview consists of the GL_OVR_multiview2 and GL_OVR_multiview_multisampled_render_to_texture OpenGL ES extensions. These extensions require shaders to use a 2D texture array that consists of two slices, one slice per eye. This differs from Unity’s PC/PS4 implementation of single-pass stereo rendering which uses a double-wide 2D texture. This means that shader modifications to support single-pass stereo rendering on Android are different from other platforms.

Shader code requirements

To use single-pass stereo rendering with custom shaders, you may need to include additional shader code. You don’t need to include additional code if your custom shaders are:

  • Surface Shaders that don’t have custom vertex processing.
  • Fixed-function pipeline shaders.

Note: These shader changes are compatible with multi-pass stereo rendering.

Modify your shaders

If you want to use the unity_StereoEyeIndex built-in shader variable to know which eye the GPU is rendering to, you must declare UNITY_VERTEX_OUTPUT_STEREO in any shader stage output structs that you have. For example:

struct v2f {
    float2 uv : TEXCOOR0;
    float4 vertex : SV_POSITION;
    UNITY_VERTEX_OUTPUT_STEREO
};

To initialize the output data, use UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO() in the vertex shader function. For example:

v2f vert (appdata v)
{
    v2f o;
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    return o;
}

To initialize unity_StereoEyeIndex in subsequent stages, add UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX() at the beginning. For example:

fixed4 frag (v2f i) : SV_Target
{
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    // 对纹理进行采样
    fixed4 col = tex2D(_MainTex, i.uv);
    // 应用雾
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

If your shaders use other shader stages, use the UNITY_TRANSFER_VERTEX_OUTPUT_STEREO() macro to transfer the eye index to the subsequent stages.

Tip: To calculate the final position of the object, it’s best practice to use UnityObjectToClipPos(IN.vertex) instead of mul(UNITY_MATRIX_MVP, IN.vertex).

Post-Processing Shaders

You must update post-processing shaders to deal with the eye textures being a 2D texture array. To help with this, Unity includes the UNITY_DECLARE_SCREENSPACE_TEXTURE() macro. To make textures work in both multi-pass and single-pass modes, wrap each textures in this macro. Also, when you sample the texture, use the UNITY_SAMPLE_SCREENSPACE_TEXTURE() macro.

This macro requires that you call UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX() beforehand when in single-pass mode. Unity also includes similar macros for depth textures and screen space shadow maps. You can see the full list at the bottom of HLSLSupport.cginc.

Graphics for Android
Vulkan 交换链预旋转