[Bf-blender-cvs] [2691dd28e7d] master: Fix T49979: HSV/HSL 'Far' interpolation in colorbands when both stops have same hue.

Bastien Montagne noreply at git.blender.org
Sun Mar 24 18:33:54 CET 2019


Commit: 2691dd28e7dc085d0ae0aef219c433d4521fc326
Author: Bastien Montagne
Date:   Tue Mar 19 19:50:30 2019 +0100
Branches: master
https://developer.blender.org/rB2691dd28e7dc085d0ae0aef219c433d4521fc326

Fix T49979: HSV/HSL 'Far' interpolation in colorbands when both stops have same hue.

When two stops had the exact same color, 'Far' interpolation would
behave like the three others and generate constant colors, instead of
generating expected 'full turn' in Hue space.

Note that this will break the 'constant' color between two stops with
same value in the 'Far' interpolation mode, but think that change is
OK/expected.

This fix also exposed that 'early out' case when we are after last stop
was not working properly, still triggering actual interpolation
computation in all cases, thus the refactor in `BKE_colorband_evaluate()`
itself. We also now avoid computing factors in constant case, and get
out early in all interpolation cases but the 'spline' ones (where color
ramping can start before first stop, and end after last one).

Work initiated by patch from Charlie Jolly (@charlie) in T49979, thanks.

Reviewers: brecht, sergey

Subscribers: charlie

Differential Revision: https://developer.blender.org/D4556

===================================================================

M	source/blender/blenkernel/intern/colorband.c

===================================================================

diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c
index 57c5e8eb0fe..5630a3268e2 100644
--- a/source/blender/blenkernel/intern/colorband.c
+++ b/source/blender/blenkernel/intern/colorband.c
@@ -350,7 +350,9 @@ static float colorband_hue_interp(
 		}
 		case COLBAND_HUE_FAR:
 		{
-			if      ((h1 < h2) && (h2 - h1) < +0.5f) mode = 1;
+			/* Do full loop in Hue space in case both stops are the same... */
+			if      (h1 == h2)                       mode = 1;
+			else if ((h1 < h2) && (h2 - h1) < +0.5f) mode = 1;
 			else if ((h1 > h2) && (h2 - h1) > -0.5f) mode = 2;
 			else                                     mode = 0;
 			break;
@@ -402,6 +404,8 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 
 	cbd1 = coba->data;
 
+	/* Note: when ipotype >= COLBAND_INTERP_B_SPLINE, we cannot do early-out with a constant color before
+	 * first color stop and after last one, because interpolation starts before and ends after those... */
 	ipotype = (coba->color_mode == COLBAND_BLEND_RGB) ? coba->ipotype : COLBAND_INTERP_LINEAR;
 
 	if (coba->tot == 1) {
@@ -410,7 +414,8 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 		out[2] = cbd1->b;
 		out[3] = cbd1->a;
 	}
-	else if ((in <= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) {
+	else if ((in <= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE, COLBAND_INTERP_CONSTANT)) {
+		/* We are before first color stop. */
 		out[0] = cbd1->r;
 		out[1] = cbd1->g;
 		out[2] = cbd1->b;
@@ -441,14 +446,21 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 			cbd2 = cbd1 - 1;
 		}
 
-		if ((in >= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) {
-			out[0] = cbd1->r;
-			out[1] = cbd1->g;
-			out[2] = cbd1->b;
-			out[3] = cbd1->a;
+		if ((a == coba->tot) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE, COLBAND_INTERP_CONSTANT)) {
+			/* We are after last color stop. */
+			out[0] = cbd2->r;
+			out[1] = cbd2->g;
+			out[2] = cbd2->b;
+			out[3] = cbd2->a;
+		}
+		else if (ipotype == COLBAND_INTERP_CONSTANT) {
+			/* constant */
+			out[0] = cbd2->r;
+			out[1] = cbd2->g;
+			out[2] = cbd2->b;
+			out[3] = cbd2->a;
 		}
 		else {
-
 			if (cbd2->pos != cbd1->pos) {
 				fac = (in - cbd1->pos) / (cbd2->pos - cbd1->pos);
 			}
@@ -458,14 +470,7 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 				fac = (a != coba->tot) ? 0.0f : 1.0f;
 			}
 
-			if (ipotype == COLBAND_INTERP_CONSTANT) {
-				/* constant */
-				out[0] = cbd2->r;
-				out[1] = cbd2->g;
-				out[2] = cbd2->b;
-				out[3] = cbd2->a;
-			}
-			else if (ipotype >= COLBAND_INTERP_B_SPLINE) {
+			if (ELEM(ipotype, COLBAND_INTERP_B_SPLINE, COLBAND_INTERP_CARDINAL)) {
 				/* ipo from right to left: 3 2 1 0 */
 				float t[4];
 
@@ -493,14 +498,11 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 				CLAMP(out[3], 0.0f, 1.0f);
 			}
 			else {
-				float mfac;
-
 				if (ipotype == COLBAND_INTERP_EASE) {
-					mfac = fac * fac;
-					fac = 3.0f * mfac - 2.0f * mfac * fac;
+					const float fac2 = fac * fac;
+					fac = 3.0f * fac2 - 2.0f * fac2 * fac;
 				}
-
-				mfac = 1.0f - fac;
+				const float mfac = 1.0f - fac;
 
 				if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSV)) {
 					float col1[3], col2[3];
@@ -538,6 +540,7 @@ bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
 			}
 		}
 	}
+
 	return true;   /* OK */
 }



More information about the Bf-blender-cvs mailing list