Merge branch 'master' into blender2.8
[blender.git] / source / blender / gpu / shaders / gpu_shader_edges_overlay_geom.glsl
1 layout(triangles) in;
2 layout(triangle_strip, max_vertices=3) out;
3
4 uniform float outlineWidth = 1.0;
5 uniform vec2 viewportSize;
6
7 in vec4 pos_xformed[];
8 in float widthModulator[];
9
10 noperspective out vec3 distanceToOutline;
11
12 // project to screen space
13 vec2 proj(int axis) {
14         vec4 pos = pos_xformed[axis];
15         return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
16 }
17
18 float dist(vec2 pos[3], int v) {
19         // current vertex position
20         vec2 vpos = pos[v];
21         // endpoints of opposite edge
22         vec2 e1 = pos[(v + 1) % 3];
23         vec2 e2 = pos[(v + 2) % 3];
24
25         float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify
26         return abs_det / distance(e2, e1);
27 }
28
29 vec3 distance[3];
30
31 void clearEdge(int v) {
32         float distant = 10 * outlineWidth;
33         for (int i = 0; i < 3; ++i)
34                 distance[i][v] += distant;
35 }
36
37 void modulateEdge(int v) {
38         float offset = min(widthModulator[v],1) * outlineWidth;
39         for (int i = 0; i < 3; ++i)
40                 distance[i][v] -= offset;
41 }
42
43 void main() {
44         vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2));
45
46         for (int v = 0; v < 3; ++v)
47                 distance[v] = vec3(0);
48
49         for (int v = 0; v < 3; ++v) {
50                 if (widthModulator[v] > 0) {
51                         distance[v][v] = dist(pos, v);
52                         modulateEdge(v);
53                 }
54         }
55
56         for (int v = 0; v < 3; ++v)
57                 if (widthModulator[v] <= 0)
58                         clearEdge(v);
59
60         for (int v = 0; v < 3; ++v) {
61                 gl_Position = pos_xformed[v];
62                 distanceToOutline = distance[v];
63                 EmitVertex();
64         }
65
66         EndPrimitive();
67 }