mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-01 16:09:49 +00:00
48 lines
1.3 KiB
Plaintext
48 lines
1.3 KiB
Plaintext
// Based on https://godotshaders.com/shader/2d-outline-inline/
|
|
shader_type canvas_item;
|
|
render_mode unshaded;
|
|
|
|
uniform vec4 color : source_color = vec4(1.0);
|
|
uniform float width : hint_range(0, 10, 1) = 1.0;
|
|
uniform int pattern : hint_range(0, 2) = 0; // diamond, circle, square
|
|
uniform bool inside = false;
|
|
uniform sampler2D selection;
|
|
|
|
|
|
bool has_contrary_neighbour(vec2 uv, vec2 texture_pixel_size, sampler2D tex) {
|
|
for (float i = -ceil(width); i <= ceil(width); i++) {
|
|
float offset;
|
|
|
|
if (pattern == 0) {
|
|
offset = width - abs(i);
|
|
} else if (pattern == 1) {
|
|
offset = floor(sqrt(pow(width + 0.5, 2) - i * i));
|
|
} else if (pattern == 2) {
|
|
offset = width;
|
|
}
|
|
|
|
for (float j = -ceil(offset); j <= ceil(offset); j++) {
|
|
vec2 xy = uv + texture_pixel_size * vec2(i, j);
|
|
|
|
if ((xy != clamp(xy, vec2(0.0), vec2(1.0)) || texture(tex, xy).a == 0.0) == inside) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void fragment() {
|
|
vec4 original_color = texture(TEXTURE, UV);
|
|
vec4 selection_color = texture(selection, UV);
|
|
vec4 output = texture(TEXTURE, UV);
|
|
|
|
if ((output.a > 0.0) == inside && has_contrary_neighbour(UV, TEXTURE_PIXEL_SIZE, TEXTURE)) {
|
|
output.rgb = inside ? mix(output.rgb, color.rgb, color.a) : color.rgb;
|
|
output.a += (1.0 - output.a) * color.a;
|
|
}
|
|
|
|
COLOR = mix(original_color, output, selection_color.a);
|
|
}
|