diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders/canvas_sdf.glsl')
-rw-r--r-- | servers/rendering/renderer_rd/shaders/canvas_sdf.glsl | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl index 65a554e839..2bdfbabfcf 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl @@ -7,7 +7,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(r8, set = 0, binding = 1) uniform restrict readonly image2D src_pixels; -layout(r16, set = 0, binding = 2) uniform restrict writeonly image2D dst_sdf; +layout(r16_snorm, set = 0, binding = 2) uniform restrict writeonly image2D dst_sdf; layout(rg16i, set = 0, binding = 3) uniform restrict readonly iimage2D src_process; layout(rg16i, set = 0, binding = 4) uniform restrict writeonly iimage2D dst_process; @@ -32,7 +32,7 @@ void main() { #ifdef MODE_LOAD bool solid = imageLoad(src_pixels, pos).r > 0.5; - imageStore(dst_process, pos, solid ? ivec4(pos, 0, 0) : ivec4(ivec2(32767), 0, 0)); + imageStore(dst_process, pos, solid ? ivec4(ivec2(-32767), 0, 0) : ivec4(ivec2(32767), 0, 0)); #endif #ifdef MODE_LOAD_SHRINK @@ -43,6 +43,8 @@ void main() { ivec2 rel = ivec2(32767); float d = 1e20; + int found = 0; + int solid_found = 0; for (int i = 0; i < s; i++) { for (int j = 0; j < s; j++) { ivec2 src_pos = base + ivec2(i, j); @@ -56,10 +58,17 @@ void main() { d = dist; rel = src_pos; } + solid_found++; } + found++; } } + if (solid_found == found) { + //mark solid only if all are solid + rel = ivec2(-32767); + } + imageStore(dst_process, pos, ivec4(rel, 0, 0)); #endif @@ -70,6 +79,12 @@ void main() { ivec2 rel = imageLoad(src_process, pos).xy; + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + if (center != rel) { //only process if it does not point to itself const int ofs_table_size = 8; @@ -92,6 +107,15 @@ void main() { continue; } ivec2 src_rel = imageLoad(src_process, src_pos).xy; + bool src_solid = src_rel.x < 0; + if (src_solid) { + src_rel = -src_rel - ivec2(1); + } + + if (src_solid != solid) { + src_rel = ivec2(src_pos << params.shift); //point to itself if of different type + } + float src_dist = length(vec2(src_rel - center)); if (src_dist < dist) { dist = src_dist; @@ -100,18 +124,31 @@ void main() { } } + if (solid) { + rel = -rel - ivec2(1); + } + imageStore(dst_process, pos, ivec4(rel, 0, 0)); #endif #ifdef MODE_STORE ivec2 rel = imageLoad(src_process, pos).xy; + + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + float d = length(vec2(rel - pos)); - if (d > 0.01) { - d += 1.0; //make it signed + + if (solid) { + d = -d; } + d /= SDF_MAX_LENGTH; - d = clamp(d, 0.0, 1.0); + d = clamp(d, -1.0, 1.0); imageStore(dst_sdf, pos, vec4(d)); #endif @@ -122,13 +159,20 @@ void main() { ivec2 center = base + ivec2(params.shift); ivec2 rel = imageLoad(src_process, pos).xy; + + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + float d = length(vec2(rel - center)); - if (d > 0.01) { - d += 1.0; //make it signed + if (solid) { + d = -d; } d /= SDF_MAX_LENGTH; - d = clamp(d, 0.0, 1.0); + d = clamp(d, -1.0, 1.0); imageStore(dst_sdf, pos, vec4(d)); #endif |