Configurable CanvasItem Outline Shader

This shader samples the alpha value of a configurable number of points around the current point at a given distance relative to the canvas size. Designed to be applied to a viewport container or texture with only the objects that need outlining visible on it. Increasing the samples count has a minor impact on performance, but can smooth out rough corners.

Shader code
shader_type canvas_item;
 
uniform vec4 outline_color : source_color = vec4(1.);
uniform lowp float outline_size : hint_range(0.0, 0.2, 0.001) = 0.01 ; // this is not in pixels.
uniform lowp float alpha_threshold : hint_range(0., 1., 0.1) = 0.5;
uniform float samples : hint_range(4, 32, 1) = 4;
 
vec2 rotate2d(vec2 vector, float angle){
	return vector * mat2(
				vec2(cos(angle),-sin(angle)),
                vec2(sin(angle),cos(angle)));
}

void fragment() {
	if (COLOR.a > alpha_threshold) discard;
	
	vec2 AR = vec2(TEXTURE_PIXEL_SIZE.x/TEXTURE_PIXEL_SIZE.y, 1.);
	
	vec2 rightvec = vec2(outline_size, 0);
	float amax = 0.;

	for (float i = 0.; i<samples; i++) {
		vec2 samplevec = rotate2d(rightvec, i*TAU/float(samples))*AR;
		vec4 sample = texture(TEXTURE, UV+samplevec);
		amax = max(sample.a, amax);
	}
	
	if (amax == 0.0) discard;

	COLOR = mix(outline_color - vec4(0.,0.,0.,1.), outline_color, amax);
}
Tags
canvasitem, outline
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

Configurable Box Blur

Hologram simple canvasItem shader

3D Hover CanvasItem

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
alienmonday
alienmonday
3 months ago

Hey! First thanks for the shader. I tried applying it to a SubviewportContainer that contains a Subviewport with a 3D scene with a cube. The outline works perfectly but the cube itself turns the same color as the outline if I set the Alpha Threshold to 1. Tried different values but I got a transparent cube with just the outline visible.
What could I be doing wrong?

Last edited 3 months ago by alienmonday