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;
}
}
}
the outline blacks out the whole mesh whenever it’s in a scene with another material that has subsurface scattering enabled
This only works if the object is not in front of another object
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/
yes this is what my shader based on!