Edit Mesh: Simplify the overlay shader.
[blender.git] / source / blender / draw / modes / shaders / edit_mesh_overlay_frag.glsl
1
2 /* Solid Wirefram implementation
3  * Mike Erwin, ClĂ©ment Foucault */
4
5 /* This shader follows the principles of
6  * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
7
8 /* This is not perfect. Only a subset of intel gpus are affected.
9  * This fix have some performance impact.
10  * TODO Refine the range to only affect GPUs. */
11
12 uniform float faceAlphaMod;
13
14 flat in vec3 edgesCrease;
15 flat in vec3 edgesBweight;
16 flat in vec4 faceColor;
17 flat in ivec3 flag;
18 #ifdef VERTEX_SELECTION
19 in vec3 vertexColor;
20 #endif
21 #ifdef VERTEX_FACING
22 in float facing;
23 #endif
24
25 flat in vec2 ssPos[3];
26
27 out vec4 FragColor;
28
29 /* Vertex flag is shifted and combined with the edge flag */
30 #define FACE_ACTIVE     (1 << (2 + 8))
31
32 #define LARGE_EDGE_SIZE 2.0
33
34 /* Style Parameters in pixel */
35
36 void distToEdgeAndPoint(vec2 dir, vec2 ori, out float edge, out float point)
37 {
38         dir = normalize(dir.xy);
39         vec2 of = gl_FragCoord.xy - ori;
40         point = dot(of, of);
41         float dof = dot(dir, of);
42         edge = sqrt(abs(point - dof * dof));
43         point = sqrt(point);
44 }
45
46 void colorDist(vec4 color, float dist)
47 {
48         FragColor = (dist < 0) ? color : FragColor;
49 }
50
51 #ifdef ANTI_ALIASING
52 void colorDistEdge(vec4 color, float dist)
53 {
54         FragColor.rgb *= FragColor.a;
55         FragColor = mix(color, FragColor, clamp(dist, 0.0, 1.0));
56         FragColor.rgb /= max(1e-8, FragColor.a);
57 }
58 #else
59 #define colorDistEdge colorDist
60 #endif
61
62 void main()
63 {
64         vec3 e, p;
65
66         /* Step 1 : Computing Distances */
67         distToEdgeAndPoint((ssPos[1] - ssPos[0]) + 1e-8, ssPos[0], e.z, p.x);
68         distToEdgeAndPoint((ssPos[2] - ssPos[1]) + 1e-8, ssPos[1], e.x, p.y);
69         distToEdgeAndPoint((ssPos[0] - ssPos[2]) + 1e-8, ssPos[2], e.y, p.z);
70
71         /* Step 2 : coloring (order dependant) */
72
73         /* Face */
74         FragColor = faceColor;
75         FragColor.a *= faceAlphaMod;
76
77         /* Edges */
78         for (int v = 0; v < 3; ++v) {
79                 if ((flag[v] & EDGE_EXISTS) != 0) {
80                         /* Outer large edge */
81                         float largeEdge = e[v] - sizeEdge * LARGE_EDGE_SIZE;
82
83                         vec4 large_edge_color = EDIT_MESH_edge_color_outer(flag[v], (flag[0]& FACE_ACTIVE) != 0, edgesCrease[v], edgesBweight[v]);
84
85                         if (large_edge_color.a != 0.0) {
86                                 colorDistEdge(large_edge_color, largeEdge);
87                         }
88
89                         /* Inner thin edge */
90                         float innerEdge = e[v] - sizeEdge;
91 #ifdef ANTI_ALIASING
92                         innerEdge += 0.4;
93 #endif
94
95 #ifdef VERTEX_SELECTION
96                         colorDistEdge(vec4(vertexColor, 1.0), innerEdge);
97 #else
98                         vec4 inner_edge_color = EDIT_MESH_edge_color_inner(flag[v], (flag[0]& FACE_ACTIVE) != 0);
99                         colorDistEdge(inner_edge_color, innerEdge);
100 #endif
101                 }
102         }
103
104         /* Points */
105 #ifdef VERTEX_SELECTION
106         for (int v = 0; v < 3; ++v) {
107                 float size = p[v] - sizeVertex;
108
109                 vec4 point_color = colorVertex;
110                 point_color = ((flag[v] & EDGE_VERTEX_SELECTED) != 0) ? colorVertexSelect : point_color;
111                 point_color = ((flag[v] & EDGE_VERTEX_ACTIVE) != 0) ? vec4(colorEditMeshActive.xyz, 1.0) : point_color;
112
113                 colorDist(point_color, size);
114         }
115 #endif
116
117 #ifdef VERTEX_FACING
118         FragColor.a *= 1.0 - abs(facing) * 0.4;
119 #endif
120
121         /* don't write depth if not opaque */
122         if (FragColor.a == 0.0) discard;
123 }