This repository has been archived on 2025-09-28. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
rectangular/core/shaders/screen_effects.gdshader

55 lines
1.4 KiB
Text
Raw Normal View History

2024-09-25 21:18:58 +02:00
shader_type canvas_item;
render_mode unshaded;
// uniforms
2024-09-25 21:18:58 +02:00
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap;
// constants
const vec3 BLACK = vec3(0);
const float glow_strength = 0.5;
const float glow_size_lod = 3.0;
const int outline_radius = 1;
// simple edge detection based on black
2024-09-25 21:18:58 +02:00
bool is_edge(int radius, vec2 screen_uv, vec2 screen_pixel_size) {
bool ed_found_bg = false;
2024-09-25 21:18:58 +02:00
bool ed_found_color = false;
// check neighbor pixels
for (int x = -radius; x < radius+1; x++) {
for (int y = -radius; y < radius+1; y++) {
vec4 p = texture(screen_texture, screen_uv + (vec2(float(x), float(y)) * screen_pixel_size));
if (p.rgb == BLACK) {
ed_found_bg = true;
2024-09-25 21:18:58 +02:00
} else {
ed_found_color = true;
}
}
}
return ed_found_bg && ed_found_color;
2024-09-25 21:18:58 +02:00
}
//
2024-09-25 21:18:58 +02:00
void fragment() {
// get screen texture
vec4 screen = texture(screen_texture, SCREEN_UV);
// apply edge detection
if (is_edge(outline_radius, SCREEN_UV, SCREEN_PIXEL_SIZE)) {
if (screen.rgb != BLACK) { // would be incompatible with target backgrounds != black
COLOR = screen;
}
2024-09-25 21:18:58 +02:00
}
// apply glow
// blur a relative radius -> x * log(1.0/SCREEN_PIXEL_SIZE.y)
// using log, because the LOD value seems to affect the blur radius exponentially
vec4 glow = textureLod(screen_texture, SCREEN_UV, glow_size_lod);
if (screen.rgb == BLACK) {
COLOR += glow * glow_strength;
2024-09-25 21:18:58 +02:00
}
// set alpha to 1
COLOR.a = 1.0;
2024-09-25 21:18:58 +02:00
}