Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2022-04-12 08:49:18 +0300
committerJoseph Eagar <joeedh@gmail.com>2022-04-12 08:54:32 +0300
commitd683ea4862130b448077de08b2dcebc20418784e (patch)
treec6cbf5011dbf4d8a95122a362ea28971db2b9939
parent2451d7d57ed354aa3721153af417f06b2cebeec0 (diff)
Fix T97098: Color filter sharpening artifacts.
Color filter sharpening now clamps the output. The sharpening delta is now calculated from the difference of two levels of vertex averaging instead of one smooth iteration and the base color. TODO: Sharpen in a different color space; SRGB-linear has saturation artifacts. I tried HSL but it had value artifacts. I'd like to try LAB but we don't seem to have conversion functions for it (at least as far as I could see).
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c71
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c1
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
3 files changed, 74 insertions, 1 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index a5bd87117fc..ab14a9629b1 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -193,7 +193,32 @@ static void color_filter_task_cb(void *__restrict userdata,
float col[4];
SCULPT_vertex_color_get(ss, vd.index, col);
- blend_color_interpolate_float(final_color, col, smooth_color, fade);
+ if (fade < 0.0f) {
+ interp_v4_v4v4(smooth_color, smooth_color, col, 0.5f);
+ }
+
+ bool copy_alpha = col[3] == smooth_color[3];
+
+ if (fade < 0.0f) {
+ float delta[4];
+
+ /* Unsharp mask. */
+ copy_v4_v4(delta, ss->filter_cache->pre_smoothed_color[vd.index]);
+ sub_v4_v4(delta, smooth_color);
+
+ copy_v4_v4(final_color, col);
+ madd_v4_v4fl(final_color, delta, fade);
+ }
+ else {
+ blend_color_interpolate_float(final_color, col, smooth_color, fade);
+ }
+
+ CLAMP4(final_color, 0.0f, 1.0f);
+
+ /* Prevent accumulated numeric error from corrupting alpha. */
+ if (copy_alpha) {
+ final_color[3] = smooth_color[3];
+ }
break;
}
}
@@ -208,6 +233,46 @@ static void color_filter_task_cb(void *__restrict userdata,
BKE_pbvh_node_mark_update_color(data->nodes[n]);
}
+static void sculpt_color_presmooth_init(SculptSession *ss)
+{
+ int totvert = SCULPT_vertex_count_get(ss);
+
+ if (!ss->filter_cache->pre_smoothed_color) {
+ ss->filter_cache->pre_smoothed_color = MEM_malloc_arrayN(
+ totvert, sizeof(float) * 4, "ss->filter_cache->pre_smoothed_color");
+ }
+
+ for (int i = 0; i < totvert; i++) {
+ SCULPT_vertex_color_get(ss, i, ss->filter_cache->pre_smoothed_color[i]);
+ }
+
+ for (int iteration = 0; iteration < 2; iteration++) {
+ for (int i = 0; i < totvert; i++) {
+ float avg[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ float col[4] = {0};
+
+ copy_v4_v4(col, ss->filter_cache->pre_smoothed_color[ni.index]);
+
+ add_v4_v4(avg, col);
+ total++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (total > 0) {
+ mul_v4_fl(avg, 1.0f / (float)total);
+ interp_v4_v4v4(ss->filter_cache->pre_smoothed_color[i],
+ ss->filter_cache->pre_smoothed_color[i],
+ avg,
+ 0.5f);
+ }
+ }
+ }
+}
+
static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
@@ -234,6 +299,10 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent
RNA_float_get_array(op->ptr, "fill_color", fill_color);
IMB_colormanagement_srgb_to_scene_linear_v3(fill_color);
+ if (filter_strength < 0.0 && !ss->filter_cache->pre_smoothed_color) {
+ sculpt_color_presmooth_init(ss);
+ }
+
SculptThreadedTaskData data = {
.sd = sd,
.ob = ob,
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 4b832256dae..a32b1c3015b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -178,6 +178,7 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache->sharpen_factor);
MEM_SAFE_FREE(ss->filter_cache->detail_directions);
MEM_SAFE_FREE(ss->filter_cache->limit_surface_co);
+ MEM_SAFE_FREE(ss->filter_cache->pre_smoothed_color);
MEM_SAFE_FREE(ss->filter_cache);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 38905b50c59..bd18810acf8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -439,6 +439,9 @@ typedef struct FilterCache {
/* Auto-masking. */
AutomaskingCache *automasking;
+
+ /* Pre-smoothed colors used by sharpening. Colors are HSL.*/
+ float (*pre_smoothed_color)[4];
} FilterCache;
/**