Commit: 376f84e244ee3f7cabfe9fa9faaa58063150d04b Author: Omar Emara Date: Thu Mar 31 16:20:21 2022 +0200 Branches: temp-viewport-compositor-compiler https://developer.blender.org/rB376f84e244ee3f7cabfe9fa9faaa58063150d04b
Viewport Compositor: Implement Filter node =================================================================== M source/blender/gpu/CMakeLists.txt A source/blender/gpu/shaders/compositor/compositor_filter.glsl A source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh M source/blender/nodes/composite/nodes/node_composite_filter.cc =================================================================== diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 349c5e57f34..469ea3ea037 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -310,6 +310,7 @@ set(GLSL_SRC shaders/compositor/material/gpu_shader_compositor_type_conversion.glsl shaders/compositor/compositor_convert.glsl + shaders/compositor/compositor_filter.glsl shaders/compositor/compositor_realize_on_domain.glsl shaders/compositor/compositor_split_viewer.glsl @@ -495,6 +496,7 @@ set(SHADER_CREATE_INFOS shaders/infos/gpu_srgb_to_framebuffer_space_info.hh shaders/compositor/infos/compositor_convert_info.hh + shaders/compositor/infos/compositor_filter_info.hh shaders/compositor/infos/compositor_realize_on_domain_info.hh shaders/compositor/infos/compositor_split_viewer_info.hh ) diff --git a/source/blender/gpu/shaders/compositor/compositor_filter.glsl b/source/blender/gpu/shaders/compositor/compositor_filter.glsl new file mode 100644 index 00000000000..b92a0644ff8 --- /dev/null +++ b/source/blender/gpu/shaders/compositor/compositor_filter.glsl @@ -0,0 +1,22 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utils.glsl) + +void main() +{ + ivec2 xy = ivec2(gl_GlobalInvocationID.xy); + + /* Compute the dot product between the kernel and the 3x3 window around the current pixel. */ + vec4 color = vec4(0); + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + color += texture_load(input_image, xy + ivec2(i - 1, j - 1)) * kernel[j][i]; + } + } + + /* Mix with the original color at the center of the kernel using the input factor. */ + color = mix(texture_load(input_image, xy), color, texture_load(factor, xy).x); + + /* Make sure the output is never negative. */ + color = max(color, 0.0); + + imageStore(output_image, xy, color); +} diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh new file mode 100644 index 00000000000..f55f8617b8a --- /dev/null +++ b/source/blender/gpu/shaders/compositor/infos/compositor_filter_info.hh @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2022 Blender Foundation. + * All rights reserved. + */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_filter) + .local_group_size(16, 16) + .push_constant(Type::MAT3, "kernel") + .sampler(0, ImageType::FLOAT_2D, "input_image") + .sampler(1, ImageType::FLOAT_2D, "factor") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_image") + .compute_source("compositor_filter.glsl") + .do_static_compilation(true); diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.cc b/source/blender/nodes/composite/nodes/node_composite_filter.cc index cd51e0d3c85..d5ba133d4aa 100644 --- a/source/blender/nodes/composite/nodes/node_composite_filter.cc +++ b/source/blender/nodes/composite/nodes/node_composite_filter.cc @@ -24,6 +24,12 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_compute.h" +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "NOD_compositor_execute.hh" + #include "node_composite_util.hh" /* **************** FILTER ******************** */ @@ -42,6 +48,146 @@ static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), Poi uiItemR(layout, ptr, "filter_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); } +using namespace blender::viewport_compositor; + +class FilterOperation : public NodeOperation { + public: + using NodeOperation::NodeOperation; + + void execute() override + { + GPUShader *shader = GPU_shader_create_from_info_name("compositor_filter"); + GPU_shader_bind(shader); + + float kernel[3][3]; + get_filter_kernel(kernel); + GPU_shader_uniform_mat3(shader, "kernel", kernel); + + const Result &input_image = get_input("Image"); + input_image.bind_as_texture(shader, "input_image"); + + const Result &factor = get_input("Fac"); + factor.bind_as_texture(shader, "factor"); + + Result &output_image = get_result("Image"); + output_image.allocate_texture(compute_domain()); + output_image.bind_as_image(shader, "output_image"); + + const int2 size = compute_domain().size; + GPU_compute_dispatch(shader, size.x / 16 + 1, size.y / 16 + 1, 1); + + input_image.unbind_as_texture(); + factor.unbind_as_texture(); + output_image.unbind_as_image(); + GPU_shader_unbind(); + GPU_shader_free(shader); + } + + int get_filter_method() + { + return node().custom1; + } + + void get_filter_kernel(float kernel[3][3]) + { + switch (get_filter_method()) { + case CMP_FILT_SOFT: + kernel[0][0] = 1.0f / 16.0f; + kernel[0][1] = 2.0f / 16.0f; + kernel[0][2] = 1.0f / 16.0f; + kernel[1][0] = 2.0f / 16.0f; + kernel[1][1] = 4.0f / 16.0f; + kernel[1][2] = 2.0f / 16.0f; + kernel[2][0] = 1.0f / 16.0f; + kernel[2][1] = 2.0f / 16.0f; + kernel[2][2] = 1.0f / 16.0f; + break; + case CMP_FILT_SHARP: + kernel[0][0] = -1.0f; + kernel[0][1] = -1.0f; + kernel[0][2] = -1.0f; + kernel[1][0] = -1.0f; + kernel[1][1] = 9.0f; + kernel[1][2] = -1.0f; + kernel[2][0] = -1.0f; + kernel[2][1] = -1.0f; + kernel[2][2] = -1.0f; + break; + case CMP_FILT_LAPLACE: + kernel[0][0] = -1.0f / 8.0f; + kernel[0][1] = -1.0f / 8.0f; + kernel[0][2] = -1.0f / 8.0f; + kernel[1][0] = -1.0f / 8.0f; + kernel[1][1] = 1.0f; + kernel[1][2] = -1.0f / 8.0f; + kernel[2][0] = -1.0f / 8.0f; + kernel[2][1] = -1.0f / 8.0f; + kernel[2][2] = -1.0f / 8.0f; + break; + case CMP_FILT_SOBEL: + kernel[0][0] = 1.0f; + kernel[0][1] = 0.0f; + kernel[0][2] = -1.0f; + kernel[1][0] = 2.0f; + kernel[1][1] = 0.0f; + kernel[1][2] = -2.0f; + kernel[2][0] = 1.0f; + kernel[2][1] = 0.0f; + kernel[2][2] = -1.0f; + break; + case CMP_FILT_PREWITT: + kernel[0][0] = 1.0f; + kernel[0][1] = 0.0f; + kernel[0][2] = -1.0f; + kernel[1][0] = 1.0f; + kernel[1][1] = 0.0f; + kernel[1][2] = -1.0f; + kernel[2][0] = 1.0f; + kernel[2][1] = 0.0f; + kernel[2][2] = -1.0f; + break; + case CMP_FILT_KIRSCH: + kernel[0][0] = 5.0f; + kernel[0][1] = -3.0f; + kernel[0][2] = -2.0f; + kernel[1][0] = 5.0f; + kernel[1][1] = -3.0f; + kernel[1][2] = -2.0f; + kernel[2][0] = 5.0f; + kernel[2][1] = -3.0f; + kernel[2][2] = -2.0f; + break; + case CMP_FILT_SHADOW: + kernel[0][0] = 1.0f; + kernel[0][1] = 0.0f; + kernel[0][2] = -1.0f; + kernel[1][0] = 2.0f; + kernel[1][1] = 1.0f; + kernel[1][2] = -2.0f; + kernel[2][0] = 1.0f; + kernel[2][1] = 0.0f; + kernel[2][2] = -1.0f; + break; + default: + kernel[0][0] = 0.0f; + kernel[0][1] = 0.0f; + kernel[0][2] = 0.0f; + kernel[1][0] = 0.0f; + kernel[1][1] = 1.0f; + kernel[1][2] = 0.0f; + kernel[2][0] = 0.0f; + kernel[2][1] = 0.0f; + kernel[2][2] = 0.0f; + break; + } + } +}; + +static NodeOperation *get_compositor_operation(Context &context, DNode node) +{ + return new FilterOperation(context, node); +} + } // namespace blender::nodes::node_composite_filter_cc void register_node_type_cmp_filter() @@ -54,6 +200,7 @@ void register_node_type_cmp_filter() ntype.declare = file_ns::cmp_node_filter_declare; ntype.draw_buttons = file_ns::node_composit_buts_filter; ntype.labelfunc = node_filter_label; + ntype.get_compositor_operation = file_ns::get_compositor_operation; ntype.flag |= NODE_PREVIEW; nodeRegisterType(&ntype); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs