diff options
author | Manuel Castilla <manzanillawork@gmail.com> | 2021-07-05 22:02:22 +0300 |
---|---|---|
committer | Manuel Castilla <manzanillawork@gmail.com> | 2021-07-06 00:36:43 +0300 |
commit | 0c90aa097d0eb2f4faf91974113edb2b60599c9c (patch) | |
tree | 374ae7035b294d9be78384b012ffbd864e00862b /source/blender/compositor | |
parent | bf75106ae98206795818d702102c94a94bfe32a6 (diff) |
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
Diffstat (limited to 'source/blender/compositor')
-rw-r--r-- | source/blender/compositor/operations/COM_ColorCorrectionOperation.cc | 80 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_ColorCorrectionOperation.h | 6 |
2 files changed, 84 insertions, 2 deletions
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 |