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-05-20 23:48:35 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-26 23:28:52 +0300
commit6b38fa8caba68ed9e694b995e71e190d9d07df25 (patch)
tree5217a41917546c96c3c4db8017de1b93ade8fa0f /source/blender/draw/modes/shaders
parent581b021a1f1e987df66a659683cfc057f51dc204 (diff)
Armature: Modify Shape outline shader to use Line adjacency instead of tri.
This is much faster and simpler. This is also to make it compatible with custom bone shape in the future.
Diffstat (limited to 'source/blender/draw/modes/shaders')
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl71
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl17
2 files changed, 31 insertions, 57 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..4fb6fe5a245 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,31 @@ 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));
-
- /* Only generate outlines from backfaces. */
- if (do_edge.w)
- return;
+ 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];
- if (do_edge.x) {
- emit_corner(edges.x, thick, is_persp);
- emit_edge(edges.xyz, thick, is_persp);
- }
+ float fac1 = dot(view_vec, cross(v10, v12));
+ float fac2 = dot(view_vec, cross(v12, v13));
- 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 both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac1) == sign(fac2))
+ 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();
}
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
index 0d09114579c..3e7a185bb62 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
@@ -15,8 +15,7 @@ in mat4 InstanceModelMatrix;
in vec4 outlineColorSize;
out vec4 pPos;
-out float vZ;
-out float vFacing;
+out vec3 vPos;
out vec2 ssPos;
out vec2 ssNor;
out vec4 vColSize;
@@ -34,25 +33,15 @@ void main()
mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix)));
vec4 viewpos = ViewMatrix * (InstanceModelMatrix * vec4(pos, 1.0));
- pPos = ProjectionMatrix * viewpos;
- vZ = abs(viewpos.z);
- /* if perspective */
- vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(-viewpos.xyz) : vec3(0.0, 0.0, 1.0);
+ vPos = viewpos.xyz;
+ pPos = ProjectionMatrix * viewpos;
/* TODO FIX: there is still a problem with this vector
* when the bone is scaled or in persp mode. But it's
* barelly visible at the outline corners. */
ssNor = normalize((NormalMatrix * snor).xy);
- vec3 normal = normalize(NormalMatrix * nor);
- /* Add a small bias to avoid loosing outline
- * on faces orthogonal to the view.
- * (test case: octahedral bone without rotation in front view.) */
- normal.z += 1e-6;
-
- vFacing = dot(V, normal);
-
ssPos = proj(pPos);
vColSize = outlineColorSize;