Fix T46560: 2D paint smear and soften brushes not working with alpha.

Interpolate rather than do alpha over mix, matching projection paint.
This commit is contained in:
Brecht Van Lommel 2017-07-21 00:16:59 +02:00
parent 2b132fc3f7
commit 0d4fd7528f
Notes: blender-bot 2023-02-14 08:31:05 +01:00
Referenced by issue #50541, UV Image Paint Bugs: Smear Tool Black Alpha and Radius Global Hotkey Broken
Referenced by issue #46560, Smear brush destroys alpha
3 changed files with 39 additions and 13 deletions

View File

@ -797,6 +797,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3];
mul_v3_v3fl(rrgbf, rgb, map_alpha);
rrgbf[3] = rgb[3];
}
else {
unsigned char straight[4];
@ -806,6 +807,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
rrgb[0] = straight[0];
rrgb[1] = straight[1];
rrgb[2] = straight[2];
rrgb[3] = straight[3];
}
}
@ -995,7 +997,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short tile)
IMB_rectblend(ibufb, ibufb, ibuf, NULL, NULL, NULL, 0, region[a].destx, region[a].desty,
region[a].destx, region[a].desty,
region[a].srcx, region[a].srcy,
region[a].width, region[a].height, IMB_BLEND_COPY_RGB, false);
region[a].width, region[a].height, IMB_BLEND_COPY, false);
}
static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
@ -1096,6 +1098,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
/* lift from canvas */
if (s->tool == PAINT_TOOL_SOFTEN) {
paint_2d_lift_soften(s, s->canvas, ibufb, bpos, tile);
blend = IMB_BLEND_INTERPOLATE;
}
else if (s->tool == PAINT_TOOL_SMEAR) {
if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
@ -1103,6 +1106,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
paint_2d_convert_brushco(ibufb, lastpos, blastpos);
paint_2d_lift_smear(s->canvas, ibufb, blastpos, tile);
blend = IMB_BLEND_INTERPOLATE;
}
else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
liftpos[0] = pos[0] - offset[0] * s->canvas->x;

View File

@ -205,6 +205,7 @@ typedef enum IMB_BlendMode {
IMB_BLEND_SATURATION = 21,
IMB_BLEND_LUMINOSITY = 22,
IMB_BLEND_COLOR = 23,
IMB_BLEND_INTERPOLATE = 24,
IMB_BLEND_COPY = 1000,
IMB_BLEND_COPY_RGB = 1001,

View File

@ -424,6 +424,7 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
else {
switch (mode) {
case IMB_BLEND_MIX:
case IMB_BLEND_INTERPOLATE:
func = blend_color_mix_byte;
func_float = blend_color_mix_float;
break;
@ -563,9 +564,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask_src[0] = src[0];
mask_src[1] = src[1];
mask_src[2] = src[2];
mask_src[3] = divide_round_i(src[3] * mask, 65535);
func((unsigned char *)dr, (unsigned char *)or, mask_src);
if (mode == IMB_BLEND_INTERPOLATE) {
mask_src[3] = src[3];
blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
}
else {
mask_src[3] = divide_round_i(src[3] * mask, 65535);
func((unsigned char *)dr, (unsigned char *)or, mask_src);
}
}
}
}
@ -588,9 +595,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask_src[0] = src[0];
mask_src[1] = src[1];
mask_src[2] = src[2];
mask_src[3] = divide_round_i(src[3] * mask, 65535);
func((unsigned char *)dr, (unsigned char *)or, mask_src);
if (mode == IMB_BLEND_INTERPOLATE) {
mask_src[3] = src[3];
blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
}
else {
mask_src[3] = divide_round_i(src[3] * mask, 65535);
func((unsigned char *)dr, (unsigned char *)or, mask_src);
}
}
}
}
@ -642,12 +655,16 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask = min_ff(mask, 65535.0);
if (mask > *dmr) {
float mask_srf[4];
*dmr = mask;
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
func_float(drf, orf, mask_srf);
if (mode == IMB_BLEND_INTERPOLATE) {
blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
}
else {
float mask_srf[4];
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
func_float(drf, orf, mask_srf);
}
}
}
}
@ -664,11 +681,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask = min_ff(mask, 65535.0);
if (srf[3] && (mask > 0.0f)) {
float mask_srf[4];
if (mode == IMB_BLEND_INTERPOLATE) {
blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
}
else {
float mask_srf[4];
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
func_float(drf, orf, mask_srf);
}
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
func_float(drf, orf, mask_srf);
}
}
}