2D Pixel Shadow/Outline

This is my own custom outline shader which supports configuring what sides the outline is on and whether it’s on the inside or outside.

This uses the canvas item’s texture to sampler from so it probably won’t work with 3d.

I didn’t know how to support width so maybe someone can improve it.

Shader code
shader_type canvas_item;

uniform bool top;
uniform bool left;
uniform bool right;
uniform bool bottom;
uniform bool topleft;
uniform bool topright;
uniform bool bottomleft;
uniform bool bottomright;
uniform vec4 color  : source_color = vec4(1.0);
uniform bool inside = false;

bool check(sampler2D sampler, vec2 uv, vec2 pixel_size, vec2 offset, bool _inside)
{
	vec4 c1 = textureLod(sampler, uv                      , 0.0);
	vec4 c2 = textureLod(sampler, uv - offset * pixel_size, 0.0);
	vec4 c3 = textureLod(sampler, uv + offset * pixel_size, 0.0);
	if (_inside) return (c1.a > 0.0) == true && (c3.a > 0.0) == false;
	return (c1.a > 0.0) == false && (c2.a > 0.0) == true;
}

void fragment() 
{
	bool b_top         = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(+0,-1), inside) && top;
	bool b_left        = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(-1,+0), inside) && left;
	bool b_right       = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(+1,+0), inside) && right;
	bool b_bottom      = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(+0,+1), inside) && bottom;
	bool b_topleft     = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(-1,-1), inside) && topleft;
	bool b_topright    = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(+1,-1), inside) && topright;
	bool b_bottomleft  = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(-1,+1), inside) && bottomleft;
	bool b_bottomright = check(TEXTURE, UV, TEXTURE_PIXEL_SIZE, vec2(+1,+1), inside) && bottomright;
	
	if (b_top || b_left || b_right || b_bottom || b_topleft || b_topright || b_bottomleft || b_bottomright)
	{
		COLOR.rgb = color.rgb;
		COLOR.a  += (1.0 - COLOR.a) * color.a;
	}
}
Tags
2d, outline, shadow
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Sub-Pixel Accurate Pixel-Sprite Filtering

Clean pixel perfect outline via material

Pixel Perfect outline Shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Null
11 days ago

Thanks this is a neat shader to use with a Sprite2D