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:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user