From c61c18486cc9b49101e5f7a5011384c7cc38444a Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Mon, 5 Aug 2024 13:37:17 -0500 Subject: [PATCH] Don't bevel corners on inner joints of quadratic bezier curves --- .../shaders/quadratic_bezier_stroke/geom.glsl | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/manimlib/shaders/quadratic_bezier_stroke/geom.glsl b/manimlib/shaders/quadratic_bezier_stroke/geom.glsl index 4232b3e9..beb4f016 100644 --- a/manimlib/shaders/quadratic_bezier_stroke/geom.glsl +++ b/manimlib/shaders/quadratic_bezier_stroke/geom.glsl @@ -67,9 +67,9 @@ vec4 get_joint_product(vec3 v1, vec3 v2){ } -vec3 project(vec3 vect, vec3 normal){ +vec3 project(vec3 vect, vec3 unit_normal){ /* Project the vector onto the plane perpendicular to a given unit normal */ - return vect - dot(vect, normal) * normal; + return vect - dot(vect, unit_normal) * unit_normal; } vec3 inverse_joint_product(vec3 vect, vec4 joint_product){ @@ -87,7 +87,7 @@ vec3 inverse_joint_product(vec3 vect, vec4 joint_product){ } -vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_product){ +vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_product, bool inner_joint){ /* Step the the left of a curve. First a perpendicular direction is calculated, then it is adjusted @@ -95,9 +95,9 @@ vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_prod */ vec3 step = normalize(cross(unit_normal, unit_tan)); - // Check if an adjustment is needed + // Check if an adjustment is needed, float cos_angle = joint_product.w; - if(abs(cos_angle) > 1 - 1e-5 || int(joint_type) == NO_JOINT){ + if(inner_joint || int(joint_type) == NO_JOINT || cos_angle > 1 - 1e-5){ return step; } @@ -107,11 +107,11 @@ vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_prod (cos_angle + 1.0) / sin_angle : (cos_angle - 1.0) / sin_angle; - // return step + shift * unit_tan; vec3 result = step + shift * unit_tan; if (length(result) > MITER_LIMIT){ result = MITER_LIMIT * normalize(result); } + return result; } @@ -121,28 +121,31 @@ void emit_point_with_width( vec3 tangent, vec4 joint_product, float width, - vec4 joint_color + vec4 joint_color, + bool inner_joint ){ // Normalize relevant vectors vec3 unit_tan; vec4 unit_jp; vec3 unit_normal; - if(bool(flat_stroke)){ + vec3 to_camera = camera_position - point; + if(flat_stroke == 1.0){ unit_tan = normalize(tangent); unit_jp = normalized_joint_product(joint_product); unit_normal = get_joint_unit_normal(joint_product); }else{ - unit_normal = normalize(camera_position - point); + unit_normal = normalize(to_camera); unit_tan = normalize(project(tangent, unit_normal)); vec3 adj_tan = inverse_joint_product(tangent, joint_product); adj_tan = project(adj_tan, unit_normal); unit_jp = normalized_joint_product(get_joint_product(unit_tan, adj_tan)); } - if(unit_normal.z < 0) unit_normal *= -1; // Choose the "outward" normal direction + // Choose the "outward" normal direction + if(to_camera.z * dot(unit_normal, to_camera) < 0) unit_normal *= -1; // Figure out the step from the point to the corners of the // triangle strip around the polyline - vec3 step = step_to_corner(point, unit_tan, unit_normal, unit_jp); + vec3 step = step_to_corner(point, unit_tan, unit_normal, unit_jp, inner_joint); // Set styling color = finalize_color(joint_color, point, unit_normal); @@ -205,7 +208,8 @@ void main() { tangent_on_quadratic(t, c1, c2), joint_products[i], mix(v_stroke_width[0], v_stroke_width[2], t), - mix(v_color[0], v_color[2], t) + mix(v_color[0], v_color[2], t), + (i > 0 && i < n_steps - 1) // Is this an inner joint ); } EndPrimitive();