From 0c90aa097d0eb2f4faf91974113edb2b60599c9c Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Mon, 5 Jul 2021 21:02:22 +0200 Subject: 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 --- .../operations/COM_ColorCorrectionOperation.cc | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'source/blender/compositor/operations/COM_ColorCorrectionOperation.cc') 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; -- cgit v1.2.3