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
This commit is contained in:
parent
bf75106ae9
commit
0c90aa097d
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue