Clean pixel perfect outline via material

with this shader you can set personal outline thickness for each object

 

INSTRUCTION:

 

-just drop this shader to next pass in resource

 

 

 

outline is glitching with other objects but im gonna fix it. sometime…

Shader code
shader_type spatial;
render_mode unshaded;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture;
uniform vec4 outline_color : source_color;
uniform float outline_width = 2.0;
uniform bool constant_width = true;

void fragment() {
	vec4 pixelatedtext = texture(SCREEN_TEXTURE, SCREEN_UV);
	vec2 pixel_size = 1.0 / VIEWPORT_SIZE;
	ALBEDO = pixelatedtext.rgb;
	for(int y = -1*int(outline_width); y <= 1*int(outline_width); y++)
	for(int x = -1*int(outline_width); x <= 1*int(outline_width); x++)
	{
		vec4 tex = texture(SCREEN_TEXTURE, SCREEN_UV + vec2(float(x),float(y)) * pixel_size );
		if(tex.a == 0.0 && SCREEN_UV.x + float(x) * pixel_size.x < 1.0 && SCREEN_UV.x + float(x) * pixel_size.x > 0.0 && SCREEN_UV.y + float(y) * pixel_size.y < 1.0 && SCREEN_UV.y + float(y) * pixel_size.y > 0.0)
		{
			ALBEDO = outline_color.rgb;
			ALPHA = 1.0;
		}
	}
	
}
Tags
3d, outline, pixel perfect
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 LopkaUna

3D Pixelation via material

Related shaders

The simplest outline shader (via material)

3D Pixelation via material

Selective post-processing via material ID masking on a second visibility layer

Subscribe
Notify of
guest

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Laurels
Laurels
9 months ago

the outline blacks out the whole mesh whenever it’s in a scene with another material that has subsurface scattering enabled

Confused
Confused
8 months ago

This only works if the object is not in front of another object

martingu
martingu
6 months ago
Reply to  Confused

This is because it basically re-draws the whole object again with a boundary added on the second pass. For that it needs to read from the screen texture, which will not be up to date for overlapping objects. Anyway this is a VERY expensive way to achieve this and probably impossible to get it work correctly.

I suggest to use shader based on vertex offsets and drawing only backfaces, this way you only run a very simple unshaded fragment program for the actual outline pixels. Like this one here: https://godotshaders.com/shader/pixel-perfect-outline-shader/