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

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:

Shader "Hyperborean/UI/Crosshair"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags
        {
            "RenderType" = "Transparent"
            "Queue" = "Overlay"
        }

        Cull Off ZWrite Off ZTest Always

        Pass
        {

            Blend OneMinusDstColor OneMinusSrcAlpha // invert colors
            BlendOp Add

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

If I need to provide any more information, please let me know. Thanks in advance.

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

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!