Sprite Outline

Sprite Outline

In this “Unity Sprite Outline” tutorial we’ll discover how to create both a “Sprite Innerline” and a “Outer Sprite Outline”.
Simply, the Inner Sprite Outline shader is drawn “inside” the sprite, while “Outer” is the opposite

Read more about “Texture’s Texel Size” here.

0:00
/0:01

HLSL

Inner Sprite Outline HLSL

Shader "Unlit/InnerSpriteOutline HLSL"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_OutlineColor("Outline Color", Color) = (1,1,1,1)
    }
    SubShader
    {
		Tags
		{
			"RenderType" = "Transparent"
		}
 
		Blend SrcAlpha OneMinusSrcAlpha
 
        Pass
        {
            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;
            };
 
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _MainTex_TexelSize;
 
			fixed4 _OutlineColor;
 
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }
 
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
 
				fixed leftPixel = tex2D(_MainTex, i.uv + float2(-_MainTex_TexelSize.x, 0)).a;
				fixed upPixel = tex2D(_MainTex, i.uv + float2(0, _MainTex_TexelSize.y)).a;
				fixed rightPixel = tex2D(_MainTex, i.uv + float2(_MainTex_TexelSize.x, 0)).a;
				fixed bottomPixel = tex2D(_MainTex, i.uv + float2(0, -_MainTex_TexelSize.y)).a;
 
				fixed outline = (1 - leftPixel * upPixel * rightPixel * bottomPixel) * col.a;
 
                return lerp(col, _OutlineColor, outline);
            }
            ENDCG
        }
    }
}

Outer Sprite Outline HLSL

To have achieve an “Outline” instead of an “Innerline”, just change the “outline” line (in the previous code snippet) into this:

fixed outline = max(max(leftPixel, upPixel), max(rightPixel, bottomPixel)) - col.a;

Amplify Shader

Inner Sprite Outline ASE

Outer Sprite Outline ASE

Thanks for reading! ❤️

Let us know what you think! We're a small team and we are loving what we do, so any feedback is appreciated ❤️ You can also consider joining the newsletter (either weekly or monthly, we care deeply about it) and never miss our new posts. Cheers!

✦  Join the newsletter Already have an account? Sign in

Comments

More Posts

The Best Gamescom so far! August 2025

The Best Gamescom so far! August 2025

We just attended Gamescom (and devcom) this year and they were the best one for us so far!! Here's a short update about the general mood and more thoughts.

I'm giving a talk at devcom 2025!

I'm giving a talk at devcom 2025!

I am giving a talk at devcom 2025 about the many lessons I have learned while developing and selling Text Animator for Unity! I'll also make a post here in the future... read more!

Resuming content and tools!

Resuming content and tools!

We are ready to post new content and tools!! Text Animator for Godot, for Unity 3.X, a game in development and more.