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
This commit is contained in:
Bastien Montagne 2019-03-19 19:50:30 +01:00
parent b48e6799f1
commit 2691dd28e7
Notes: blender-bot 2023-02-14 09:29:42 +01:00
Referenced by issue #49979, Color ramp HSV, Far-mode have wrong behavior
1 changed files with 25 additions and 22 deletions

View File

@ -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 */
}