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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl')
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl74
1 files changed, 33 insertions, 41 deletions
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
index dc7ed5e202a..11924b19cf8 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
@@ -1,11 +1,9 @@
-/* TODO: See perf with multiple invocations. */
-layout(triangles_adjacency) in;
-layout(triangle_strip, max_vertices = 16) out;
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = 6) out;
in vec4 pPos[];
-in float vZ[];
-in float vFacing[];
+in vec3 vPos[];
in vec2 ssPos[];
in vec2 ssNor[];
in vec4 vColSize[];
@@ -22,21 +20,18 @@ vec2 compute_dir(vec2 v0, vec2 v1)
return dir;
}
-void emit_edge(const ivec3 edges, vec2 thick, bool is_persp)
+void emit_edge(vec2 edge_dir, vec2 hidden_dir, vec2 thick, bool is_persp)
{
- vec2 edge_dir = compute_dir(ssPos[edges.x], ssPos[edges.y]);
- vec2 hidden_dir = normalize(ssPos[edges.z] - ssPos[edges.x]);
-
float fac = dot(-hidden_dir, edge_dir);
- vec2 t = thick * (is_persp ? vZ[edges.x] : 1.0);
- gl_Position = pPos[edges.x];
+ vec2 t = thick * (is_persp ? abs(vPos[1].z) : 1.0);
+ gl_Position = pPos[1];
EmitVertex();
gl_Position.xy += t * edge_dir * sign(fac);
EmitVertex();
- t = thick * (is_persp ? vZ[edges.y] : 1.0);
- gl_Position = pPos[edges.y];
+ t = thick * (is_persp ? abs(vPos[2].z) : 1.0);
+ gl_Position = pPos[2];
EmitVertex();
gl_Position.xy += t * edge_dir * sign(fac);
EmitVertex();
@@ -45,7 +40,7 @@ void emit_edge(const ivec3 edges, vec2 thick, bool is_persp)
void emit_corner(const int e, vec2 thick, bool is_persp)
{
vec2 corner_dir = ssNor[e];
- vec2 t = thick * (is_persp ? vZ[e] : 1.0);
+ vec2 t = thick * (is_persp ? abs(vPos[e].z) : 1.0);
gl_Position = pPos[e] + vec4(t * corner_dir, 0.0, 0.0);
EmitVertex();
@@ -55,41 +50,38 @@ void main(void)
{
finalColor = vec4(vColSize[0].rgb, 1.0);
- vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
- const ivec3 edges = ivec3(0, 2, 4);
- vec4 facing = vec4(vFacing[1], vFacing[3], vFacing[5], vFacing[0]);
- bvec4 do_edge = greaterThanEqual(facing, vec4(0.0));
+ vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+ vec3 v10 = vPos[0] - vPos[1];
+ vec3 v12 = vPos[2] - vPos[1];
+ vec3 v13 = vPos[3] - vPos[1];
- /* Only generate outlines from backfaces. */
- if (do_edge.w)
- return;
+ vec3 n0 = cross(v12, v10);
+ vec3 n3 = cross(v13, v12);
- if (do_edge.x) {
- emit_corner(edges.x, thick, is_persp);
- emit_edge(edges.xyz, thick, is_persp);
- }
+ float fac0 = dot(view_vec, n0);
+ float fac3 = dot(view_vec, n3);
- if (any(do_edge.xy)) {
- emit_corner(edges.y, thick, is_persp);
- }
+ /* If both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac0) == sign(fac3))
+ return;
- if (do_edge.y) {
- emit_edge(edges.yzx, thick, is_persp);
- }
- else {
- EndPrimitive();
- }
+ /* Don't outline if concave edge. */
+ if (dot(n0, v13) > 0.0)
+ return;
- if (any(do_edge.yz)) {
- emit_corner(edges.z, thick, is_persp);
- }
+ vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
+ vec2 edge_dir = compute_dir(ssPos[1], ssPos[2]);
- if (do_edge.z) {
- emit_edge(edges.zxy, thick, is_persp);
- emit_corner(edges.x, thick, is_persp);
- }
+ /* Take the farthest point to compute edge direction
+ * (avoid problems with point behind near plane). */
+ vec2 hidden_point = (vPos[0].z < vPos[3].z) ? ssPos[0] : ssPos[3];
+ vec2 hidden_dir = normalize(hidden_point - ssPos[1]);
+ emit_corner(1, thick, is_persp);
+ emit_edge(edge_dir, hidden_dir, thick, is_persp);
+ emit_corner(2, thick, is_persp);
EndPrimitive();
}