1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#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++;
}
}
}