Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Appears Unity's automatic conversion of Fixed Function Shaders has some bugs.

Discussion in 'Shaders' started by Noisecrime, Dec 12, 2018.

  1. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,050
    Hi,

    Having wasted a few hours trying to pin down a weird bug using a blur ( mutlitap ) shader effect, I figured i'd make a post here to alert others to the potential issue.

    Now i'm deep in the middle or an urgent project so I've not performed extensive tests to confirm this is purely a Unity bug. I will try and remember this and get back to it when I have more time, confirm the bug, make bug report etc.

    The Bug
    The problem appears to be that Unity's automatic upgrading of old fixed function shaders to modern vert/frag shaders fails to observe or maintain multiple uv channels inputs.

    The Situation
    The fixed function code I was using ( from Unity 3.x days ) was for performing BlurConeTaps. The code was originally grabed from Unity's ImageEffects but rewritten for direct use on material renderers and now I was going to use it on a UI RawImage. I didn't think anything of using the old fixed function shader as I knew Unity would deal with updating it and I just needed something quick to get working rather than modern and fast.

    Here is the original fixed function code:
    Code (CSharp):
    1. Shader "DellCES/Unlit/BlurConeTapSimple"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Source Texture", 2D) = "white" {}
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Pass
    11.         {
    12.             ZTest Always
    13.             Cull Off
    14.             ZWrite Off
    15.             Fog{ Mode Off }
    16.  
    17.             SetTexture[_MainTex]{ constantColor(0,0,0,0.25) combine texture * constant alpha }
    18.             SetTexture[_MainTex]{ constantColor(0,0,0,0.25) combine texture * constant + previous }
    19.             SetTexture[_MainTex]{ constantColor(0,0,0,0.25) combine texture * constant + previous }
    20.             SetTexture[_MainTex]{ constantColor(0,0,0,0.25) combine texture * constant + previous }
    21.         }
    22.     }
    23.  
    24.     Fallback off
    25. }
    The Issue
    Using 'Show Generated Code' on this shader and noticed this specifically
    Code (CSharp):
    1. // compute texture coordinates
    2. o.uv0 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    3. o.uv1 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    4. o.uv2 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    5. o.uv3 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    The problem is obvious, instead of each uv channel having its own unique uv values, the generated shader code was re-using the same uv0 channel each time.


    The Fix
    The fix was simple. I created a new shader, copy and pasted the generated code into it. Then added the uv channels to the app_data and fixed the code highlighted above
    Code (csharp):
    1. // vertex shader input data
    2. struct appdata
    3. {
    4.         float3 pos : POSITION;
    5.         float3 uv0 : TEXCOORD0;
    6.         float3 uv1 : TEXCOORD1;
    7.         float3 uv2 : TEXCOORD2;
    8.         float3 uv3 : TEXCOORD3;
    9.         UNITY_VERTEX_INPUT_INSTANCE_ID
    10. };
    11.  
    12. // compute texture coordinates
    13. o.uv0 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    14. o.uv1 = IN.uv1.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    15. o.uv2 = IN.uv2.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    16. o.uv3 = IN.uv3.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    So as far as I can tell Unity's code generation for fixed function fails to account for multiple uv channels. One problem with this is at low settings it kind hard to know that the shader was broken and in other cases it might nnt even be obvious as to what the problem is.

    So I've posted this just as a PSA in case someone has some random problem with a shader that they know is upgraded from fixed function programming and maybe this will point them in the right direction.

    Of course in my case this was the last thing I thought was causing the bug and instead spent a few hours rewriting various parts of the project code thinking the issue was related to other aspects. Now i've got to go back and clean up all my other changes ;)
     
    bgolus likes this.