Search Unity

Sprites and UI images give different results with a Color Pallet Shader

Discussion in 'Shaders' started by ChrisJohnson, Aug 6, 2021.

  1. ChrisJohnson

    ChrisJohnson

    Joined:
    Feb 20, 2013
    Posts:
    64
    Hello Everyone,

    Right now, I have a weird problem with my current game that I can’t figure out. In my game I have a color pallet shader, so that I can use different colors for the sprites in my game. The main problem I have is that sometimes the index color will skip to a wrong position on the color pallet.


    But this problem only happens with UI Images, and the shader seems to work fine with sprites. Here I made a project that demonstrates the problem. On some pallet indices the UI Image will show the wrong pallet color.

    Bug.png

    Here is the code for my shader:

    Code (CSharp):
    1. Shader "Sprites/Color Palette"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _SwapTex("Color Data", 2D) = "transparent" {}
    7.         _Color("Tint", Color) = (1,1,1,1)
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             "PreviewType"="Plane"
    18.             "CanUseSpriteAtlas"="True"
    19.         }
    20.  
    21.         Cull Off
    22.         Lighting Off
    23.         ZWrite Off
    24.         Blend One OneMinusSrcAlpha
    25.  
    26.         Pass
    27.         {
    28.             CGPROGRAM
    29.             #pragma vertex vert
    30.             #pragma fragment frag
    31.             #pragma fragmentoption ARB_precision_hint_fastest
    32.  
    33.             struct appdata_t
    34.             {
    35.                 float4 vertex   : POSITION;
    36.                 fixed4 color    : COLOR;
    37.                 float2 texcoord : TEXCOORD0;
    38.             };
    39.  
    40.             struct v2f
    41.             {
    42.                 float4 vertex   : SV_POSITION;
    43.                 fixed4 color    : COLOR;
    44.                 float2 texcoord    : TEXCOORD0;
    45.             };
    46.            
    47.             CBUFFER_START(UnityPerMaterial)
    48.             fixed4 _Color;
    49.             CBUFFER_END
    50.  
    51.             sampler2D _MainTex;
    52.             sampler2D _SwapTex;
    53.  
    54.             v2f vert(appdata_t IN)
    55.             {
    56.                 v2f OUT;
    57.                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
    58.                 OUT.texcoord = IN.texcoord;
    59.                 OUT.color = IN.color * _Color;
    60.  
    61.                 return OUT;
    62.             }
    63.  
    64.             fixed4 frag(v2f IN) : SV_Target
    65.             {
    66.                 fixed4 tex = tex2D(_MainTex, IN.texcoord);
    67.  
    68.                 fixed4 swapColor = tex2D(_SwapTex, fixed2(tex.x + IN.color.g, IN.color.b));
    69.                 fixed4 color = lerp(tex, swapColor, swapColor.a);
    70.                 color.a = tex.a * IN.color.a * swapColor.a;
    71.                 color.gb *= IN.color.r;
    72.                 color.rgb *= tex.a;
    73.  
    74.                 return color;
    75.             }
    76.             ENDCG
    77.         }
    78.     }
    79. }
     
  2. ChrisJohnson

    ChrisJohnson

    Joined:
    Feb 20, 2013
    Posts:
    64
    I think I might of figured out what is causing the problem. I am using the color of the material as the index for the shader. And I found out that if I cast the color to a Color32 then this will cause the Sprite to have the same messed up indexing as the UI.Image.


    So this makes me think that this is what is causing the problem with the UI.Image.
    I also looked at the source code for the UI.Image and it looked like it may be turning the Color into a Color32.


    The problem is, that if this is really the cause then I am still not sure how to fix it.