Search Unity

Inconsistent results from UnityObjectToClipPos in Unity 5.6

Discussion in 'Shaders' started by Poya, Apr 28, 2017.

  1. Poya

    Poya

    Joined:
    Jul 3, 2011
    Posts:
    51
    Hi All,

    I just upgraded my project from Unity 5.5 to 5.6.0f3 (also tried the 2017 beta). One of my shaders seems to have broken since. It's essentially a screen space gradient shader. The result from UnityObjectToClipPos seems to have their sign flipped. What's more interesting / problematic is that both in the Editor, and also whenever I have a texture (screen) shader enabled on the camera, the result are correct and as before.

    Here is the shader code:

    Code (CSharp):
    1. Shader "Custom/ScreenGradient"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.         _NoiseTex("Noise Texture", 2D) = "white" {}
    7.         _BottomColor("Bottom Color", Color) = (1,1,1,1)
    8.         _TopColor("Top Color", Color) = (1,1,1,1)
    9.         _Offset("Offset", float) = 0
    10.     }
    11.  
    12.     SubShader
    13.     {
    14.         Tags
    15.         {
    16.             "Queue" = "Transparent"
    17.             "IgnoreProjector" = "True"
    18.             "RenderType" = "Transparent"
    19.             "PreviewType" = "Plane"
    20.             "CanUseSpriteAtlas" = "True"
    21.         }
    22.  
    23.         Cull Off
    24.         Lighting Off
    25.         Blend One OneMinusSrcAlpha
    26.  
    27.         Pass
    28.         {
    29.         CGPROGRAM
    30.  
    31.         #pragma vertex vert
    32.         #pragma fragment frag
    33.         #include "UnityCG.cginc"
    34.  
    35.         struct appdata_t
    36.         {
    37.             float4 position    : POSITION;
    38.             float2 uv        : TEXCOORD0;
    39.         };
    40.  
    41.         struct v2f
    42.         {
    43.             float4 position    : SV_POSITION;
    44.             float2 uv        : TEXCOORD0;
    45.             half4 color        : COLOR;
    46.         };
    47.  
    48.         sampler2D _MainTex;
    49.         sampler2D _NoiseTex;
    50.         float4 _MainTex_ST;
    51.         half4 _BottomColor;
    52.         half4 _TopColor;
    53.         float _Offset;
    54.  
    55.         v2f vert(appdata_t IN)
    56.         {
    57.             v2f OUT;
    58.             OUT.position = UnityObjectToClipPos(IN.position);
    59.             OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
    60.  
    61.             float factor = mad(OUT.position.y, -0.5, 0.5);
    62.             factor *= 1 + _Offset*2;
    63.             factor -= _Offset;
    64.             factor = clamp(factor, 0, 1);
    65.             OUT.color = lerp(_BottomColor, _TopColor, factor);
    66.  
    67.             return OUT;
    68.         }
    69.  
    70.         float3 getNoise(float2 uv)
    71.         {
    72.             float3 noise = tex2D(_NoiseTex, uv * 100 + _Time * 50);
    73.             noise = mad(noise, 2.0, -0.5);
    74.  
    75.             return noise/255;
    76.         }
    77.  
    78.         half4 frag(v2f IN) : SV_Target
    79.         {
    80.             half4 texCol = tex2D(_MainTex, IN.uv);
    81.            
    82.             half4 c;
    83.             c.rgb = IN.color.rgb + getNoise(IN.uv);
    84.             c.rgb *= texCol.a;
    85.             c.a = texCol.a;
    86.  
    87.             return c;
    88.         }
    89.  
    90.         ENDCG
    91.         }
    92.     }
    93. }
    What it looks like without any screen shader effects (light near the top, dark near the bottom):

    screen1.png

    And how it looks if I have an image effect on or in the editor (dark near the top, light near the bottom)

    screen2.png screen3.png


    Any help would be much appreciated
     
  2. Poya

    Poya

    Joined:
    Jul 3, 2011
    Posts:
    51
    OK, after much reading I came across a solution which may help others running into a similar issue:

    _ProjectionParams is a built in variable in the shaders which contains some platform-specific data. Specifically some "platforms" use an inverted projection which you can query for using _ProjectionParams.x. So what I had to do is change this line from above:

    Code (CSharp):
    1. float factor = mad(OUT.position.y, -0.5, 0.5);
    to this:

    Code (CSharp):
    1. float factor = mad(OUT.position.y, _ProjectionParams.x*0.5, 0.5);
    For further details see Platform-specific rendering differences.

    Why this only started showing itself after I upgraded to 5.6, and more strangely why I'm getting two different behaviours on the same hardware is quite a mystery to me.