Quick answer: Apply uv.y = lerp(uv.y, 1 - uv.y, step(0, _ProjectionParams.x)) in a Custom Function, or simpler: multiply Y by _ProjectionParams.x when sampling a screen-relative texture. Vulkan flips Y vs Metal/GL.

Custom shader uses Screen Position to sample a render texture. Looks correct on PC. Same shader on Android Vulkan shows a vertical flip. ProjectionParams.x covers it.

The Symptom

Screen-relative sampling (refraction, distortion, screen-grab) renders flipped on Android Vulkan. Same shader on Metal or DirectX is correct.

The Fix

In a Custom Function node:

void SafeScreenUV_float(float2 ScreenUV, out float2 Out)
{
    Out = ScreenUV;
    #if UNITY_UV_STARTS_AT_TOP
        Out.y = 1.0 - Out.y;
    #endif
}

UNITY_UV_STARTS_AT_TOP is defined on platforms with flipped framebuffer-Y. Branch and flip.

Or use ProjectionParams.x directly:

float2 uv = ScreenUV;
if (_ProjectionParams.x < 0) uv.y = 1.0 - uv.y;

Screen Position Modes

For sampling _CameraOpaqueTexture or similar, use Default and apply the platform flip.

Verifying

Build to Android Vulkan device. The screen-relative effect should match the Editor and PC builds. If still flipped, the platform branch isn’t firing — check that the include is reaching the shader.

“ProjectionParams.x or UNITY_UV_STARTS_AT_TOP. Vulkan stops flipping.”

Related Issues

For SRP Batcher, see SRP Batcher. For Shader Graph not in build, see build shader updates.

Branch the flip. Vulkan reads upright.