Texture Paint: fix artifacts when using masks with symmetry.

For most brushes, texture painting uses a special mask accumulation
table in order to ensure that the amount of added color only increases
when the same pixel is touched multiple times by the stroke.

Unfortunately, only the mask texture was added to the mask before
this check, while normal, stencil, texture alpha masks were applied
after this check. This means that the check can pass if e.g. the
pressure is increased, but the final mask value is actually lower.
One might think that the mask values are fixed per pixel, but with
symmetry that isn't true. The result is a nasty stripe artifact due
to the discrete cutoff nature of the accumulation test.

In order to fix this, apply all masks before accumulation.
This commit is contained in:
Alexander Gavrilov 2018-11-29 18:54:32 +03:00
parent 43e7c5dd43
commit 26d5a3625e
Notes: blender-bot 2023-02-14 09:29:42 +01:00
Referenced by issue #60933, can't run blender 2.8 on my 32 bit windows 7 . It crashes
Referenced by issue #60933, can't run blender 2.8 on my 32 bit windows 7 . It crashes
Referenced by issue #59947, Animated texture node (in Compositor) remains static in render
Referenced by issue #58951, Subdivision not displaying correctly in edit mode
Referenced by issue #58742, Segmentation faults while trying to render with GPU and CPU hybrid rendering in Cycles
Referenced by issue #58672, Error by using modifiers
Referenced by issue #58422, Mirror modifier doesn't work with Curves
Referenced by issue #58380, Set Origin for spline right click menu
Referenced by issue #58381, No shortcut or menu entry for flipping normals
Referenced by issue #58382, Shortcuts all say "O" on rollover
Referenced by issue #58383, Screw modifier missing for splines
Referenced by issue #58385, Can't set [SplineType]
Referenced by issue #58386, Circle select not working properly
Referenced by issue #58372, Cycles GPU+CPU Render crashes
Referenced by issue #58362, Sample Color Shortcut doesn't work
Referenced by issue #58315, shader editor doesn't full screen
Referenced by issue #58299, Removed Auto Perspective in preferences but Blender re-enables subsequently
Referenced by issue #58301, Subsurface scatter \ separate albedo
Referenced by issue #58271, Blender 2.8 Beta Crash when pressing some toggles
Referenced by issue #58256, "Tool `Select Box` not found for space `IMAGE_EDITOR`." message is often displayed
Referenced by issue #58260, alt clicking to apply modifier to multiple objects doesn't work
Referenced by issue #58249, Studio lighting options aren't available in the shading options in 3D viewport.
Referenced by issue #58254, Crash report
Referenced by issue #58237, Exporters: Curve Modifier not applied when "apply modifiers" are selected
Referenced by issue #58240, Random crashes with mathutils.Vector
Referenced by issue #58242, Show whole scene transparent doesn't work correctly
Referenced by issue #58232, When rendering it seems that the focal length of the camera is different
Referenced by issue #58214, Annotations in any editor are hard to erase
Referenced by issue #58216, The backdrop in the VSE is broken.
Referenced by issue #58217, Import bpy makes mesh duplicate when changing location
Referenced by issue #58218, Use scene lights in LookDev produces different results to when it's off when there are no lights.
Referenced by issue #58219, Blender crashes if you attempt to change render layers or render slots
Referenced by issue #58221, Blender crashes on "spin tool" use
Referenced by issue #58202, Instanced children objects to parents are invisible in Cycles render
Referenced by issue #58206, EEVEE lights have a dragable energy value between 0-10 while higher values are useful.
Referenced by issue #58207, Render time going crazy!
Referenced by issue #58208, Selecting particle system as Dynamic paint Brush crashes Blender
Referenced by issue #58210, Surface Deform modifier doesn't indicate a successful bind, and shows a warning
Referenced by issue #58211, Node inputs and output "hit boxes" are smaller when different select options are used.
Referenced by issue #58191, Subdivision Surface modifier performance issues
Referenced by issue #58196, Annotation tool placed on view with thickness 0 is invisible
Referenced by issue #58197, "Shading Mode" and "Proportional Editing Object Mode" have the same keyboard shortcut
Referenced by issue #58199, Spin tool top bar settings don't apply
Referenced by issue #58201, Viewport Visibility and Render Visibility keyframes don't work
Referenced by issue #58184, Modifier texture changes don't update the modifier stack
Referenced by issue #58185, Crash when adjusting a torous in edit mode
Referenced by issue #58187, object visibility controlled by driver bug
Referenced by issue #58170, Crash when using Gpu
Referenced by issue #58171, Crash when using over 2 particles systems
Referenced by issue #58173, UV editor: "shared location" doesn't work correctly
Referenced by issue #58176, Loop Cut Doesn't Exit Properly
Referenced by issue #58164, Parent/child hierarchy in Outliner doesn't show properly
Referenced by issue #58167, Export arrow points the wrong way
Referenced by issue #58168, Displace Modifier Viewport Update with Texture (Generated)
Referenced by issue #58154, X-Mirror for edit mesh is broken in 2.8 Beta
1 changed files with 37 additions and 39 deletions

View File

@ -4679,6 +4679,41 @@ static void *do_projectpaint_thread(void *ph_v)
float texrgb[3];
float mask;
/* Extra mask for normal, layer stencil, .. */
float custom_mask = ((float)projPixel->mask) * (1.0f / 65535.0f);
/* Mask texture. */
if (ps->is_maskbrush) {
float texmask = BKE_brush_sample_masktex(ps->scene, ps->brush, projPixel->projCoSS, thread_index, pool);
CLAMP(texmask, 0.0f, 1.0f);
custom_mask *= texmask;
}
/* Color texture (alpha used as mask). */
if (ps->is_texbrush) {
MTex *mtex = &brush->mtex;
float samplecos[3];
float texrgba[4];
/* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
copy_v3_v3(samplecos, projPixel->worldCoSS);
}
else {
copy_v2_v2(samplecos, projPixel->projCoSS);
samplecos[2] = 0.0f;
}
/* note, for clone and smear, we only use the alpha, could be a special function */
BKE_brush_sample_tex_3d(ps->scene, brush, samplecos, texrgba, thread_index, pool);
copy_v3_v3(texrgb, texrgba);
custom_mask *= texrgba[3];
}
else {
zero_v3(texrgb);
}
if (ps->do_masking) {
/* masking to keep brush contribution to a pixel limited. note we do not do
* a simple max(mask, mask_accum), as this is very sensitive to spacing and
@ -4687,12 +4722,7 @@ static void *do_projectpaint_thread(void *ph_v)
* Instead we use a formula that adds up but approaches brush_alpha slowly
* and never exceeds it, which gives nice smooth results. */
float mask_accum = *projPixel->mask_accum;
float max_mask = brush_alpha * falloff * 65535.0f;
if (ps->is_maskbrush) {
float texmask = BKE_brush_sample_masktex(ps->scene, ps->brush, projPixel->projCoSS, thread_index, pool);
max_mask *= texmask;
}
float max_mask = brush_alpha * custom_mask * falloff * 65535.0f;
if (brush->flag & BRUSH_ACCUMULATE)
mask = mask_accum + max_mask;
@ -4712,41 +4742,9 @@ static void *do_projectpaint_thread(void *ph_v)
}
}
else {
mask = brush_alpha * falloff;
if (ps->is_maskbrush) {
float texmask = BKE_brush_sample_masktex(ps->scene, ps->brush, projPixel->projCoSS, thread_index, pool);
CLAMP(texmask, 0.0f, 1.0f);
mask *= texmask;
}
mask = brush_alpha * custom_mask * falloff;
}
if (ps->is_texbrush) {
MTex *mtex = &brush->mtex;
float samplecos[3];
float texrgba[4];
/* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
copy_v3_v3(samplecos, projPixel->worldCoSS);
}
else {
copy_v2_v2(samplecos, projPixel->projCoSS);
samplecos[2] = 0.0f;
}
/* note, for clone and smear, we only use the alpha, could be a special function */
BKE_brush_sample_tex_3d(ps->scene, brush, samplecos, texrgba, thread_index, pool);
copy_v3_v3(texrgb, texrgba);
mask *= texrgba[3];
}
else {
zero_v3(texrgb);
}
/* extra mask for normal, layer stencil, .. */
mask *= ((float)projPixel->mask) * (1.0f / 65535.0f);
if (mask > 0.0f) {
/* copy of code above */