9e5a3d76c0d2376cd49ff94706af7f5d7866c42b
[blender.git] / source / blender / draw / modes / shaders / armature_stick_vert.glsl
1
2 uniform mat4 ProjectionMatrix;
3 uniform mat4 ViewProjectionMatrix;
4 uniform mat4 ModelMatrix;
5 uniform mat4 ViewMatrix;
6 uniform vec2 viewportSize;
7
8 /* ---- Instantiated Attrs ---- */
9 in vec2 pos; /* bone aligned screen space */
10 in uint flag;
11
12 #define COL_WIRE 1u /* (1 << 0) */
13 #define COL_HEAD 2u /* (1 << 1) */
14 #define COL_TAIL 4u /* (1 << 2) */
15 #define COL_BONE 8u /* (1 << 3) */
16
17 #define POS_HEAD 16u                /* (1 << 4) */
18 #define POS_TAIL 32u /* (1 << 5) */ /* UNUSED */
19 #define POS_BONE 64u                /* (1 << 6) */
20
21 /* ---- Per instance Attrs ---- */
22 in vec3 boneStart;
23 in vec3 boneEnd;
24 in vec4 wireColor; /* alpha encode if we do wire. If 0.0 we dont. */
25 in vec4 boneColor; /* alpha encode if we do bone. If 0.0 we dont. */
26 in vec4 headColor; /* alpha encode if we do head. If 0.0 we dont. */
27 in vec4 tailColor; /* alpha encode if we do tail. If 0.0 we dont. */
28
29 #define do_wire (wireColor.a > 0.0)
30 #define is_head bool(flag & POS_HEAD)
31 #define is_bone bool(flag & POS_BONE)
32
33 noperspective out float colorFac;
34 flat out vec4 finalWireColor;
35 flat out vec4 finalInnerColor;
36
37 uniform float stickSize = 5.0; /* might be dependent on DPI setting in the future. */
38
39 /* project to screen space */
40 vec2 proj(vec4 pos)
41 {
42   return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
43 }
44
45 void main()
46 {
47   finalInnerColor = ((flag & COL_HEAD) != 0u) ? headColor : tailColor;
48   finalInnerColor = ((flag & COL_BONE) != 0u) ? boneColor : finalInnerColor;
49   finalWireColor = (do_wire) ? wireColor : finalInnerColor;
50   /* Make the color */
51   colorFac = ((flag & COL_WIRE) == 0u) ? ((flag & COL_BONE) != 0u) ? 1.0 : 2.0 : 0.0;
52
53   vec4 boneStart_4d = vec4(boneStart, 1.0);
54   vec4 boneEnd_4d = vec4(boneEnd, 1.0);
55   vec4 v0 = ViewMatrix * boneStart_4d;
56   vec4 v1 = ViewMatrix * boneEnd_4d;
57
58   /* Clip the bone to the camera origin plane (not the clip plane)
59    * to avoid glitches if one end is behind the camera origin (in persp). */
60   float clip_dist = (ProjectionMatrix[3][3] == 0.0) ?
61                         -1e-7 :
62                         1e20; /* hardcoded, -1e-8 is giving gliches. */
63   vec3 bvec = v1.xyz - v0.xyz;
64   vec3 clip_pt = v0.xyz + bvec * ((v0.z - clip_dist) / -bvec.z);
65   if (v0.z > clip_dist) {
66     v0.xyz = clip_pt;
67   }
68   else if (v1.z > clip_dist) {
69     v1.xyz = clip_pt;
70   }
71
72   vec4 p0 = ProjectionMatrix * v0;
73   vec4 p1 = ProjectionMatrix * v1;
74
75   float h = (is_head) ? p0.w : p1.w;
76
77   vec2 x_screen_vec = normalize(proj(p1) - proj(p0) + 1e-8);
78   vec2 y_screen_vec = vec2(x_screen_vec.y, -x_screen_vec.x);
79
80   /* 2D screen aligned pos at the point */
81   vec2 vpos = pos.x * x_screen_vec + pos.y * y_screen_vec;
82   vpos *= (ProjectionMatrix[3][3] == 0.0) ? h : 1.0;
83   vpos *= (do_wire) ? 1.0 : 0.5;
84
85   if (finalInnerColor.a > 0.0) {
86     gl_Position = (is_head) ? p0 : p1;
87     gl_Position.xy += stickSize * (vpos / viewportSize);
88     gl_Position.z += (is_bone) ? 0.0 : 1e-6; /* Avoid Z fighting of head/tails. */
89
90 #ifdef USE_WORLD_CLIP_PLANES
91     world_clip_planes_calc_clip_distance(
92         (ModelMatrix * (is_head ? boneStart_4d : boneEnd_4d)).xyz);
93 #endif
94   }
95   else {
96     gl_Position = vec4(0.0);
97   }
98 }