Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Odd thick white outline artifact around 2d sprite after applying basic invert color shader

Discussion in 'Shaders' started by sobble_p, May 18, 2023.

  1. sobble_p

    sobble_p

    Joined:
    Dec 10, 2022
    Posts:
    3
    Hello unity forum. I'm a beginner to creating and understanding custom shaders in Unity and I have run into a problem that may be somewhat trivial but I cannot figure out how to fix it after looking through some online shader tutorials to see it would apply to my problem.

    Anyways, I have a 2D crosshair sprite plugged into the "Source Image" fill-in on an Image component in my Scene's UI Canvas object. The effect I'm going for is an inverted crosshair effect that'll take the background colors through the sprite and invert them. The issue is that this thick white outline not present in the original sprite file appears around it. I have checked the "Alpha is transparency" box on the sprite and have messed with the Texture Type settings and the Image component settings to see if something would do the trick but nothing changes it so this has led me to believe this is something with my custom shader. This outline also doesn't appear when selecting other built-in shaders in Unity. Am I missing something obvious?

    Screenshot of the crosshair with the invert effect using the custom shader:


    You can see the crosshair is inverting correctly but also that white outline appears around it when this shader is used.

    Screenshot of the crosshair using the UI/Unlit/Detail shader:


    Plus a paste of my shader file:

    Code (CSharp):
    1. Shader "Hyperborean/UI/Crosshair"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags
    10.         {
    11.             "RenderType" = "Transparent"
    12.             "Queue" = "Overlay"
    13.         }
    14.  
    15.         Cull Off ZWrite Off ZTest Always
    16.  
    17.         Pass
    18.         {
    19.  
    20.             Blend OneMinusDstColor OneMinusSrcAlpha // invert colors
    21.             BlendOp Add
    22.  
    23.             CGPROGRAM
    24.             #pragma vertex vert
    25.             #pragma fragment frag
    26.  
    27.             #include "UnityCG.cginc"
    28.  
    29.             struct appdata
    30.             {
    31.                 float4 vertex : POSITION;
    32.                 float2 uv : TEXCOORD0;
    33.             };
    34.  
    35.             struct v2f
    36.             {
    37.                 float2 uv : TEXCOORD0;
    38.                 float4 vertex : SV_POSITION;
    39.             };
    40.  
    41.             v2f vert (appdata v)
    42.             {
    43.                 v2f o;
    44.                 o.vertex = UnityObjectToClipPos(v.vertex);
    45.                 o.uv = v.uv;
    46.                 return o;
    47.             }
    48.  
    49.             sampler2D _MainTex;
    50.  
    51.             fixed4 frag (v2f i) : SV_Target
    52.             {
    53.                 fixed4 col = tex2D(_MainTex, i.uv);
    54.                 return col;
    55.             }
    56.             ENDCG
    57.         }
    58.     }
    59. }
    If I need to provide any more information, please let me know. Thanks in advance.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,402
    Because you’re adding the inverted color to the background.

    Try this:
    fixed4 col = tex2D(_MainTex, i.uv).a;


    That should fix it.

    The issue is when you’re using the default alpha blend, that’s applying the image’s own alpha to its color before adding it to the background (which is being multiplied by the inverse of the alpha). With the inverted color blend the alpha is never applied to the image’s color, so it’s multiplying that solid white with the inverted background color and adding that to the background.

    x + (1-x) = 1
     
  3. sobble_p

    sobble_p

    Joined:
    Dec 10, 2022
    Posts:
    3
    Ahh okay I see. I forgot to account for the alpha in this case. This worked perfectly. Thank you very much!



    I've been waiting for days for a response to this problem in other places while looking online for answers and I'm very thankful that I got a reply here so fast with a solution. Thanks, again!