20
2018
Marching Ants Sprite Outline Shader
Saw interesting question here https://forum.unity.com/threads/animated-outline-effects-using-shader.600028/
and unity sprite outline https://github.com/wlgys8/Sprites-Outline + stackoverflow https://stackoverflow.com/a/16856878/5452781 to the rescue!
(although this is for 2D sprite..)
Results:

TODO
– Test how this would look with screenspace values (to keep same size even if zoomed)
– Maybe could check neighbor pixel to get “flowing direction” for each pixel ?
Modified shader: *note: hard coded values, could put them into properties, and also download the original github project first to test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // original source: https://github.com/wlgys8/Sprites-Outline | |
| Shader "Sprites/Outline (Marching Ants)" | |
| { | |
| Properties | |
| { | |
| [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} | |
| _Color ("Tint", Color) = (1,1,1,1) | |
| [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 | |
| // Add values to determine if outlining is enabled and outline color. | |
| [PerRendererData] _OutlineSize ("Outline", Float) = 0 | |
| [PerRendererData] _OutlineColor("Outline Color", Color) = (1,1,1,1) | |
| } | |
| CGINCLUDE | |
| #include "UnityCG.cginc" | |
| struct appdata_t | |
| { | |
| float4 vertex : POSITION; | |
| float4 color : COLOR; | |
| float2 texcoord : TEXCOORD0; | |
| }; | |
| struct v2f | |
| { | |
| float4 vertex : SV_POSITION; | |
| fixed4 color : COLOR; | |
| float2 texcoord : TEXCOORD0; | |
| }; | |
| fixed4 _Color; | |
| v2f vert_outline(appdata_t IN) | |
| { | |
| v2f OUT; | |
| OUT.vertex = UnityObjectToClipPos(IN.vertex); | |
| OUT.texcoord = IN.texcoord; | |
| OUT.color = IN.color * _Color; | |
| #ifdef PIXELSNAP_ON | |
| OUT.vertex = UnityPixelSnap (OUT.vertex); | |
| #endif | |
| return OUT; | |
| } | |
| sampler2D _MainTex; | |
| sampler2D _AlphaTex; | |
| float4 _MainTex_TexelSize; //magic var | |
| float _OutlineSize; //outline size | |
| fixed4 _OutlineColor; // outlie color | |
| fixed4 SampleSpriteTexture (float2 uv) | |
| { | |
| fixed4 color = tex2D (_MainTex, uv); | |
| return color; | |
| } | |
| ENDCG | |
| SubShader | |
| { | |
| Tags | |
| { | |
| "Queue"="Transparent" | |
| "IgnoreProjector"="True" | |
| "RenderType"="Transparent" | |
| "PreviewType"="Plane" | |
| "CanUseSpriteAtlas"="True" | |
| } | |
| Cull Off | |
| Lighting Off | |
| ZWrite Off | |
| Blend One OneMinusSrcAlpha | |
| //outline down | |
| Pass | |
| { | |
| Offset 1, 1 | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma multi_compile _ PIXELSNAP_ON | |
| #pragma shader_feature ETC1_EXTERNAL_ALPHA | |
| v2f vert(appdata_t IN) | |
| { | |
| return vert_outline(IN); | |
| } | |
| fixed4 frag(v2f IN) : SV_Target | |
| { | |
| fixed4 texColor = SampleSpriteTexture (IN.texcoord + fixed2(0,_MainTex_TexelSize.y*_OutlineSize)) * IN.color; | |
| fixed4 c = _OutlineColor * texColor.a; | |
| int w = ((int)(IN.texcoord.x * 100 + IN.texcoord.y * 100 + _Time.y * 5) & 1); | |
| return c*w; | |
| } | |
| ENDCG | |
| } | |
| //outline up | |
| Pass | |
| { | |
| Offset 1, 1 | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma multi_compile _ PIXELSNAP_ON | |
| #pragma shader_feature ETC1_EXTERNAL_ALPHA | |
| v2f vert(appdata_t IN) | |
| { | |
| return vert_outline(IN); | |
| } | |
| fixed4 frag(v2f IN) : SV_Target | |
| { | |
| fixed4 texColor = SampleSpriteTexture (IN.texcoord + fixed2(0,- _MainTex_TexelSize.y* _OutlineSize)) * IN.color; | |
| fixed4 c = _OutlineColor * texColor.a; | |
| int w = ((int)(IN.texcoord.x * 100 + IN.texcoord.y * 100 + _Time.y * 5) & 1); | |
| return c*w; | |
| } | |
| ENDCG | |
| } | |
| //outline left | |
| Pass | |
| { | |
| Offset 1, 1 | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma multi_compile _ PIXELSNAP_ON | |
| #pragma shader_feature ETC1_EXTERNAL_ALPHA | |
| v2f vert(appdata_t IN) | |
| { | |
| return vert_outline(IN); | |
| } | |
| fixed4 frag(v2f IN) : SV_Target | |
| { | |
| fixed4 texColor = SampleSpriteTexture (IN.texcoord + fixed2(_MainTex_TexelSize.x* _OutlineSize,0)) * IN.color; | |
| fixed4 c = _OutlineColor * texColor.a; | |
| int w = ((int)(IN.texcoord.x * 100 + IN.texcoord.y * 100 + _Time.y * 5) & 1); | |
| return c * w; | |
| } | |
| ENDCG | |
| } | |
| //outline right | |
| Pass | |
| { | |
| Offset 1, 1 | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma multi_compile _ PIXELSNAP_ON | |
| #pragma shader_feature ETC1_EXTERNAL_ALPHA | |
| v2f vert(appdata_t IN) | |
| { | |
| return vert_outline(IN); | |
| } | |
| fixed4 frag(v2f IN) : SV_Target | |
| { | |
| fixed4 texColor = SampleSpriteTexture (IN.texcoord + fixed2(-_MainTex_TexelSize.x* _OutlineSize,0)) * IN.color; | |
| fixed4 c = _OutlineColor * texColor.a; | |
| int w = ((int)(IN.texcoord.x * 100 + IN.texcoord.y * 100 + _Time.y * 5) & 1); | |
| return c * w; | |
| } | |
| ENDCG | |
| } | |
| // | |
| Pass | |
| { | |
| Offset 0, 0 | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma multi_compile _ PIXELSNAP_ON | |
| #pragma shader_feature ETC1_EXTERNAL_ALPHA | |
| v2f vert(appdata_t IN) | |
| { | |
| v2f OUT; | |
| OUT.vertex = UnityObjectToClipPos(IN.vertex); | |
| OUT.texcoord = IN.texcoord; | |
| OUT.color = IN.color * _Color; | |
| #ifdef PIXELSNAP_ON | |
| OUT.vertex = UnityPixelSnap (OUT.vertex); | |
| #endif | |
| return OUT; | |
| } | |
| fixed4 frag(v2f IN) : SV_Target | |
| { | |
| fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color; | |
| c.rgb *= c.a; | |
| return c; | |
| } | |
| ENDCG | |
| } | |
| } | |
| } |
Resources:
– wiki https://en.wikipedia.org/wiki/Marching_ants
– rectangle outline marching ants shader https://www.shadertoy.com/view/XltcR2
– 3d marching ants from uvs https://shaderfrog.com/app/view/1847
– marching ant ideas https://losingfight.com/blog/2007/08/30/an-alternate-way-to-implement-marching-ants/
– marching ants done in Flash http://www.quasimondo.com/archives/000573.php
Comparison (photoshop selection line)

Related Posts
2 Comments + Add Comment
Leave a comment
Recent posts
- LudumDare59 : Signal
- Unity Editor: Tree Generator
- Leaf/Foliage Generator Tools (Runs in Browser)
- Testing Unity AI Beta
- Ways to Support UnityCoder Development
- Using UI Slider to Create 5-Star Rating Element
- Game Music Library For Unity (editor plugin)
- Fontastic : Easily Test Fonts in Unity Editor!
- GeoTiff Importer & Terrain Generator for Unity
- Create Baked DropShadow for UI images
- .JP2 Ortho Image Converter to PNG/JPG/TIFF
- Convert LAS/LAZ/PLY pointclouds to GLTF (GLB) Point Meshes (standalone converter)
Recent Comments
- on Mesh Exploder (sources)
- on Sprite Sheet Flip Book Shader
- on Sprite Sheet Flip Book Shader
- on [Asset Store] PolygonCollider2D Optimizer
- on Trajectory Test Scene 2.0
- on Vector3 maths for dummies!
- on UnityHub 3.6.0: Remove Version Control & Cloud Dashboard columns
- on Using RenderDoc with Unity (graphics debugger)
Coin:
CUgDSbRqFcAumDSAcdKDvuXsw26VdkJe8C8WGUQHBAGS
An article by












Oooh. Nice one. I may borrow this at some point. 🙂
ashed (dotted) 2D Sprite Shapes in Unity
https://github.com/yasirkula/UnityDashedSpriteShape