123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #[compute]
- #version 450
- #VERSION_DEFINES
- 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_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;
- layout(push_constant, std430) uniform Params {
- ivec2 size;
- int stride;
- int shift;
- ivec2 base_size;
- uvec2 pad;
- }
- params;
- #define SDF_MAX_LENGTH 16384.0
- void main() {
- ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(pos, params.size))) { //too large, do nothing
- return;
- }
- #ifdef MODE_LOAD
- bool solid = imageLoad(src_pixels, pos).r > 0.5;
- imageStore(dst_process, pos, solid ? ivec4(ivec2(-32767), 0, 0) : ivec4(ivec2(32767), 0, 0));
- #endif
- #ifdef MODE_LOAD_SHRINK
- int s = 1 << params.shift;
- ivec2 base = pos << params.shift;
- ivec2 center = base + ivec2(params.shift);
- 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);
- if (any(greaterThanEqual(src_pos, params.base_size))) {
- continue;
- }
- bool solid = imageLoad(src_pixels, src_pos).r > 0.5;
- if (solid) {
- float dist = length(vec2(src_pos - center));
- if (dist < d) {
- 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
- #ifdef MODE_PROCESS
- ivec2 base = pos << params.shift;
- ivec2 center = base + ivec2(params.shift);
- 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;
- const ivec2 ofs_table[ofs_table_size] = ivec2[](
- ivec2(-1, -1),
- ivec2(0, -1),
- ivec2(+1, -1),
- ivec2(-1, 0),
- ivec2(+1, 0),
- ivec2(-1, +1),
- ivec2(0, +1),
- ivec2(+1, +1));
- float dist = length(vec2(rel - center));
- for (int i = 0; i < ofs_table_size; i++) {
- ivec2 src_pos = pos + ofs_table[i] * params.stride;
- if (any(lessThan(src_pos, ivec2(0))) || any(greaterThanEqual(src_pos, params.size))) {
- 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;
- rel = src_rel;
- }
- }
- }
- 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 (solid) {
- d = -d;
- }
- d /= SDF_MAX_LENGTH;
- d = clamp(d, -1.0, 1.0);
- imageStore(dst_sdf, pos, vec4(d));
- #endif
- #ifdef MODE_STORE_SHRINK
- ivec2 base = pos << params.shift;
- 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 (solid) {
- d = -d;
- }
- d /= SDF_MAX_LENGTH;
- d = clamp(d, -1.0, 1.0);
- imageStore(dst_sdf, pos, vec4(d));
- #endif
- }
|