Fix #147377: Glare Kernel is dependent on quality

The Kernel mode of the Glare node is dependent on the quality input of
the node. This patch makes it such that it is independent. This is down
by downsampling the kernel with the same amount the image was
downsampled.

Pull Request: https://projects.blender.org/blender/blender/pulls/147811
This commit is contained in:
Omar Emara
2025-10-10 16:52:15 +02:00
committed by Omar Emara
parent 4cb1564507
commit 42263644c1
4 changed files with 108 additions and 1 deletions

View File

@@ -261,6 +261,7 @@ set(GLSL_SRC
shaders/compositor_glare_ghost_accumulate.glsl
shaders/compositor_glare_ghost_base.glsl
shaders/compositor_glare_highlights.glsl
shaders/compositor_glare_kernel_downsample.glsl
shaders/compositor_glare_mix.glsl
shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl
shaders/compositor_glare_simple_star_diagonal_pass.glsl

View File

@@ -0,0 +1,11 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
void main()
{
int2 texel = int2(gl_GlobalInvocationID.xy);
const float2 normalized_coordinates = (float2(texel) + float2(0.5f)) /
float2(imageSize(output_img));
imageStore(output_img, texel, texture(input_tx, normalized_coordinates));
}

View File

@@ -193,3 +193,25 @@ DEFINE("JITTER")
PUSH_CONSTANT(float, jitter_factor)
DO_STATIC_COMPILATION()
GPU_SHADER_CREATE_END()
/* ------
* Kernel
* ------ */
GPU_SHADER_CREATE_INFO(compositor_glare_kernel_downsample_shared)
LOCAL_GROUP_SIZE(16, 16)
SAMPLER(0, sampler2D, input_tx)
COMPUTE_SOURCE("compositor_glare_kernel_downsample.glsl")
GPU_SHADER_CREATE_END()
GPU_SHADER_CREATE_INFO(compositor_glare_kernel_downsample_color)
ADDITIONAL_INFO(compositor_glare_kernel_downsample_shared)
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
DO_STATIC_COMPILATION()
GPU_SHADER_CREATE_END()
GPU_SHADER_CREATE_INFO(compositor_glare_kernel_downsample_float)
ADDITIONAL_INFO(compositor_glare_kernel_downsample_shared)
IMAGE(0, SFLOAT_16, write, image2D, output_img)
DO_STATIC_COMPILATION()
GPU_SHADER_CREATE_END()

View File

@@ -2424,10 +2424,83 @@ class GlareOperation : public NodeOperation {
}
return kernel_result;
}
convolve(this->context(), highlights, kernel, kernel_result, true);
if (this->get_quality() == CMP_NODE_GLARE_QUALITY_HIGH) {
convolve(this->context(), highlights, kernel, kernel_result, true);
}
else {
Result downsampled_kernel = this->downsample_kernel(kernel);
convolve(this->context(), highlights, downsampled_kernel, kernel_result, true);
downsampled_kernel.release();
}
return kernel_result;
}
Result downsample_kernel(const Result &kernel)
{
if (this->context().use_gpu()) {
return this->downsample_kernel_gpu(kernel);
}
return this->downsample_kernel_cpu(kernel);
}
Result downsample_kernel_cpu(const Result &kernel)
{
Result downsampled_kernel = this->context().create_result(kernel.type());
const int2 size = kernel.domain().size / this->get_quality_factor();
downsampled_kernel.allocate_texture(size);
if (kernel.type() == ResultType::Float) {
parallel_for(size, [&](const int2 texel) {
const float2 normalized_coordinates = (float2(texel) + float2(0.5f)) / float2(size);
downsampled_kernel.store_pixel(texel,
kernel.sample_bilinear_extended(normalized_coordinates).x);
});
}
else {
parallel_for(size, [&](const int2 texel) {
const float2 normalized_coordinates = (float2(texel) + float2(0.5f)) / float2(size);
downsampled_kernel.store_pixel(texel,
kernel.sample_bilinear_extended(normalized_coordinates));
});
}
return downsampled_kernel;
}
Result downsample_kernel_gpu(const Result &kernel)
{
Result downsampled_kernel = this->context().create_result(kernel.type());
const int2 size = kernel.domain().size / this->get_quality_factor();
downsampled_kernel.allocate_texture(size);
gpu::Shader *shader = context().get_shader(this->get_kernel_downsample_shader_name(kernel));
GPU_shader_bind(shader);
GPU_texture_filter_mode(kernel, true);
kernel.bind_as_texture(shader, "input_tx");
downsampled_kernel.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, size);
GPU_shader_unbind();
kernel.unbind_as_texture();
downsampled_kernel.unbind_as_image();
return downsampled_kernel;
}
const char *get_kernel_downsample_shader_name(const Result &kernel)
{
if (kernel.type() == ResultType::Float) {
return "compositor_glare_kernel_downsample_float";
}
return "compositor_glare_kernel_downsample_color";
}
const Result &get_kernel_input()
{
switch (this->get_kernel_data_type()) {