Welcome to mirror list, hosted at ThFree Co, Russian Federation.

common_subdiv_vbo_edituv_strech_angle_comp.glsl « shaders « intern « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
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;
  }
}