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

SELECT PLAYER STYLE 80S GAME

GHOST SHINE

Related shaders

Animated Screen Outline (flaming rainbow)

Rainbow Outline

Moving RGB Rainbow Stripes

Subscribe
Notify of
guest

10 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ALEX_EXE
ALEX_EXE
2 years ago

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

adictonator
adictonator
2 years 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
2 years 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.

Andrew
Andrew
11 months ago

Use the line

uniform vec4 line_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);//color line

to make this work in godot 4.x

James
James
2 months ago
Reply to  Andrew

Oh man, you save the day!

Poppi
Poppi
10 months ago

I got the outline in editor, but nothing in game.
And, no error…

Last edited 10 months ago by Poppi