52 lines
1.4 KiB
Plaintext
52 lines
1.4 KiB
Plaintext
shader_type canvas_item;
|
|
render_mode unshaded;
|
|
|
|
const vec2 OFFSETS[8] = {
|
|
vec2(-0.71, -0.71),
|
|
vec2(-1, 0),
|
|
vec2(-0.71, 0.71),
|
|
vec2(0, -1),
|
|
vec2(0, 1),
|
|
vec2(0.71, -0.71),
|
|
vec2(1, 0),
|
|
vec2(0.71, 0.71)
|
|
};
|
|
|
|
uniform bool ripple = false;
|
|
uniform float line_thickness : hint_range(0.0, 100.0);
|
|
uniform vec4 line_color : source_color = vec4(1.0);
|
|
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
|
|
|
|
void fragment() {
|
|
// Get the size of the pixels on screen, and create a variable for out outline
|
|
vec2 size = line_thickness * SCREEN_PIXEL_SIZE;
|
|
float outline = 0.0;
|
|
|
|
// Project in each direction, and add up the alpha of each projection.
|
|
// This is similar to picking a point, hit testing in 8 directions, and
|
|
// returning true if the hit test works
|
|
for (int i = 0; i < OFFSETS.length(); i++) {
|
|
vec2 coordinate_offset = SCREEN_UV + size * OFFSETS[i];
|
|
outline += texture(screen_texture, coordinate_offset).a;
|
|
}
|
|
|
|
// Force outline to 1 or 0
|
|
//outline = sign(outline);
|
|
outline = .4 * (outline / 8.0) + .6 * sign(outline);
|
|
// Get the texture from the screen
|
|
vec4 c = texture(screen_texture, SCREEN_UV);
|
|
|
|
|
|
if(ripple){
|
|
c.rgb = line_color.rgb;
|
|
COLOR = c;
|
|
}else{
|
|
// If the alpha exists at least a little bit, amplify the colors.
|
|
// This ensures alpha and colors remain precise even when reading from screen.
|
|
if (c.a > 0.0001) {
|
|
c.rgb /= c.a;
|
|
}
|
|
COLOR = mix(c, line_color, outline - c.a);
|
|
}
|
|
|
|
} |