32 b.use_custom_socket_order();
36 b.add_input<
decl::Color>(
"Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
37 b.add_input<
decl::Float>(
"Mask").default_value(1.0f).min(0.0f).max(1.0f);
45 .description(
"Controls the saturation of the entire image");
51 .description(
"Controls the contrast of the entire image");
57 .description(
"Controls the gamma of the entire image");
63 .description(
"Controls the gain of the entire image");
69 .description(
"Controls the lift of the entire image");
77 .description(
"Controls the saturation of the highlights");
83 .description(
"Controls the contrast of the highlights");
89 .description(
"Controls the gamma of the highlights");
95 .description(
"Controls the gain of the highlights");
101 .description(
"Controls the lift of the highlights");
109 .description(
"Controls the saturation of the midtones");
115 .description(
"Controls the contrast of the midtones");
121 .description(
"Controls the gamma of the midtones");
127 .description(
"Controls the gain of the midtones");
133 .description(
"Controls the lift of the midtones");
141 .description(
"Controls the saturation of the shadows");
147 .description(
"Controls the contrast of the shadows");
153 .description(
"Controls the gamma of the shadows");
159 .description(
"Controls the gain of the shadows");
165 .description(
"Controls the lift of the shadows");
174 "Specifies the luminance at which the midetones of the image start and the shadows end");
181 "Specifies the luminance at which the midetones of the image end and the highlights "
187 .
description(
"If true, the correction will be applied on the red channel");
190 .
description(
"If true, the correction will be applied on the green channel");
193 .
description(
"If true, the correction will be applied on the blue channel");
204 float luminance_coefficients[3];
209 "node_composite_color_correction",
217 const float &master_saturation,
218 const float &master_contrast,
219 const float &master_gamma,
220 const float &master_gain,
221 const float &master_lift,
222 const float &highlights_saturation,
223 const float &highlights_contrast,
224 const float &highlights_gamma,
225 const float &highlights_gain,
226 const float &highlights_lift,
227 const float &midtones_saturation,
228 const float &midtones_contrast,
229 const float &midtones_gamma,
230 const float &midtones_gain,
231 const float &midtones_lift,
232 const float &shadows_saturation,
233 const float &shadows_contrast,
234 const float &shadows_gamma,
235 const float &shadows_gain,
236 const float &shadows_lift,
237 const float &start_midtones,
238 const float &end_midtones,
239 const bool &apply_on_red,
240 const bool &apply_on_green,
241 const bool &apply_on_blue,
242 const float3 &luminance_coefficients)
244 const float margin = 0.10f;
245 const float margin_divider = 0.5f / margin;
247 float level_shadows = 0.0f;
248 float level_midtones = 0.0f;
249 float level_highlights = 0.0f;
250 if (level < (start_midtones - margin)) {
251 level_shadows = 1.0f;
253 else if (level < (start_midtones + margin)) {
254 level_midtones = ((level - start_midtones) * margin_divider) + 0.5f;
255 level_shadows = 1.0f - level_midtones;
257 else if (level < (end_midtones - margin)) {
258 level_midtones = 1.0f;
260 else if (level < (end_midtones + margin)) {
261 level_highlights = ((level - end_midtones) * margin_divider) + 0.5f;
262 level_midtones = 1.0f - level_highlights;
265 level_highlights = 1.0f;
268 float contrast = level_shadows * shadows_contrast;
269 contrast += level_midtones * midtones_contrast;
270 contrast += level_highlights * highlights_contrast;
271 contrast *= master_contrast;
272 float saturation = level_shadows * shadows_saturation;
273 saturation += level_midtones * midtones_saturation;
274 saturation += level_highlights * highlights_saturation;
275 saturation *= master_saturation;
276 float gamma = level_shadows * shadows_gamma;
277 gamma += level_midtones * midtones_gamma;
278 gamma += level_highlights * highlights_gamma;
279 gamma *= master_gamma;
280 float gain = level_shadows * shadows_gain;
281 gain += level_midtones * midtones_gain;
282 gain += level_highlights * highlights_gain;
284 float lift = level_shadows * shadows_lift;
285 lift += level_midtones * midtones_lift;
286 lift += level_highlights * highlights_lift;
289 float inverse_gamma = 1.0f / gamma;
292 float3 corrected = luma + saturation * (
color.xyz() - luma);
293 corrected = 0.5f + (corrected - 0.5f) * contrast;
297 return float4(apply_on_red ? corrected.x :
color.x,
298 apply_on_green ? corrected.y :
color.y,
299 apply_on_blue ? corrected.z :
color.z,
305 float3 luminance_coefficients;
309 return mf::build::detail::build_multi_function_with_n_inputs_one_output<float4>(
313 const float &master_saturation,
314 const float &master_contrast,
315 const float &master_gamma,
316 const float &master_gain,
317 const float &master_lift,
318 const float &highlights_saturation,
319 const float &highlights_contrast,
320 const float &highlights_gamma,
321 const float &highlights_gain,
322 const float &highlights_lift,
323 const float &midtones_saturation,
324 const float &midtones_contrast,
325 const float &midtones_gamma,
326 const float &midtones_gain,
327 const float &midtones_lift,
328 const float &shadows_saturation,
329 const float &shadows_contrast,
330 const float &shadows_gamma,
331 const float &shadows_gain,
332 const float &shadows_lift,
333 const float &start_midtones,
334 const float &end_midtones,
335 const bool &apply_on_red,
336 const bool &apply_on_green,
337 const bool &apply_on_blue) ->
float4 {
345 highlights_saturation,
365 luminance_coefficients);
367 mf::build::exec_presets::SomeSpanOrSingle<0>(),
407 ntype.
ui_name =
"Color Correction";
409 "Adjust the color of an image, separately in several tonal ranges (highlights, midtones and "
413 ntype.
declare = file_ns::cmp_node_colorcorrection_declare;
414 ntype.
gpu_fn = file_ns::node_gpu_material;
#define NODE_CLASS_OP_COLOR
#define CMP_NODE_COLORCORRECTION
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
#define NOD_REGISTER_NODE(REGISTER_FUNC)
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
void construct_and_set_matching_fn_cb(Fn &&create_multi_function)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
T min(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)
T fallback_pow(const T &x, const T &power, const T &fallback)
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
static int node_gpu_material(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *inputs, GPUNodeStack *outputs)
static void cmp_node_colorcorrection_declare(NodeDeclarationBuilder &b)
static float4 color_correction(const float4 &color, const float &mask, const float &master_saturation, const float &master_contrast, const float &master_gamma, const float &master_gain, const float &master_lift, const float &highlights_saturation, const float &highlights_contrast, const float &highlights_gamma, const float &highlights_gain, const float &highlights_lift, const float &midtones_saturation, const float &midtones_contrast, const float &midtones_gamma, const float &midtones_gain, const float &midtones_lift, const float &shadows_saturation, const float &shadows_contrast, const float &shadows_gamma, const float &shadows_gain, const float &shadows_lift, const float &start_midtones, const float &end_midtones, const bool &apply_on_red, const bool &apply_on_green, const bool &apply_on_blue, const float3 &luminance_coefficients)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
static void register_node_type_cmp_colorcorrection()
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
static blender::bke::bNodeSocketTemplate outputs[]
static blender::bke::bNodeSocketTemplate inputs[]
std::string ui_description
NodeGPUExecFunction gpu_fn
NodeMultiFunctionBuildFunction build_multi_function
const char * enum_name_legacy
NodeDeclareFunction declare