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:
authorClément Foucault <foucault.clem@gmail.com>2018-04-22 23:49:36 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-02 21:49:38 +0300
commite493a1a1aedcd6bc00f0f016aa6ef707742e3825 (patch)
treee479cb1f54c0029e92446dc6b0cfc263fe1bfb56 /source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
parent77b481fd5ae2e8b503aed714ae3335ba637c84b6 (diff)
DRW: Armature: New bone outline shader.
This fix the issue with the zfighting we were getting at bones edges. Moreover, this enables us to render arbitrarly large outline with varying thickness.
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.glsl95
1 files changed, 95 insertions, 0 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
new file mode 100644
index 00000000000..3d3cb692634
--- /dev/null
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
@@ -0,0 +1,95 @@
+
+/* TODO: See perf with multiple invocations. */
+layout(triangles_adjacency) in;
+layout(triangle_strip, max_vertices = 16) out;
+
+in vec4 pPos[];
+in float vZ[];
+in float vFacing[];
+in vec2 ssPos[];
+in vec2 ssNor[];
+in vec4 vCol[];
+
+flat out vec4 finalColor;
+uniform mat4 ProjectionMatrix;
+uniform vec2 viewportSize;
+uniform float lineThickness = 3.0;
+
+vec2 compute_dir(vec2 v0, vec2 v1)
+{
+ vec2 dir = normalize(v1 - v0);
+ dir = vec2(-dir.y, dir.x);
+ return dir;
+}
+
+void emit_edge(const ivec3 edges, 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];
+ EmitVertex();
+ gl_Position.xy += t * edge_dir * sign(fac);
+ EmitVertex();
+
+ t = thick * (is_persp ? vZ[edges.y] : 1.0);
+ gl_Position = pPos[edges.y];
+ EmitVertex();
+ gl_Position.xy += t * edge_dir * sign(fac);
+ EmitVertex();
+}
+
+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);
+
+ gl_Position = pPos[e] + vec4(t * corner_dir, 0.0, 0.0);
+ EmitVertex();
+}
+
+void main(void)
+{
+ finalColor = vCol[0];
+
+ vec2 thick = 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));
+
+ /* Only generate outlines from backfaces. */
+ if (do_edge.w)
+ return;
+
+ if (do_edge.x) {
+ emit_corner(edges.x, thick, is_persp);
+ emit_edge(edges.xyz, thick, is_persp);
+ }
+
+ if (any(do_edge.xy)) {
+ emit_corner(edges.y, thick, is_persp);
+ }
+
+ if (do_edge.y) {
+ emit_edge(edges.yzx, thick, is_persp);
+ }
+ else {
+ EndPrimitive();
+ }
+
+ if (any(do_edge.yz)) {
+ emit_corner(edges.z, thick, is_persp);
+ }
+
+ if (do_edge.z) {
+ emit_edge(edges.zxy, thick, is_persp);
+ emit_corner(edges.x, thick, is_persp);
+ }
+
+ EndPrimitive();
+}