[Bf-blender-cvs] [0c90aa097d0] master: Compositor: Full frame Color Correction node

Manuel Castilla noreply at git.blender.org
Mon Jul 5 23:51:56 CEST 2021


Commit: 0c90aa097d0eb2f4faf91974113edb2b60599c9c
Author: Manuel Castilla
Date:   Mon Jul 5 21:02:22 2021 +0200
Branches: master
https://developer.blender.org/rB0c90aa097d0eb2f4faf91974113edb2b60599c9c

Compositor: Full frame Color Correction node

Adds full frame implementation to this node operation.
No functional changes.
1.4x faster than tiled fallback.

Reviewed By: jbakker

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

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

M	source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
M	source/blender/compositor/operations/COM_ColorCorrectionOperation.h

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

diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
index 168e9b57eb2..fa5c8c994d4 100644
--- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
@@ -157,6 +157,86 @@ void ColorCorrectionOperation::executePixelSampled(float output[4],
   output[3] = inputImageColor[3];
 }
 
+void ColorCorrectionOperation::update_memory_buffer_row(PixelCursor &p)
+{
+  for (; p.out < p.row_end; p.next()) {
+    const float *in_color = p.ins[0];
+    const float *in_mask = p.ins[1];
+
+    const float level = (in_color[0] + in_color[1] + in_color[2]) / 3.0f;
+    float level_shadows = 0.0f;
+    float level_midtones = 0.0f;
+    float level_highlights = 0.0f;
+    constexpr float MARGIN = 0.10f;
+    constexpr float MARGIN_DIV = 0.5f / MARGIN;
+    if (level < this->m_data->startmidtones - MARGIN) {
+      level_shadows = 1.0f;
+    }
+    else if (level < this->m_data->startmidtones + MARGIN) {
+      level_midtones = ((level - this->m_data->startmidtones) * MARGIN_DIV) + 0.5f;
+      level_shadows = 1.0f - level_midtones;
+    }
+    else if (level < this->m_data->endmidtones - MARGIN) {
+      level_midtones = 1.0f;
+    }
+    else if (level < this->m_data->endmidtones + MARGIN) {
+      level_highlights = ((level - this->m_data->endmidtones) * MARGIN_DIV) + 0.5f;
+      level_midtones = 1.0f - level_highlights;
+    }
+    else {
+      level_highlights = 1.0f;
+    }
+    float contrast = this->m_data->master.contrast;
+    float saturation = this->m_data->master.saturation;
+    float gamma = this->m_data->master.gamma;
+    float gain = this->m_data->master.gain;
+    float lift = this->m_data->master.lift;
+    contrast *= level_shadows * this->m_data->shadows.contrast +
+                level_midtones * this->m_data->midtones.contrast +
+                level_highlights * this->m_data->highlights.contrast;
+    saturation *= level_shadows * this->m_data->shadows.saturation +
+                  level_midtones * this->m_data->midtones.saturation +
+                  level_highlights * this->m_data->highlights.saturation;
+    gamma *= level_shadows * this->m_data->shadows.gamma +
+             level_midtones * this->m_data->midtones.gamma +
+             level_highlights * this->m_data->highlights.gamma;
+    gain *= level_shadows * this->m_data->shadows.gain +
+            level_midtones * this->m_data->midtones.gain +
+            level_highlights * this->m_data->highlights.gain;
+    lift += level_shadows * this->m_data->shadows.lift +
+            level_midtones * this->m_data->midtones.lift +
+            level_highlights * this->m_data->highlights.lift;
+
+    const float inv_gamma = 1.0f / gamma;
+    const float luma = IMB_colormanagement_get_luminance(in_color);
+
+    float r = luma + saturation * (in_color[0] - luma);
+    float g = luma + saturation * (in_color[1] - luma);
+    float b = luma + saturation * (in_color[2] - luma);
+
+    r = 0.5f + (r - 0.5f) * contrast;
+    g = 0.5f + (g - 0.5f) * contrast;
+    b = 0.5f + (b - 0.5f) * contrast;
+
+    /* Check for negative values to avoid nan. */
+    r = color_correct_powf_safe(r * gain + lift, inv_gamma, r);
+    g = color_correct_powf_safe(g * gain + lift, inv_gamma, g);
+    b = color_correct_powf_safe(b * gain + lift, inv_gamma, b);
+
+    /* Mix with mask. */
+    const float value = MIN2(1.0f, in_mask[0]);
+    const float m_value = 1.0f - value;
+    r = m_value * in_color[0] + value * r;
+    g = m_value * in_color[1] + value * g;
+    b = m_value * in_color[2] + value * b;
+
+    p.out[0] = m_redChannelEnabled ? r : in_color[0];
+    p.out[1] = m_greenChannelEnabled ? g : in_color[1];
+    p.out[2] = m_blueChannelEnabled ? b : in_color[2];
+    p.out[3] = in_color[3];
+  }
+}
+
 void ColorCorrectionOperation::deinitExecution()
 {
   this->m_inputImage = nullptr;
diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
index c5826ed0152..32b5e02e77a 100644
--- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
@@ -18,11 +18,11 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedRowOperation.h"
 
 namespace blender::compositor {
 
-class ColorCorrectionOperation : public NodeOperation {
+class ColorCorrectionOperation : public MultiThreadedRowOperation {
  private:
   /**
    * Cached reference to the inputProgram
@@ -69,6 +69,8 @@ class ColorCorrectionOperation : public NodeOperation {
   {
     this->m_blueChannelEnabled = enabled;
   }
+
+  void update_memory_buffer_row(PixelCursor &p) override;
 };
 
 }  // namespace blender::compositor



More information about the Bf-blender-cvs mailing list