From bf161e7b141b2df8ed2dd5e8b5f1389d5cd99136 Mon Sep 17 00:00:00 2001 From: Daniel Sabo Date: Sat, 19 Dec 2015 15:53:42 -0800 Subject: [PATCH] app: MyBrush: Improve blend math --- app/paint/gimpmybrushsurface.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/paint/gimpmybrushsurface.c b/app/paint/gimpmybrushsurface.c index 26a4290575..70d3ea577e 100644 --- a/app/paint/gimpmybrushsurface.c +++ b/app/paint/gimpmybrushsurface.c @@ -373,14 +373,20 @@ gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface, rr = calculate_rr (ix, iy, x, y, aspect_ratio, sn, cs, one_over_radius2); alpha = calculate_alpha_for_rr (rr, hardness, segment1_slope, segment2_slope) * opaque; dst_alpha = pixel[ALPHA]; - a = alpha * color_a + dst_alpha * (1.0f - alpha); + /* a = alpha * color_a + dst_alpha * (1.0f - alpha); + * which converts to: */ + a = alpha * (color_a - dst_alpha) + dst_alpha; if (a > 0.0f) { - float a_term = dst_alpha * (1.0f - alpha); - dst_pixel[RED] = (color_r * alpha * color_a + pixel[RED] * a_term) / a; - dst_pixel[GREEN] = (color_g * alpha * color_a + pixel[GREEN] * a_term) / a; - dst_pixel[BLUE] = (color_b * alpha * color_a + pixel[BLUE] * a_term) / a; + /* By definition the ratio between each color[] and pixel[] component in a non-pre-multipled blend always sums to 1.0f. + * Originaly this would have been "(color[n] * alpha * color_a + pixel[n] * dst_alpha * (1.0f - alpha)) / a", + * instead we only calculate the cheaper term. */ + float src_term = (alpha * color_a) / a; + float dst_term = 1.0f - src_term; + dst_pixel[RED] = color_r * src_term + pixel[RED] * dst_term; + dst_pixel[GREEN] = color_g * src_term + pixel[GREEN] * dst_term; + dst_pixel[BLUE] = color_b * src_term + pixel[BLUE] * dst_term; } dst_pixel[ALPHA] = a;