From 46662a289b53f79b9e6fa9c0ed07db8368982b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 2 May 2018 08:45:06 +0200 Subject: Armature: Envelope: Optimize outline shader. --- .../shaders/armature_envelope_outline_vert.glsl | 33 ++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl b/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl index 2c38ffebca4..c7958148588 100644 --- a/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl +++ b/source/blender/draw/modes/shaders/armature_envelope_outline_vert.glsl @@ -73,17 +73,12 @@ mat3 compute_mat(vec4 sphere, vec3 bone_vec, out float z_ofs) return mat3(x_axis, y_axis, z_axis); } -struct Bone { vec3 p1, vec; float vec_rsq, h_bias, h_scale; }; +struct Bone { vec3 vec; float sinb; }; bool bone_blend_starts(vec3 p, Bone b) { - /* Simple capsule sdf with a minor touch and optimisations. */ - vec3 pa = p - b.p1; - float h = dot(pa, b.vec) * b.vec_rsq; - h = h * b.h_scale + b.h_bias; /* comment this line for sharp transition. */ - return h > 0.0; /* we just want to know when the head sphere starts interpolating. */ - // h = clamp(h, 0.0, 1.0); - // return length(pa - b.vec * h) - (b.r1 + b.rdif * h); + /* we just want to know when the head sphere starts interpolating. */ + return dot(p, b.vec) > -b.sinb; } vec3 get_outline_point( @@ -93,10 +88,13 @@ vec3 get_outline_point( /* Compute outline position on the nearest sphere and check * if it penetrates the capsule body. If it does, put this * vertex on the farthest sphere. */ - vec3 wpos = sph_near.xyz + mat_near * vec3(pos * sph_near.w, z_ofs_near); + vec3 wpos = mat_near * vec3(pos * sph_near.w, z_ofs_near); if (bone_blend_starts(wpos, b)) { wpos = sph_far.xyz + mat_far * vec3(pos * sph_far.w, z_ofs_far); } + else { + wpos += sph_near.xyz; + } return wpos; } @@ -117,20 +115,13 @@ void main() sph_far = tailSphere; } - Bone b; - /* Precompute everything we can to speedup iterations. */ - b.p1 = sph_near.xyz; - b.vec = sph_far.xyz - sph_near.xyz; - float vec_lsq = max(1e-8, dot(b.vec, b.vec)); - b.vec_rsq = 1.0 / vec_lsq; - float sinb = (sph_far.w - sph_near.w) * b.vec_rsq; - float ofs1 = sinb * sph_near.w; - float ofs2 = sinb * sph_far.w; - b.h_scale = 1.0 - ofs1 + ofs2; - b.h_bias = ofs1 * b.h_scale; - vec3 bone_vec = (sph_far.xyz - sph_near.xyz) + 1e-8; + Bone b; + float bone_lenrcp = 1.0 / max(1e-8, sqrt(dot(bone_vec, bone_vec))); + b.sinb = (sph_far.w - sph_near.w) * bone_lenrcp * sph_near.w; + b.vec = bone_vec * bone_lenrcp; + float z_ofs_near, z_ofs_far; mat3 mat_near = compute_mat(sph_near, bone_vec, z_ofs_near); mat3 mat_far = compute_mat(sph_far, bone_vec, z_ofs_far); -- cgit v1.2.3