Edit Mesh Overlay Geometry Shader: Ignore correction geometry for loops that are...
[blender.git] / source / blender / draw / modes / shaders / edit_mesh_overlay_geom_tri.glsl
1
2 /* Solid Wirefram implementation
3  * Mike Erwin, ClĂ©ment Foucault */
4
5 layout(triangles) in;
6
7 /* To fix the edge artifacts, we render
8  * an outline strip around the screenspace
9  * triangle. Order is important.
10  * TODO diagram
11  */
12 layout(triangle_strip, max_vertices=12) out;
13
14 uniform mat4 ProjectionMatrix;
15 uniform vec2 viewportSize;
16
17 in vec4 pPos[];
18 in ivec4 vData[];
19 #ifdef VERTEX_FACING
20 in float vFacing[];
21 #endif
22
23 /* these are the same for all vertices
24  * and does not need interpolation */
25 flat out vec3 edgesCrease;
26 flat out vec3 edgesBweight;
27 flat out vec4 faceColor;
28 flat out ivec3 flag;
29
30 flat out vec2 ssPos[3];
31 #ifdef VERTEX_SELECTION
32 out vec3 vertexColor;
33 #endif
34 #ifdef VERTEX_FACING
35 out float facing;
36 #endif
37
38 #ifdef ANTI_ALIASING
39 #define Z_OFFSET 0.008
40 #else
41 #define Z_OFFSET 0.0
42 #endif
43
44 /* Some bugged AMD drivers need these global variables. See T55961 */
45 #ifdef VERTEX_SELECTION
46 vec3 vertex_color[3];
47 #endif
48
49 #ifdef VERTEX_FACING
50 float v_facing[3];
51 #endif
52
53 /* project to screen space */
54 vec2 proj(vec4 pos)
55 {
56         return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
57 }
58
59 void doVertex(int v)
60 {
61 #ifdef VERTEX_SELECTION
62         vertexColor = vertex_color[v];
63 #endif
64
65 #ifdef VERTEX_FACING
66         facing = v_facing[v];
67 #endif
68         gl_Position = pPos[v];
69
70         EmitVertex();
71 }
72
73 void doVertexOfs(int v, vec2 fixvec)
74 {
75 #ifdef VERTEX_SELECTION
76         vertexColor = vertex_color[v];
77 #endif
78
79 #ifdef VERTEX_FACING
80         facing = v_facing[v];
81 #endif
82         gl_Position = pPos[v] + vec4(fixvec, Z_OFFSET, 0.0);
83
84         EmitVertex();
85 }
86
87 void mask_edge_flag(int v, ivec3 eflag)
88 {
89         int vbe = (v + 2) % 3;
90         int vaf = (v + 1) % 3;
91
92         /* Only shade the edge that we are currently drawing.
93          * (fix corner bleeding) */
94         flag[vbe] |= (EDGE_EXISTS & eflag[vbe]);
95         flag[vaf] &= ~EDGE_EXISTS;
96         flag[v]   &= ~EDGE_EXISTS;
97 }
98
99 vec2 compute_fixvec(int i)
100 {
101         int i1 = (i + 1) % 3;
102         int i2 = (i + 2) % 3;
103         /* This fix the case when 2 vertices are perfectly aligned
104          * and corner vectors have nowhere to go.
105          * ie: length(cornervec[i]) == 0 */
106         const float epsilon = 1e-2; /* in pixel so not that much */
107         const vec2 bias[3] = vec2[3](
108                 vec2( epsilon,  epsilon),
109                 vec2(-epsilon,  epsilon),
110                 vec2(     0.0, -epsilon)
111         );
112         vec2 v1 = ssPos[i] + bias[i];
113         vec2 v2 = ssPos[i1] + bias[i1];
114         vec2 v3 = ssPos[i2] + bias[i2];
115         /* Edge normalized vector */
116         vec2 dir = normalize(v2 - v1);
117         vec2 dir2 = normalize(v3 - v1);
118         /* perpendicular to dir */
119         vec2 perp = vec2(-dir.y, dir.x);
120         /* Backface case */
121         if (dot(perp, dir2) > 0.0) {
122                 perp = -perp;
123         }
124         /* Make it view independent */
125         return perp * sizeEdgeFix / viewportSize;;
126 }
127
128 void main()
129 {
130         /* Edge */
131         ivec3 eflag;
132         for (int v = 0; v < 3; ++v) {
133                 flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8);
134                 edgesCrease[v] = vData[v].z / 255.0;
135                 edgesBweight[v] = vData[v].w / 255.0;
136         }
137
138         /* Face */
139         vec4 fcol;
140         if ((vData[0].x & FACE_ACTIVE) != 0)
141                 fcol = colorFaceSelect;
142         else if ((vData[0].x & FACE_SELECTED) != 0)
143                 fcol = colorFaceSelect;
144         else if ((vData[0].x & FACE_FREESTYLE) != 0)
145                 fcol = colorFaceFreestyle;
146         else
147                 fcol = colorFace;
148
149         /* Vertex */
150         ssPos[0] = proj(pPos[0]);
151         ssPos[1] = proj(pPos[1]);
152         ssPos[2] = proj(pPos[2]);
153
154         vec2 fixvec[3];
155         vec2 fixvecaf[3];
156
157         for (int i = 0; i < 3; ++i) {
158                 fixvec[i] = fixvecaf[i] = compute_fixvec(i);
159                 /* Perspective */
160                 if (ProjectionMatrix[3][3] == 0.0) {
161                         fixvec[i] *= pPos[i].w;
162                         fixvecaf[i] *= pPos[(i + 1) % 3].w;
163                 }
164         }
165
166 #ifdef VERTEX_SELECTION
167         vertex_color[0] = EDIT_MESH_vertex_color(vData[0].x).rgb;
168         vertex_color[1] = EDIT_MESH_vertex_color(vData[1].x).rgb;
169         vertex_color[2] = EDIT_MESH_vertex_color(vData[2].x).rgb;
170 #endif
171
172 #ifdef VERTEX_FACING
173         /* Weird but some buggy AMD drivers need this. */
174         v_facing[0] = vFacing[0];
175         v_facing[1] = vFacing[1];
176         v_facing[2] = vFacing[2];
177 #endif
178
179         /* Remember that we are assuming the last vertex
180          * of a triangle is the provoking vertex (decide what flat attribs are). */
181
182         if ((eflag[2] & EDGE_EXISTS) != 0) {
183                 /* Do 0 -> 1 edge strip */
184                 faceColor = vec4(fcol.rgb, 0.0);
185                 mask_edge_flag(0, eflag);
186                 doVertexOfs(0, fixvec[0]);
187                 doVertexOfs(1, fixvecaf[0]);
188         }
189         doVertex(0);
190         doVertex(1);
191
192         /* Do face triangle */
193         faceColor = fcol;
194         flag = eflag;
195         doVertex(2);
196         faceColor.a = 0.0; /* to not let face color bleed */
197
198         if ((eflag[0] & EDGE_EXISTS) != 0) {
199                 /* Do 1 -> 2 edge strip */
200                 mask_edge_flag(1, eflag);
201                 doVertexOfs(1, fixvec[1]);
202                 doVertexOfs(2, fixvecaf[1]);
203         }
204         EndPrimitive();
205
206         if ((eflag[1] & EDGE_EXISTS) != 0) {
207                 /* Do 2 -> 0 edge strip */
208                 mask_edge_flag(2, eflag);
209                 doVertex(2);
210                 doVertex(0);
211                 doVertexOfs(2, fixvec[2]);
212                 doVertexOfs(0, fixvecaf[2]);
213                 EndPrimitive();
214         }
215 }