[Bf-blender-cvs] [5877e33f230] temp-viewport-compositor-merge: Viewport Compositor: Add ellipse mask node

Omar Emara noreply at git.blender.org
Fri May 20 16:43:30 CEST 2022


Commit: 5877e33f2309b53eca1f8777a1da968de7f64ac4
Author: Omar Emara
Date:   Fri May 20 16:27:46 2022 +0200
Branches: temp-viewport-compositor-merge
https://developer.blender.org/rB5877e33f2309b53eca1f8777a1da968de7f64ac4

Viewport Compositor: Add ellipse mask node

===================================================================

M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
A	source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
M	source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index bf2f52dfa7a..fac4d1dd983 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -315,6 +315,7 @@ set(GLSL_SRC
   shaders/compositor/compositor_alpha_crop.glsl
   shaders/compositor/compositor_blur.glsl
   shaders/compositor/compositor_convert.glsl
+  shaders/compositor/compositor_ellipse_mask.glsl
   shaders/compositor/compositor_filter.glsl
   shaders/compositor/compositor_flip.glsl
   shaders/compositor/compositor_image_crop.glsl
@@ -555,6 +556,7 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/compositor/infos/compositor_alpha_crop_info.hh
   shaders/compositor/infos/compositor_blur_info.hh
   shaders/compositor/infos/compositor_convert_info.hh
+  shaders/compositor/infos/compositor_ellipse_mask_info.hh
   shaders/compositor/infos/compositor_filter_info.hh
   shaders/compositor/infos/compositor_flip_info.hh
   shaders/compositor/infos/compositor_image_crop_info.hh
diff --git a/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl b/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
new file mode 100644
index 00000000000..86fb951445f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_ellipse_mask.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 xy = ivec2(gl_GlobalInvocationID.xy);
+
+  vec2 uv = vec2(xy) / vec2(domain_size - ivec2(1));
+  uv -= location;
+  uv.y *= float(domain_size.y) / float(domain_size.x);
+  uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv;
+  bool is_inside = length(uv / radius) < 1.0;
+
+  float base_mask_value = texture_load(base_mask, xy).x;
+  float value = texture_load(mask_value, xy).x;
+
+#if defined(CMP_NODE_MASKTYPE_ADD)
+  float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_SUBTRACT)
+  float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_MULTIPLY)
+  float output_mask_value = is_inside ? base_mask_value * value : 0.0;
+#elif defined(CMP_NODE_MASKTYPE_NOT)
+  float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value;
+#endif
+
+  imageStore(output_mask, xy, vec4(output_mask_value));
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
new file mode 100644
index 00000000000..dbb1e2a240a
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_ellipse_mask_info.hh
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_shared)
+    .local_group_size(16, 16)
+    .push_constant(Type::IVEC2, "domain_size")
+    .push_constant(Type::VEC2, "location")
+    .push_constant(Type::VEC2, "radius")
+    .push_constant(Type::FLOAT, "cos_angle")
+    .push_constant(Type::FLOAT, "sin_angle")
+    .sampler(0, ImageType::FLOAT_2D, "base_mask")
+    .sampler(1, ImageType::FLOAT_2D, "mask_value")
+    .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask")
+    .compute_source("compositor_ellipse_mask.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_add)
+    .additional_info("compositor_ellipse_mask_shared")
+    .define("CMP_NODE_MASKTYPE_ADD")
+    .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_subtract)
+    .additional_info("compositor_ellipse_mask_shared")
+    .define("CMP_NODE_MASKTYPE_SUBTRACT")
+    .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_multiply)
+    .additional_info("compositor_ellipse_mask_shared")
+    .define("CMP_NODE_MASKTYPE_MULTIPLY")
+    .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_not)
+    .additional_info("compositor_ellipse_mask_shared")
+    .define("CMP_NODE_MASKTYPE_NOT")
+    .do_static_compilation(true);
diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
index 3aec9f6c01a..42f776bbdc1 100644
--- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc
@@ -5,10 +5,17 @@
  * \ingroup cmpnodes
  */
 
+#include <cmath>
+
+#include "BLI_math_vec_types.hh"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 
-#include "VPC_unsupported_node_operation.hh"
+#include "GPU_shader.h"
+
+#include "VPC_node_operation.hh"
+#include "VPC_utilities.hh"
 
 #include "node_composite_util.hh"
 
@@ -50,9 +57,94 @@ static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C)
 
 using namespace blender::viewport_compositor;
 
+class EllipseMaskOperation : public NodeOperation {
+ public:
+  using NodeOperation::NodeOperation;
+
+  void execute() override
+  {
+    GPUShader *shader = shader_pool().acquire(get_shader_name());
+    GPU_shader_bind(shader);
+
+    const Domain domain = compute_domain();
+
+    GPU_shader_uniform_2iv(shader, "domain_size", domain.size);
+
+    GPU_shader_uniform_2fv(shader, "location", get_location());
+    GPU_shader_uniform_2fv(shader, "radius", get_size() / 2.0f);
+    GPU_shader_uniform_1f(shader, "cos_angle", std::cos(get_angle()));
+    GPU_shader_uniform_1f(shader, "sin_angle", std::sin(get_angle()));
+
+    const Result &input_mask = get_input("Mask");
+    input_mask.bind_as_texture(shader, "base_mask");
+
+    const Result &value = get_input("Value");
+    value.bind_as_texture(shader, "mask_value");
+
+    Result &output_mask = get_result("Mask");
+    output_mask.allocate_texture(domain);
+    output_mask.bind_as_image(shader, "output_mask");
+
+    compute_dispatch_global(shader, domain.size);
+
+    input_mask.unbind_as_texture();
+    value.unbind_as_texture();
+    output_mask.unbind_as_image();
+    GPU_shader_unbind();
+  }
+
+  Domain compute_domain() override
+  {
+    if (get_input("Mask").is_single_value()) {
+      return Domain(context().get_viewport_size());
+    }
+    return get_input("Mask").domain();
+  }
+
+  int get_mask_type()
+  {
+    return bnode().custom1;
+  }
+
+  const char *get_shader_name()
+  {
+    switch (get_mask_type()) {
+      default:
+      case CMP_NODE_MASKTYPE_ADD:
+        return "compositor_ellipse_mask_add";
+      case CMP_NODE_MASKTYPE_SUBTRACT:
+        return "compositor_ellipse_mask_subtract";
+      case CMP_NODE_MASKTYPE_MULTIPLY:
+        return "compositor_ellipse_mask_multiply";
+      case CMP_NODE_MASKTYPE_NOT:
+        return "compositor_ellipse_mask_not";
+    }
+  }
+
+  NodeEllipseMask &get_node_ellipse_mask()
+  {
+    return *static_cast<NodeEllipseMask *>(bnode().storage);
+  }
+
+  float2 get_location()
+  {
+    return float2(get_node_ellipse_mask().x, get_node_ellipse_mask().y);
+  }
+
+  float2 get_size()
+  {
+    return float2(get_node_ellipse_mask().width, get_node_ellipse_mask().height);
+  }
+
+  float get_angle()
+  {
+    return get_node_ellipse_mask().rotation;
+  }
+};
+
 static NodeOperation *get_compositor_operation(Context &context, DNode node)
 {
-  return new UnsupportedNodeOperation(context, node);
+  return new EllipseMaskOperation(context, node);
 }
 
 }  // namespace blender::nodes::node_composite_ellipsemask_cc



More information about the Bf-blender-cvs mailing list