From b7ea24f9ea6d795d9c1d467e943988a5c6c98fec Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Fri, 20 Jan 2023 10:09:58 -0800 Subject: [PATCH] Tweak stroke frag --- .../shaders/quadratic_bezier_stroke/frag.glsl | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/manimlib/shaders/quadratic_bezier_stroke/frag.glsl b/manimlib/shaders/quadratic_bezier_stroke/frag.glsl index 54319965..2ad580e8 100644 --- a/manimlib/shaders/quadratic_bezier_stroke/frag.glsl +++ b/manimlib/shaders/quadratic_bezier_stroke/frag.glsl @@ -10,7 +10,7 @@ in float is_linear; out vec4 frag_color; -const float QUICK_DIST_WIDTH = 0.2; +const float QUICK_DIST_WIDTH = 0.4; float dist_to_curve(){ // In the linear case, the curve will have @@ -20,13 +20,15 @@ float dist_to_curve(){ // Returns distance from uv_coords to the curve v = u^2 float x0 = uv_coords.x; float y0 = uv_coords.y; - if(uv_stroke_width < QUICK_DIST_WIDTH){ - // This is a quick approximation for computing - // the distance to the curve. - // Evaluate F(x, y) = y - x^2 - // divide by its gradient's magnitude - return abs((y0 - x0 * x0) / sqrt(1 + 4 * x0 * x0)); - } + // This is a quick approximation for computing + // the distance to the curve. + // Evaluate F(x, y) = y - x^2 + // divide by its gradient's magnitude + float Fxy = y0 - x0 * x0; + float grad_sq = 1 + 4 * x0 * x0; + float approx_dist = abs(Fxy) / sqrt(grad_sq); + if(approx_dist < QUICK_DIST_WIDTH) return approx_dist; + // Otherwise, solve for the minimal distance. // The distance squared between (x0, y0) and a point (x, x^2) looks like // @@ -37,7 +39,7 @@ float dist_to_curve(){ // x^3 + (0.5 - y0) * x - 0.5 * x0 = 0 // // Use two rounds of Newton's method - float x = x0; + float x = x0 + 2 * x0 * Fxy / grad_sq; // Seed with a step along the gradient vector float p = (0.5 - y0); float q = -0.5 * x0; for(int i = 0; i < 2; i++){ @@ -45,7 +47,7 @@ float dist_to_curve(){ float dfx = 3 * x * x + p; x = x - fx / dfx; } - return distance(vec2(x0, y0), vec2(x, x * x)); + return distance(uv_coords, vec2(x, x * x)); }