Compositor: Perform LGG Color Balance in linear space
This patch adjusts the LGG Color Balance mode to operate in linear space as opposed to sRGB space, which is more inline with other software and is more expected to the user. Versioning was added using pre and post gamma correction, but it is very slightly different in the blacks because the gamma node only does power correction. Pull Request: https://projects.blender.org/blender/blender/pulls/147533
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 102
|
||||
#define BLENDER_FILE_SUBVERSION 103
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -2498,6 +2498,85 @@ static void sequencer_substitute_transform_effects(Scene *scene)
|
||||
});
|
||||
}
|
||||
|
||||
/* The LGG mode of the Color Balance node was being done in sRGB space, while now it is done in
|
||||
* linear space. So a Gamma node will be added before and after the node to perform the adjustment
|
||||
* in sRGB space. */
|
||||
static void do_version_lift_gamma_gain_srgb_to_linear(bNodeTree &node_tree, bNode &node)
|
||||
{
|
||||
bNodeSocket *image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image");
|
||||
bNodeSocket *type_input = blender::bke::node_find_socket(node, SOCK_IN, "Type");
|
||||
bNodeSocket *image_output = blender::bke::node_find_socket(node, SOCK_OUT, "Image");
|
||||
|
||||
/* Find the links going into and out of of the node. */
|
||||
bNodeLink *image_input_link = nullptr;
|
||||
bNodeLink *type_input_link = nullptr;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
|
||||
if (link->tosock == image_input) {
|
||||
image_input_link = link;
|
||||
}
|
||||
if (link->tosock == type_input) {
|
||||
type_input_link = link;
|
||||
}
|
||||
}
|
||||
|
||||
if (type_input_link || !type_input ||
|
||||
type_input->default_value_typed<bNodeSocketValueMenu>()->value != CMP_NODE_COLOR_BALANCE_LGG)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bNode *inverse_gamma_node = blender::bke::node_add_static_node(
|
||||
nullptr, node_tree, SH_NODE_GAMMA);
|
||||
inverse_gamma_node->parent = node.parent;
|
||||
inverse_gamma_node->location[0] = node.location[0];
|
||||
inverse_gamma_node->location[1] = node.location[1];
|
||||
|
||||
bNodeSocket *inverse_gamma_color_input = blender::bke::node_find_socket(
|
||||
*inverse_gamma_node, SOCK_IN, "Color");
|
||||
copy_v4_v4(inverse_gamma_color_input->default_value_typed<bNodeSocketValueRGBA>()->value,
|
||||
image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
|
||||
bNodeSocket *inverse_gamma_color_output = blender::bke::node_find_socket(
|
||||
*inverse_gamma_node, SOCK_OUT, "Color");
|
||||
|
||||
bNodeSocket *inverse_gamma_input = blender::bke::node_find_socket(
|
||||
*inverse_gamma_node, SOCK_IN, "Gamma");
|
||||
inverse_gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 1.0f / 2.2f;
|
||||
|
||||
version_node_add_link(
|
||||
node_tree, *inverse_gamma_node, *inverse_gamma_color_output, node, *image_input);
|
||||
if (image_input_link) {
|
||||
version_node_add_link(node_tree,
|
||||
*image_input_link->fromnode,
|
||||
*image_input_link->fromsock,
|
||||
*inverse_gamma_node,
|
||||
*inverse_gamma_color_input);
|
||||
blender::bke::node_remove_link(&node_tree, *image_input_link);
|
||||
}
|
||||
|
||||
bNode *gamma_node = blender::bke::node_add_static_node(nullptr, node_tree, SH_NODE_GAMMA);
|
||||
gamma_node->parent = node.parent;
|
||||
gamma_node->location[0] = node.location[0];
|
||||
gamma_node->location[1] = node.location[1];
|
||||
|
||||
bNodeSocket *gamma_color_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Color");
|
||||
bNodeSocket *gamma_color_output = blender::bke::node_find_socket(*gamma_node, SOCK_OUT, "Color");
|
||||
|
||||
bNodeSocket *gamma_input = blender::bke::node_find_socket(*gamma_node, SOCK_IN, "Gamma");
|
||||
gamma_input->default_value_typed<bNodeSocketValueFloat>()->value = 2.2f;
|
||||
|
||||
LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree.links) {
|
||||
if (link->fromsock != image_output) {
|
||||
continue;
|
||||
}
|
||||
|
||||
version_node_add_link(
|
||||
node_tree, *gamma_node, *gamma_color_output, *link->tonode, *link->tosock);
|
||||
blender::bke::node_remove_link(&node_tree, *link);
|
||||
}
|
||||
|
||||
version_node_add_link(node_tree, node, *image_output, *gamma_node, *gamma_color_input);
|
||||
}
|
||||
|
||||
void do_versions_after_linking_500(FileData *fd, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 9)) {
|
||||
@@ -3826,6 +3905,19 @@ void blo_do_versions_500(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 103)) {
|
||||
FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
|
||||
if (node_tree->type == NTREE_COMPOSIT) {
|
||||
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
|
||||
if (node->type_legacy == CMP_NODE_COLORBALANCE) {
|
||||
do_version_lift_gamma_gain_srgb_to_linear(*node_tree, *node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_common_color_utils.glsl"
|
||||
#include "gpu_shader_math_matrix_construct_lib.glsl"
|
||||
|
||||
#define CMP_NODE_COLOR_BALANCE_LGG 0
|
||||
@@ -17,19 +16,14 @@ float4 lift_gamma_gain(const float4 color,
|
||||
const float base_gain,
|
||||
const float4 color_gain)
|
||||
{
|
||||
const float3 srgb_color = linear_rgb_to_srgb(color.rgb);
|
||||
|
||||
const float3 lift = base_lift + color_lift.xyz();
|
||||
const float3 lift_balanced = ((srgb_color - 1.0f) * (2.0f - lift)) + 1.0f;
|
||||
const float3 lift_balanced = ((color.xyz() - 1.0f) * (2.0f - lift)) + 1.0f;
|
||||
|
||||
const float3 gain = base_gain * color_gain.xyz();
|
||||
float3 gain_balanced = lift_balanced * gain;
|
||||
gain_balanced = max(gain_balanced, float3(0.0f));
|
||||
|
||||
float3 linear_color = srgb_to_linear_rgb(gain_balanced);
|
||||
const float3 gain_balanced = max(float3(0.0f), lift_balanced * gain);
|
||||
|
||||
const float3 gamma = base_gamma * color_gamma.xyz();
|
||||
float3 gamma_balanced = pow(linear_color, 1.0f / max(gamma, float3(1e-6)));
|
||||
const float3 gamma_balanced = pow(gain_balanced, 1.0f / max(gamma, float3(1e-6)));
|
||||
|
||||
return float4(gamma_balanced, color.w);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
@@ -245,21 +244,14 @@ static float4 lift_gamma_gain(const float4 color,
|
||||
const float base_gain,
|
||||
const float4 color_gain)
|
||||
{
|
||||
float3 srgb_color;
|
||||
linearrgb_to_srgb_v3_v3(srgb_color, color);
|
||||
|
||||
const float3 lift = base_lift + color_lift.xyz();
|
||||
const float3 lift_balanced = ((srgb_color - 1.0f) * (2.0f - lift)) + 1.0f;
|
||||
const float3 lift_balanced = ((color.xyz() - 1.0f) * (2.0f - lift)) + 1.0f;
|
||||
|
||||
const float3 gain = base_gain * color_gain.xyz();
|
||||
float3 gain_balanced = lift_balanced * gain;
|
||||
gain_balanced = math::max(gain_balanced, float3(0.0f));
|
||||
|
||||
float3 linear_color;
|
||||
srgb_to_linearrgb_v3_v3(linear_color, gain_balanced);
|
||||
const float3 gain_balanced = math::max(float3(0.0f), lift_balanced * gain);
|
||||
|
||||
const float3 gamma = base_gamma * color_gamma.xyz();
|
||||
float3 gamma_balanced = math::pow(linear_color, 1.0f / math::max(gamma, float3(1e-6f)));
|
||||
const float3 gamma_balanced = math::pow(gain_balanced, 1.0f / math::max(gamma, float3(1e-6f)));
|
||||
|
||||
return float4(gamma_balanced, color.w);
|
||||
}
|
||||
|
||||
BIN
tests/files/compositor/color/compositor_renders/node_color_balance_lift.png
(Stored with Git LFS)
BIN
tests/files/compositor/color/compositor_renders/node_color_balance_lift.png
(Stored with Git LFS)
Binary file not shown.
BIN
tests/files/compositor/pixel_nodes/compositor_renders/consecutive_pixel_nodes.png
(Stored with Git LFS)
BIN
tests/files/compositor/pixel_nodes/compositor_renders/consecutive_pixel_nodes.png
(Stored with Git LFS)
Binary file not shown.
BIN
tests/files/compositor/pixel_nodes/compositor_renders/pixel_and_non_pixel_nodes.png
(Stored with Git LFS)
BIN
tests/files/compositor/pixel_nodes/compositor_renders/pixel_and_non_pixel_nodes.png
(Stored with Git LFS)
Binary file not shown.
Reference in New Issue
Block a user