Godot Version
4.3
I made a shader to create an outline.
I set up the shader right in front of my camera.
If I test it in a test world with a white void i can clearly see the outline, but if there’s a mesh behind it the shader wont appear
Im pretty new to godot and shaders so take all im saying with a kilo of salt
Picture with shader
Gameplay with the shader applied but nothing appears
shader_type spatial;
render_mode unshaded;
uniform sampler2D screen_texture : source_color, hint_screen_texture, filter_nearest;
uniform sampler2D normal_texture : source_color, hint_normal_roughness_texture, filter_nearest;
uniform sampler2D depth_texture : source_color, hint_depth_texture, filter_nearest;
uniform float depth_treshold = 0.05;
uniform float void_depth = 1000.0; // Large fallback depth for void areas
vec3 get_original(vec2 screen_uv) {
return texture(screen_texture, screen_uv).rgb;
}
vec3 get_normal(vec2 screen_uv) {
return texture(normal_texture, screen_uv).rgb * 2.0 - 1.0;
}
float get_depth(vec2 screen_uv) {
float depth = texture(depth_texture, screen_uv).r;
// Handle invalid depth values in the void
if (depth <= 0.0) {
return void_depth;
}
return depth;
}
void vertex() {
POSITION = vec4(VERTEX, 1.0);
}
void fragment() {
vec3 original = get_original(SCREEN_UV);
vec3 normal = get_normal(SCREEN_UV);
float depth = get_depth(SCREEN_UV);
vec2 texel_size = 1.0 / VIEWPORT_SIZE.xy;
vec2 uvs[4] = {
SCREEN_UV + vec2(0.0, texel_size.y),
SCREEN_UV - vec2(0.0, texel_size.y),
SCREEN_UV + vec2(texel_size.x, 0.0),
SCREEN_UV - vec2(texel_size.x, 0.0)
};
float depth_diff = 0.0;
float normal_sum = 0.0;
// Loop through surrounding pixels to compute depth and normal differences
for (int i = 0; i < 4; i++) {
float d = get_depth(uvs[i]);
depth_diff += abs(depth - d);
vec3 n = get_normal(uvs[i]);
normal_sum += length(normal - n);
}
// Combine depth difference and normal difference for outline effect
float outline = clamp(depth_diff * 0.5 + normal_sum, 0.0, 1.0);
// Mix the original color with the outline effect
ALBEDO = mix(original, vec3(0.0), outline);
}