[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56359] trunk/blender/source/blender: Fix #34233: bad alpha blending for 3D texture painting.
Brecht Van Lommel
brechtvanlommel at pandora.be
Sun Apr 28 13:55:41 CEST 2013
Revision: 56359
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56359
Author: blendix
Date: 2013-04-28 11:55:41 +0000 (Sun, 28 Apr 2013)
Log Message:
-----------
Fix #34233: bad alpha blending for 3D texture painting. Same changes as the
previous fix for 2D image painting were done, and also:
* For brushes that do masking (keeping the max contribution to a pixel limited),
the alpha from textures is now part of the mask. In many cases the logic
worked out the same and where it didn't it used to cause artifacts.
* Color interpolation for smear and soften tools now happens in premultipied
space, to avoid bleeding of RGB colors from zero alpha areas.
* Fix a few cases where byte <=> float conversion was not doing the proper
straight <=> premul conversion.
* Replace some float division by constants with multiplications, is faster.
Note: float texture painting seems to have some issues updating the OpenGL
texture, but issue was already there before this commit.
Modified Paths:
--------------
trunk/blender/source/blender/blenlib/intern/math_color.c
trunk/blender/source/blender/blenlib/intern/math_color_inline.c
trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
trunk/blender/source/blender/imbuf/IMB_imbuf.h
trunk/blender/source/blender/imbuf/intern/rectop.c
Modified: trunk/blender/source/blender/blenlib/intern/math_color.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_color.c 2013-04-28 11:05:49 UTC (rev 56358)
+++ trunk/blender/source/blender/blenlib/intern/math_color.c 2013-04-28 11:55:41 UTC (rev 56359)
@@ -197,9 +197,9 @@
if (hexcol[0] == '#') hexcol++;
if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) {
- *r = ri / 255.0f;
- *g = gi / 255.0f;
- *b = bi / 255.0f;
+ *r = ri * (1.0f / 255.0f);
+ *g = gi * (1.0f / 255.0f);
+ *b = bi * (1.0f / 255.0f);
CLAMP(*r, 0.0f, 1.0f);
CLAMP(*g, 0.0f, 1.0f);
CLAMP(*b, 0.0f, 1.0f);
@@ -394,17 +394,17 @@
void rgb_uchar_to_float(float col_r[3], const unsigned char col_ub[3])
{
- col_r[0] = ((float)col_ub[0]) / 255.0f;
- col_r[1] = ((float)col_ub[1]) / 255.0f;
- col_r[2] = ((float)col_ub[2]) / 255.0f;
+ col_r[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ col_r[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ col_r[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
}
void rgba_uchar_to_float(float col_r[4], const unsigned char col_ub[4])
{
- col_r[0] = ((float)col_ub[0]) / 255.0f;
- col_r[1] = ((float)col_ub[1]) / 255.0f;
- col_r[2] = ((float)col_ub[2]) / 255.0f;
- col_r[3] = ((float)col_ub[3]) / 255.0f;
+ col_r[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ col_r[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ col_r[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
+ col_r[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
}
void rgb_float_to_uchar(unsigned char col_r[3], const float col_f[3])
Modified: trunk/blender/source/blender/blenlib/intern/math_color_inline.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_color_inline.c 2013-04-28 11:05:49 UTC (rev 56358)
+++ trunk/blender/source/blender/blenlib/intern/math_color_inline.c 2013-04-28 11:55:41 UTC (rev 56359)
@@ -309,8 +309,8 @@
MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
{
- float alpha = color[3] / 255.0f;
- float fac = alpha / 255.0f;
+ float alpha = color[3] * (1.0f / 255.0f);
+ float fac = alpha * (1.0f / 255.0f);
result[0] = color[0] * fac;
result[1] = color[1] * fac;
Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c 2013-04-28 11:05:49 UTC (rev 56358)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c 2013-04-28 11:55:41 UTC (rev 56359)
@@ -40,9 +40,10 @@
# include "BLI_winstuff.h"
#endif
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
+#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
#include "BLI_memarena.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -110,26 +111,6 @@
return FTOCHAR(val);
}
-#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
- (c)[3] = f_to_char((f)[3]); \
-} (void)0
-
-#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
- (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
- (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
- (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
- (f)[3] = IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
-} (void)0
-
-#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
-} (void)0
-
/* ProjectionPaint defines */
/* approx the number of buckets to have under the brush,
@@ -570,7 +551,7 @@
else {
float rgba_tmp_f[4];
bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
+ premul_float_to_straight_uchar(rgba, rgba_tmp_f);
}
}
else {
@@ -580,7 +561,7 @@
else {
unsigned char rgba_tmp[4];
bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
+ straight_uchar_to_premul_float(rgba_fp, rgba_tmp);
}
}
}
@@ -599,7 +580,7 @@
if (rgba) {
if (ibuf->rect_float) {
float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
+ premul_float_to_straight_uchar(rgba, rgba_tmp_fp);
}
else {
*((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
@@ -611,8 +592,8 @@
copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
}
else {
- char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
+ unsigned char *tmp_ch = ((unsigned char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
+ straight_uchar_to_premul_float(rgba_fp, tmp_ch);
}
}
}
@@ -1192,10 +1173,10 @@
project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
if (ibuf_other->rect_float) { /* from float to float */
- mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) / 3.0f) * rgba_f[3];
+ mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) * (1.0f / 3.0f)) * rgba_f[3];
}
else { /* from char to float */
- mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
+ mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) * (1.0f / (255.0f * 3.0f))) * (rgba_ub[3] * (1.0f / 255.0f));
}
BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
@@ -1339,14 +1320,16 @@
if (ibuf->rect_float) {
projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
- projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
- projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
- projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
- projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
+ projPixel->origColor.f[0] = projPixel->pixel.f_pt[0];
+ projPixel->origColor.f[1] = projPixel->pixel.f_pt[1];
+ projPixel->origColor.f[2] = projPixel->pixel.f_pt[2];
+ projPixel->origColor.f[3] = projPixel->pixel.f_pt[3];
+ zero_v4(projPixel->newColor.f);
}
else {
projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
- projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
+ projPixel->origColor.uint = *projPixel->pixel.uint_pt;
+ projPixel->newColor.uint = 0;
}
/* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
@@ -1602,9 +1585,9 @@
static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
{
float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) * (1.0f / 4.0f);
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) * (1.0f / 4.0f);
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) * (1.0f / 4.0f);
sub_v3_v3v3(insetCos[0], origCos[0], cent);
sub_v3_v3v3(insetCos[1], origCos[1], cent);
@@ -1626,9 +1609,9 @@
static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
{
float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) * (1.0f / 3.0f);
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) * (1.0f / 3.0f);
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) * (1.0f / 3.0f);
sub_v3_v3v3(insetCos[0], origCos[0], cent);
sub_v3_v3v3(insetCos[1], origCos[1], cent);
@@ -2193,8 +2176,8 @@
/* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
* this is done so we can avoid offsetting all the pixels by 0.5 which causes
* problems when wrapping negative coords */
- xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 3.0f)) / ibuf_xf;
- yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 4.0f)) / ibuf_yf;
+ xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE * (1.0f / 3.0f))) / ibuf_xf;
+ yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE * (1.0f / 4.0f))) / ibuf_yf;
/* Note about (PROJ_GEOM_TOLERANCE/x) above...
* Needed to add this offset since UV coords are often quads aligned to pixels.
@@ -2477,8 +2460,8 @@
if (!is_ortho) {
pixelScreenCo[3] = 1.0f;
mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
- pixelScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * pixelScreenCo[0] / pixelScreenCo[3];
- pixelScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * pixelScreenCo[1] / pixelScreenCo[3];
+ pixelScreenCo[0] = (float)(ps->winx * 0.5f) + (ps->winx * 0.5f) * pixelScreenCo[0] / pixelScreenCo[3];
+ pixelScreenCo[1] = (float)(ps->winy * 0.5f) + (ps->winy * 0.5f) * pixelScreenCo[1] / pixelScreenCo[3];
pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
}
@@ -2976,8 +2959,8 @@
mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co);
/* screen space, not clamped */
- projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
- projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
+ projScreenCo[0] = (float)(ps->winx * 0.5f) + (ps->winx * 0.5f) * projScreenCo[0];
+ projScreenCo[1] = (float)(ps->winy * 0.5f) + (ps->winy * 0.5f) * projScreenCo[1];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list