[Bf-blender-cvs] [4de7c0c3105] blender2.8: Compositor: Film-like curve

Jeroen Bakker noreply at git.blender.org
Thu Aug 23 11:41:56 CEST 2018


Commit: 4de7c0c3105a80d244dd9f2078c310331873a16b
Author: Jeroen Bakker
Date:   Thu Aug 23 10:25:54 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB4de7c0c3105a80d244dd9f2078c310331873a16b

Compositor: Film-like curve

Film-like curves for the RGB Curve node (Compositor) and Curve Modifier
(Sequencer)

Film-like curves originated from Adobe.
"It’s an RGB curve where the tone curve is applied on the largest and smallest value, and then the middle value is adapted to keep a constant hue as defined by RGB-HSL/HSV. In terms of look and saturation increase it’s very similar to a pure RGB curve, more so than a HSL-L curve or HSV-V curve, but some color shift problems are avoided."

Other tools like Natron, Krita and RawTherapee have implemented this curve tone.

Reviewers: brecht, campbellbarton

Reviewed By: brecht

Tags: #compositing, #video_sequencer

Differential Revision: https://developer.blender.org/D3638

===================================================================

M	release/scripts/startup/bl_ui/space_sequencer.py
M	source/blender/blenkernel/intern/colortools.c
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_color_types.h
M	source/blender/makesrna/intern/rna_color.c
M	source/blender/makesrna/intern/rna_ui_api.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 84ae59772b6..dd90968bca3 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -1248,7 +1248,7 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
                     box.prop(mod, "color_multiply")
                     draw_color_balance(box, mod.color_balance)
                 elif mod.type == 'CURVES':
-                    box.template_curve_mapping(mod, "curve_mapping", type='COLOR')
+                    box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True)
                 elif mod.type == 'HUE_CORRECT':
                     box.template_curve_mapping(mod, "curve_mapping", type='HUE')
                 elif mod.type == 'BRIGHT_CONTRAST':
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index d18572a57f6..ddf11d148cb 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -938,6 +938,21 @@ void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const
 	vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2]));
 }
 
+static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap, float vecout[3], const float vecin[3],
+                                               const int channel_offset[3])
+{
+	const float v0in = vecin[channel_offset[0]];
+	const float v1in = vecin[channel_offset[1]];
+	const float v2in = vecin[channel_offset[2]];
+
+	const float v0 = curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in);
+	const float v2 = curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in);
+	const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in));
+
+	vecout[channel_offset[0]] = v0;
+	vecout[channel_offset[1]] = v1;
+	vecout[channel_offset[2]] = v2;
+}
 /** same as #curvemapping_evaluate_premulRGBF
  * but black/bwmul are passed as args for the compositor
  * where they can change per pixel.
@@ -950,17 +965,70 @@ void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const
 void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, float vecout[3], const float vecin[3],
                                          const float black[3], const float bwmul[3])
 {
-	vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - black[0]) * bwmul[0]);
-	vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - black[1]) * bwmul[1]);
-	vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - black[2]) * bwmul[2]);
+	const float r = (vecin[0] - black[0]) * bwmul[0];
+	const float g = (vecin[1] - black[1]) * bwmul[1];
+	const float b = (vecin[2] - black[2]) * bwmul[2];
+
+	switch (cumap->tone)
+	{
+		default:
+		case CURVE_TONE_STANDARD:
+		{
+			vecout[0] = curvemap_evaluateF(&cumap->cm[0], r);
+			vecout[1] = curvemap_evaluateF(&cumap->cm[1], g);
+			vecout[2] = curvemap_evaluateF(&cumap->cm[2], b);
+			break;
+		}
+		case CURVE_TONE_FILMLIKE:
+		{
+			if (r >= g) {
+				if (g > b) {
+					/* Case 1: r >= g >  b */
+					const int shuffeled_channels[] = {0, 1, 2};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+				else if (b > r) {
+					/* Case 2: b >  r >= g */
+					const int shuffeled_channels[] = {2, 0, 1};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+				else if (b > g) {
+					/* Case 3: r >= b >  g */
+					const int shuffeled_channels[] = {0, 2, 1};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+				else {
+					/* Case 4: r >= g == b */
+					copy_v2_fl2(vecout, curvemap_evaluateF(&cumap->cm[0], r), curvemap_evaluateF(&cumap->cm[1], g));
+					vecout[2] = vecout[1];
+				}
+			}
+			else {
+				if (r >= b) {
+					/* Case 5: g >  r >= b */
+					const int shuffeled_channels[] = {1, 0, 2};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+				else if (b >  g) {
+					/* Case 6: b >  g >  r */
+					const int shuffeled_channels[] = {2, 1, 0};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+				else {
+					/* Case 7: g >= b >  r */
+					const int shuffeled_channels[] = {1, 2, 0};
+					curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels);
+				}
+			}
+			break;
+		}
+	}
 }
 
 /* RGB with black/white points and premult. tables are checked */
 void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3])
 {
-	vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - cumap->black[0]) * cumap->bwmul[0]);
-	vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - cumap->black[1]) * cumap->bwmul[1]);
-	vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - cumap->black[2]) * cumap->bwmul[2]);
+	curvemapping_evaluate_premulRGBF_ex(cumap, vecout, vecin, cumap->black, cumap->bwmul);
 }
 
 /* same as above, byte version */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 824920bce73..5cc3e369439 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1074,7 +1074,7 @@ void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, const char *pr
 void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
 void uiTemplateCurveMapping(
         uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type,
-        bool levels, bool brush, bool neg_slope);
+        bool levels, bool brush, bool neg_slope, bool tone);
 void uiTemplateColorPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool value_slider, bool lock, bool lock_luminosity, bool cubic);
 void uiTemplatePalette(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool color);
 void uiTemplateCryptoPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index e81ad1428d1..820b34c1ac4 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2942,7 +2942,7 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
 /* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
 static void curvemap_buttons_layout(
         uiLayout *layout, PointerRNA *ptr, char labeltype, bool levels,
-        bool brush, bool neg_slope, RNAUpdateCb *cb)
+        bool brush, bool neg_slope, bool tone, RNAUpdateCb *cb)
 {
 	CurveMapping *cumap = ptr->data;
 	CurveMap *cm = &cumap->cm[cumap->cur];
@@ -2956,6 +2956,11 @@ static void curvemap_buttons_layout(
 
 	block = uiLayoutGetBlock(layout);
 
+	if (tone) {
+		split = uiLayoutSplit(layout, 0.0f, false);
+		uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+	}
+
 	/* curve chooser */
 	row = uiLayoutRow(layout, false);
 
@@ -3107,7 +3112,7 @@ static void curvemap_buttons_layout(
 
 void uiTemplateCurveMapping(
         uiLayout *layout, PointerRNA *ptr, const char *propname, int type,
-        bool levels, bool brush, bool neg_slope)
+        bool levels, bool brush, bool neg_slope, bool tone)
 {
 	RNAUpdateCb *cb;
 	PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -3138,7 +3143,7 @@ void uiTemplateCurveMapping(
 	id = cptr.id.data;
 	UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
 
-	curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, cb);
+	curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
 
 	UI_block_lock_clear(block);
 
@@ -4797,7 +4802,7 @@ void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), P
 	col = uiLayoutColumn(layout, false);
 	uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
 	if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
-		uiTemplateCurveMapping(col, &view_transform_ptr, "curve_mapping", 'c', true, false, false);
+		uiTemplateCurveMapping(col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
 }
 
 /********************************* Component Menu *************************************/
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 4dfbb92971b..2634b3108fa 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -144,7 +144,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
 	}
 #endif
 
-	uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false);
+	uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false, false);
 
 	row = uiLayoutRow(layout, true);
 	uiItemR(row, ptr, "frame_start", 0, IFACE_("Sta"), ICON_NONE);
@@ -158,7 +158,7 @@ static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRN
 
 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {
-	uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false);
+	uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false, false);
 }
 
 #define SAMPLE_FLT_ISNONE FLT_MAX
@@ -186,7 +186,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
 		cumap->flag &= ~CUMA_DRAW_SAMPLE;
 	}
 
-	uiTemplateCurveMapping(layout, ptr, "mapping", 'c', false, false, false);
+	uiTemplateCurveMapping(layout, ptr, "mapping", 'c', false, false, false, true);
 }
 
 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1975,7 +1975,7 @@ static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C),
 		cumap->flag &= ~CUMA_DRAW_SAMPLE;
 	}
 
-	uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false);
+	uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false, false);


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list