From db8b7a31f5d73b50d1e5bd39411da4a4e4ab284f Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Tue, 20 Feb 2024 09:19:48 +0200 Subject: [PATCH] Fix #118461: Compositor backdrop is only updated partially The compositor backdrop is only updated partially for the GPU compositor when the render percentage is less than 100. That's because the viewer node wrongly considered the compositing space, while its space is only affected by its input. So this patch fixes that by ignoring the compositing space for viewer nodes. --- .../composite/nodes/node_composite_viewer.cc | 78 +++++++++++++------ 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_viewer.cc index 82b8fe32bc0..c9eb30d0be2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.cc @@ -119,18 +119,28 @@ class ViewerOperation : public NodeOperation { ResultPrecision::Half); GPU_shader_bind(shader); - /* The compositing space might be limited to a smaller region of the output texture, so only - * write into that compositing region. */ - const rcti compositing_region = context().get_compositing_region(); - const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); - const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); - GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); - GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + const Domain domain = compute_domain(); + /* The context can use the composite output and thus has a dedicated viewer of an arbitrary + * size, so use the input in its entirety. Otherwise, no dedicated viewer exist so only write + * into the compositing region, which might be limited to a smaller region of the output + * texture. */ + if (context().use_composite_output()) { + GPU_shader_uniform_2iv(shader, "lower_bound", int2(0)); + GPU_shader_uniform_2iv(shader, "upper_bound", domain.size); + } + else { + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); + GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); + GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + } const Result &image = get_input("Image"); image.bind_as_texture(shader, "input_tx"); - const Domain domain = compute_domain(); GPUTexture *output_texture = context().get_viewer_output_texture(domain); const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); @@ -149,18 +159,28 @@ class ViewerOperation : public NodeOperation { GPUShader *shader = context().get_shader("compositor_write_output", ResultPrecision::Half); GPU_shader_bind(shader); - /* The compositing space might be limited to a smaller region of the output texture, so only - * write into that compositing region. */ - const rcti compositing_region = context().get_compositing_region(); - const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); - const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); - GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); - GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + const Domain domain = compute_domain(); + /* The context can use the composite output and thus has a dedicated viewer of an arbitrary + * size, so use the input in its entirety. Otherwise, no dedicated viewer exist so only write + * into the compositing region, which might be limited to a smaller region of the output + * texture. */ + if (context().use_composite_output()) { + GPU_shader_uniform_2iv(shader, "lower_bound", int2(0)); + GPU_shader_uniform_2iv(shader, "upper_bound", domain.size); + } + else { + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); + GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); + GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + } const Result &image = get_input("Image"); image.bind_as_texture(shader, "input_tx"); - const Domain domain = compute_domain(); GPUTexture *output_texture = context().get_viewer_output_texture(domain); const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); @@ -179,13 +199,24 @@ class ViewerOperation : public NodeOperation { ResultPrecision::Half); GPU_shader_bind(shader); - /* The compositing space might be limited to a smaller region of the output texture, so only - * write into that compositing region. */ - const rcti compositing_region = context().get_compositing_region(); - const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); - const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); - GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); - GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + const Domain domain = compute_domain(); + /* The context can use the composite output and thus has a dedicated viewer of an arbitrary + * size, so use the input in its entirety. Otherwise, no dedicated viewer exist so only write + * into the compositing region, which might be limited to a smaller region of the output + * texture. */ + if (context().use_composite_output()) { + GPU_shader_uniform_2iv(shader, "lower_bound", int2(0)); + GPU_shader_uniform_2iv(shader, "upper_bound", domain.size); + } + else { + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + const int2 upper_bound = int2(compositing_region.xmax, compositing_region.ymax); + GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); + GPU_shader_uniform_2iv(shader, "upper_bound", upper_bound); + } const Result &image = get_input("Image"); image.bind_as_texture(shader, "input_tx"); @@ -193,7 +224,6 @@ class ViewerOperation : public NodeOperation { const Result &alpha = get_input("Alpha"); alpha.bind_as_texture(shader, "alpha_tx"); - const Domain domain = compute_domain(); GPUTexture *output_texture = context().get_viewer_output_texture(domain); const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit);