Fix #121639: Glare shifts the colors of highlights
The Glare node shifts the color of the highlights when the threshold is high. That's because the thresholding algorithm simply subtracts the threshold from the RGB data, which is not expected to retain the same hue of the color. To fix this, we do the thresholding only on the luminance of the color in HSV color space. This eliminates the color shifting and also helps to smooth the edges of the highlights. This is a breaking change, but it is more of a fix rather than a change of behavior. Pull Request: https://projects.blender.org/blender/blender/pulls/122570
This commit is contained in:
parent
9ad2c7df0b
commit
4f21b26675
@ -2,6 +2,10 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "COM_GlareThresholdOperation.h"
|
||||
|
||||
#include "IMB_colormanagement.hh"
|
||||
@ -31,17 +35,14 @@ void GlareThresholdOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
||||
{
|
||||
const float threshold = settings_->threshold;
|
||||
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
|
||||
const float *color = it.in(0);
|
||||
if (IMB_colormanagement_get_luminance(color) >= threshold) {
|
||||
it.out[0] = color[0] - threshold;
|
||||
it.out[1] = color[1] - threshold;
|
||||
it.out[2] = color[2] - threshold;
|
||||
float4 hsva;
|
||||
rgb_to_hsv_v(it.in(0), hsva);
|
||||
|
||||
CLAMP3_MIN(it.out, 0.0f);
|
||||
}
|
||||
else {
|
||||
zero_v3(it.out);
|
||||
}
|
||||
hsva.z = math::max(0.0f, hsva.z - threshold);
|
||||
|
||||
hsv_to_rgb_v(hsva, it.out);
|
||||
CLAMP3_MIN(it.out, 0.0f);
|
||||
it.out[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
/* The dispatch domain covers the output image size, which might be a fraction of the input image
|
||||
@ -13,14 +15,16 @@ void main()
|
||||
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||
vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / vec2(imageSize(output_img));
|
||||
|
||||
vec4 input_color = texture(input_tx, normalized_coordinates);
|
||||
float luminance = dot(input_color.rgb, luminance_coefficients);
|
||||
vec4 hsva;
|
||||
rgb_to_hsv(texture(input_tx, normalized_coordinates), hsva);
|
||||
|
||||
/* The pixel whose luminance is less than the threshold luminance is not considered part of the
|
||||
* highlights and is given a value of zero. Otherwise, the pixel is considered part of the
|
||||
* highlights, whose value is the difference to the threshold value clamped to zero. */
|
||||
bool is_highlights = luminance >= threshold;
|
||||
vec3 highlights = is_highlights ? max(vec3(0.0), input_color.rgb - threshold) : vec3(0.0);
|
||||
/* The pixel whose luminance value is less than the threshold luminance is not considered part of
|
||||
* the highlights and is given a value of zero. Otherwise, the pixel is considered part of the
|
||||
* highlights, whose luminance value is the difference to the threshold. */
|
||||
hsva.z = max(0.0, hsva.z - threshold);
|
||||
|
||||
imageStore(output_img, texel, vec4(highlights, 1.0));
|
||||
vec4 rgba;
|
||||
hsv_to_rgb(hsva, rgba);
|
||||
|
||||
imageStore(output_img, texel, vec4(rgba.rgb, 1.0));
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
GPU_SHADER_CREATE_INFO(compositor_glare_highlights)
|
||||
.local_group_size(16, 16)
|
||||
.push_constant(Type::FLOAT, "threshold")
|
||||
.push_constant(Type::VEC3, "luminance_coefficients")
|
||||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.compute_source("compositor_glare_highlights.glsl")
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
#include "IMB_colormanagement.hh"
|
||||
|
||||
#include "GPU_shader.hh"
|
||||
#include "GPU_state.hh"
|
||||
#include "GPU_texture.hh"
|
||||
@ -182,9 +180,6 @@ class GlareOperation : public NodeOperation {
|
||||
GPUShader *shader = context().get_shader("compositor_glare_highlights");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
float luminance_coefficients[3];
|
||||
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
|
||||
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
|
||||
GPU_shader_uniform_1f(shader, "threshold", node_storage(bnode()).threshold);
|
||||
|
||||
const Result &input_image = get_input("Image");
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 90695d0404b7cb675e1da9f778aa51b00028dd61
|
||||
Subproject commit 363d42173a72ff8e9d0bc7c3be17b9739559b74c
|
Loading…
Reference in New Issue
Block a user