2D Outline and Rainbow outline 2 in 1

This is my first shader the code is edited but I hope you like it and it works for you

Just apply this shader to a sprite or animated sprite

Select rainbow to have an animated outline
or leave it to select your own outline color

All code is property of
Rainbow outline by @Farfalk and @ThePadDev

Thank you and enjoy!

Shader code
/* 
Rainbow outline by @Farfalk and @ThePadDev, And Edit for @LURGX in 2022

Apply to canvas items with transparent backgrounds.
Check that there is sufficient transparent background space for the outline!

CC0 License (but citation is welcome <3)
All code is property of @Farfalk and @ThePadDev
Thanks for shader and I'm a newbie with shaders 
*/

shader_type canvas_item;

uniform bool rainbow  = false; //Activate the rainbow or select you color
uniform vec4 line_color : hint_color = vec4(1.0, 1.0, 1.0, 1.0);//color line
uniform float line_scale : hint_range(0, 20) = 1.2;    // thickness of the line
uniform float frequency : hint_range(0.0, 2.0) = 0.5;  // frequency of the rainbow
uniform float light_offset : hint_range(0.00001, 1.0) = 0.5;   // this offsets all color channels;
uniform float alpha : hint_range(0.0, 1.0) = 1.0;

void fragment() {
	vec2 size = TEXTURE_PIXEL_SIZE * line_scale;
	
	float outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
	outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
	outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
	outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
	outline += texture(TEXTURE, UV + vec2(-size.x, size.y)).a;
	outline += texture(TEXTURE, UV + vec2(size.x, size.y)).a;
	outline += texture(TEXTURE, UV + vec2(-size.x, -size.y)).a;
	outline += texture(TEXTURE, UV + vec2(size.x, -size.y)).a;
	outline = min(outline, 1.0);
	
	vec4 animated_line_color = vec4(light_offset + sin(2.0*3.14*frequency*TIME),
							   light_offset + sin(2.0*3.14*frequency*TIME + radians(120.0)),
							   light_offset + sin(2.0*3.14*frequency*TIME + radians(240.0)),
							   alpha);
	
	vec4 color = texture(TEXTURE, UV);
	if (rainbow == true){//if rainbow is activated
		COLOR = mix(color, animated_line_color, outline - color.a);
	}
	if (rainbow == false){//if rainbow not is activated and you pick a color
		COLOR = mix(color, line_color , outline - color.a);
	}
}
Tags
2d, effect, GLES2, GLES3, outline, rainbow, shader
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.

More from lurgx

Low life flash 2D

Related shaders

Animated Screen Outline (flaming rainbow)

Rainbow Outline

Moving Rainbow Gradient

guest

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ALEX_EXE
ALEX_EXE
10 months ago

Good JOB. l apreciatte your comments in the CODE to understand it.
Thank you for upload it.

adictonator
adictonator
5 months ago

Hello,
Thanks for this great shader. I do however am seeing some issue with it on this AnimatedSprite frame I am using (found it somewhere).

It seems like it is showing the border of another frame on the top. So there is like a thin white line (or colored, if enabled) on the top of the frame.

Is there something that can be done about it?

wentbinary
wentbinary
3 months ago
Reply to  adictonator

First of all, thank you so much for the shader lurgx.

I crossed the same problem, and in my case, I figured that the problem is due to there being pixels in the lower limit of the frame on the sprite sheet, as an example I’ve drawn the outline manually on the sprite to check the result and basically, the outline bleeds from the above frame into the other animation frame that lays below, because it operates on all of the texture, that’s why it draws the outline for the pixels on the frame physically above.

As a work around, I just have to remove lines from the outline sum that contain “-size.y”.

This creates a problem where the bottom outline may not look the same as the remaining because it loses some of the corner pixels, but in my case, these changes made it look more akin to the style that I was going for. If you’re going for a “pixel perfect” outline, just remove all the corner portions of the outline also:

outline += texture(TEXTURE, UV + vec2(-size.x, size.y)).a;
outline += texture(TEXTURE, UV + vec2(size.x, size.y)).a;
outline += texture(TEXTURE, UV + vec2(-size.x, -size.y)).a;
outline += texture(TEXTURE, UV + vec2(size.x, -size.y)).a;

Hope this helps.