Search Unity

UNITY_UV_STARTS_AT_TOP incorrect on iOS(?)

Discussion in 'Shaders' started by DanWeston, Sep 12, 2019.

  1. DanWeston

    DanWeston

    Joined:
    Sep 9, 2014
    Posts:
    19
    Recently I noticed that one of my shaders looked incorrect between iOS and Android. I conducted some test with the UNITY_UV_STARTS_AT_TOP define. I use this in the erroneous shader to work across my target platforms (mobile/windows).

    On iOS and Android I was expecting this to return false (or a value of 0) since I can evaluate that the uv 1 is at the top of the screen. On PC/DX the inverse is expected....

    However, from my tests I have noticed that on iOS UNITY_UV_STARTS_AT_TOP define returns a value of 1!

    The results of my test can be seen here (https://imgur.com/a/U7vkdgW)

    (see image in link...)
    Notice how the top left square proves that the uv coord 1 is at the top of the screen.

    Now notice on the Android screen grab the bottom left quad is green (returned when UNITY_UV_STARTS_AT_TOP is false)

    However, on iOS the bottom left quad is red (returned when UNITY_UV_STARTS_AT_TOP is true).

    This is contrary to the top left quad which proves that 1 is at the top (lerp (a, b, i.uv.y <= 0.5f)).

    My current work around is to use SHADER_API_MOBILE and then else check for UNITY_UV_STARTS_AT_TOP. Such that iOS and Android will fall into the my first condition. Originally I was just using UNITY_UV_STARTS_AT_TOP....

    Is this behaviour expected, if so am I misunderstanding this define? Or is this a Unity bug?
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    911
    Code (CSharp):
    1. #if defined(SHADER_API_D3D11) || defined(SHADER_API_PSSL) || defined(SHADER_API_METAL) || defined(SHADER_API_VULKAN) || defined(SHADER_API_SWITCH)
    2. #define UNITY_UV_STARTS_AT_TOP 1
    3. #endif
    It's not platform specific, it's graphics API specific. If you use OpenGL on iOS/Android, it will be 0.
     
  3. DanWeston

    DanWeston

    Joined:
    Sep 9, 2014
    Posts:
    19

    That makes sense, but what I'm trying to get my head around is why it's 1 on Metal when it (at least to me) seems clear that the UV coord is 1 at the top on Metal and not like DX(ect) where 1 is at the bottom of the screen... Thus UNITY_UV_STARTS_AT_TOP should be 0 on iOS/Metal?
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    911
    https://docs.unity3d.com/Manual/SL-BuiltinMacros.html
    "Always defined with value of 1 or 0. A value of 1 is on platforms where Texture V coordinate is 0 at the “top” of the Texture. Direct3D-like platforms use value of 1; OpenGL-like platforms use value of 0."