blob: a8c9b7183eb33bfb2dddc76a824770f852636632 (
plain)
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
72
73
74
75
76
77
78
79
80
|
/* To be compiled with common_subdiv_lib.glsl */
layout(std430, binding = 0) readonly buffer inputVerts
{
PosNorLoop pos_nor[];
};
layout(std430, binding = 1) readonly buffer inputUVs
{
vec2 uvs[];
};
/* Mirror of #UVStretchAngle in the C++ code, but using floats until proper data compression
* is implemented for all subdivision data. */
struct UVStretchAngle {
float angle;
float uv_angle0;
float uv_angle1;
};
layout(std430, binding = 2) writeonly buffer outputStretchAngles
{
UVStretchAngle uv_stretches[];
};
#define M_PI 3.1415926535897932
#define M_1_PI 0.31830988618379067154
/* Adapted from BLI_math_vector.h */
float angle_normalized_v3v3(vec3 v1, vec3 v2)
{
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
bool q = (dot(v1, v2) >= 0.0);
vec3 v = (q) ? (v1 - v2) : (v1 + v2);
float a = 2.0 * asin(length(v) / 2.0);
return (q) ? a : M_PI - a;
}
void main()
{
/* We execute for each quad. */
uint quad_index = get_global_invocation_index();
if (quad_index >= total_dispatch_size) {
return;
}
uint start_loop_index = quad_index * 4;
for (uint i = 0; i < 4; i++) {
uint cur_loop_index = start_loop_index + i;
uint next_loop_index = start_loop_index + (i + 1) % 4;
uint prev_loop_index = start_loop_index + (i + 3) % 4;
/* Compute 2d edge vectors from UVs. */
vec2 cur_uv = uvs[src_offset + cur_loop_index];
vec2 next_uv = uvs[src_offset + next_loop_index];
vec2 prev_uv = uvs[src_offset + prev_loop_index];
vec2 norm_uv_edge0 = normalize(prev_uv - cur_uv);
vec2 norm_uv_edge1 = normalize(cur_uv - next_uv);
/* Compute 3d edge vectors from positions. */
vec3 cur_pos = get_vertex_pos(pos_nor[cur_loop_index]);
vec3 next_pos = get_vertex_pos(pos_nor[next_loop_index]);
vec3 prev_pos = get_vertex_pos(pos_nor[prev_loop_index]);
vec3 norm_pos_edge0 = normalize(prev_pos - cur_pos);
vec3 norm_pos_edge1 = normalize(cur_pos - next_pos);
/* Compute stretches, this logic is adapted from #edituv_get_edituv_stretch_angle.
* Keep in sync! */
UVStretchAngle stretch;
stretch.uv_angle0 = atan(norm_uv_edge0.y, norm_uv_edge0.x) * M_1_PI;
stretch.uv_angle1 = atan(norm_uv_edge1.y, norm_uv_edge1.x) * M_1_PI;
stretch.angle = angle_normalized_v3v3(norm_pos_edge0, norm_pos_edge1) * M_1_PI;
uv_stretches[cur_loop_index] = stretch;
}
}
|