#version 430 core layout (local_size_x = 1, local_size_y = 1) in; struct Vertex { vec3 pos; vec3 norm; vec2 uv; }; layout(std430, binding=0) buffer Vertices { Vertex vb[]; }; layout(std430, binding=1) buffer Index { unsigned int ib[]; }; layout(std430, binding=2) buffer Offset { unsigned int offset_in; unsigned int offset_search; }; layout(std430, binding=3) buffer Output { int neighbors[][3]; }; int shared_edge(vec3 u, vec3 v, vec3 w, vec3 a, vec3 b, vec3 c) { if (u == a && v == c) { return 0; } else if (u == a && w == b) { return 2; } else if (v == a && w == c) { return 1; } return -1; } void main() { if (3 * (gl_GlobalInvocationID.x + offset_in) + 2 >= ib.length()) { return; } int found = 0; found += (neighbors[gl_GlobalInvocationID.x + offset_in][0] > 0) ? 1 : 0; found += (neighbors[gl_GlobalInvocationID.x + offset_in][1] > 0) ? 1 : 0; found += (neighbors[gl_GlobalInvocationID.x + offset_in][2] > 0) ? 1 : 0; vec3 u = vb[ib[3 * (gl_GlobalInvocationID.x + offset_in) + 0]].pos; vec3 v = vb[ib[3 * (gl_GlobalInvocationID.x + offset_in) + 1]].pos; vec3 w = vb[ib[3 * (gl_GlobalInvocationID.x + offset_in) + 2]].pos; for (int i = 0; found < 3 && i < 128 && (3 * gl_GlobalInvocationID.y + offset_search + gl_NumWorkGroups.y * i) + 2 < ib.length(); i++) { vec3 a = vb[ib[3 * (gl_GlobalInvocationID.y + offset_search + gl_NumWorkGroups.y * i) + 0]].pos; vec3 b = vb[ib[3 * (gl_GlobalInvocationID.y + offset_search + gl_NumWorkGroups.y * i) + 1]].pos; vec3 c = vb[ib[3 * (gl_GlobalInvocationID.y + offset_search + gl_NumWorkGroups.y * i) + 2]].pos; int edge; edge = shared_edge(u, v, w, a, b, c); if (edge < 0) { edge = shared_edge(u, v, w, b, c, a); } if (edge < 0) { edge = shared_edge(u, v, w, c, a, b); } if (edge >= 0) { neighbors[gl_GlobalInvocationID.x + offset_in][edge] = int(gl_GlobalInvocationID.y + offset_search + gl_NumWorkGroups.y * i); found++; } } }