Shader HLSL | Outline Pixel Art Shader

Introduction

This shader was made for Zeoland, a 2D retro style tactics game, still in development. I’m in charge of all the programming and effects. Raul, the game’s artist, wanted each character when selected to have a white outline, this both has a unique look and allows for a clearer visual effect for the player.

The problem was the outline was going to be done by hand and an additional animation would need to be provided for every character. This would cost a lot of resources, I decided that a shader would be necessary to reduce the extra asset load.

As I started thinking about solving the problem with a shader, I realized it would be fairly simple to create this effect. I just needed all the frames of the animation to have a 1-pixel alpha border. This would allow me to return a color (white) in the frag function instead of the alpha.

Here you can see the finished product of the outline shader.

tumblr_inline_olc2y4QmMP1toto34_500.gif

Here’s the simple shader, to use it in Unity create a material called “SpriteOutline”, then apply the material to any sprite you wish to have an outline.

Shader "Sprite/Outline" 
{
	Properties 
	{
	  	_MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)

        _Outline ("Outline", Float) = 0
        _OutlineColor ("Outline Color", Color ) = (1,1,1,1)
	}

	SubShader 
    {
 
        Tags 
        { 
        	"Queue"="Transparent" 
        	"IgnoreProjector"="True" 
        	"RenderType" = "Transparent" 
        	"PreviewType"="Plane"
        	"CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
 
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
 
            #include "UnityCG.cginc"

             sampler2D _MainTex;
             float4 _MainTex_ST;
             float4 _MainTex_TexelSize;
             float4 _Color;

             float _Outline;
             float4 _OutlineColor;

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

            v2f vert (appdata_base IN)
            {
                v2f OUT;

                OUT.pos = mul (UNITY_MATRIX_MVP, IN.vertex);
                OUT.uv = TRANSFORM_TEX(IN.texcoord, _MainTex);

                return OUT;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
            	fixed4 col = tex2D(_MainTex, IN.uv) * _Color;

            	if ( _Outline > 0 && col.a == 0)
            	{
            		fixed4 pixelUp = tex2D( _MainTex, IN.uv + fixed2(0,_MainTex_TexelSize.y));
                	fixed4 pixelDown = tex2D( _MainTex, IN.uv - fixed2(0,_MainTex_TexelSize.y));
                	fixed4 pixelRight = tex2D( _MainTex, IN.uv + fixed2(_MainTex_TexelSize.x,0));
                	fixed4 pixelLeft = tex2D( _MainTex, IN.uv - fixed2(_MainTex_TexelSize.x,0));
                		 
                	if ( pixelUp.a != 0 || pixelDown.a != 0  || pixelRight.a != 0  || pixelLeft.a != 0)
                	{
                		col.rgba = _OutlineColor;
                	}
            	}

            	return col;
            }
            ENDCG
         }
		
	}
	FallBack "Diffuse"
}

 

To add and remove the outline from your sprite you need to modify the “_Outline” property of the shader.

Here’s a simple script that will allow you to turn on and off the sprite outline.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s