[Bf-blender-cvs] [fa85fded071] temp-viewport-compositor-compiler: Viewport Compositor: Implement movie clip node

Omar Emara noreply at git.blender.org
Wed Mar 30 21:04:06 CEST 2022


Commit: fa85fded071638200e8abefd230a3bf7ceed9d71
Author: Omar Emara
Date:   Wed Mar 30 21:03:35 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rBfa85fded071638200e8abefd230a3bf7ceed9d71

Viewport Compositor: Implement movie clip node

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

M	source/blender/nodes/composite/nodes/node_composite_movieclip.cc

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

diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc
index f6f00864839..8643ca56512 100644
--- a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc
@@ -21,8 +21,12 @@
  * \ingroup cmpnodes
  */
 
+#include "BLI_math_vec_types.hh"
+
 #include "BKE_context.h"
 #include "BKE_lib_id.h"
+#include "BKE_movieclip.h"
+
 #include "DNA_defaults.h"
 
 #include "RNA_access.h"
@@ -30,6 +34,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"
 
 namespace blender::nodes::node_composite_movieclip_cc {
@@ -95,6 +105,186 @@ static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, Point
   uiTemplateColorspaceSettings(layout, &clipptr, "colorspace_settings");
 }
 
+using namespace blender::viewport_compositor;
+
+class MovieClipOperation : public NodeOperation {
+ public:
+  using NodeOperation::NodeOperation;
+
+  void execute() override
+  {
+    GPUTexture *movie_clip_texture = get_movie_clip_texture();
+
+    compute_image(movie_clip_texture);
+    compute_alpha(movie_clip_texture);
+    compute_stabilization_data(movie_clip_texture);
+
+    free_movie_clip_texture();
+  }
+
+  void compute_image(GPUTexture *movie_clip_texture)
+  {
+    if (!is_output_needed("Image")) {
+      return;
+    }
+
+    Result &result = get_result("Image");
+
+    /* The movie clip texture is invalid or missing, set an appropriate fallback value. */
+    if (!movie_clip_texture) {
+      result.allocate_single_value();
+      result.set_color_value(float4(float3(0.0), 1.0f));
+      return;
+    }
+
+    const int width = GPU_texture_width(movie_clip_texture);
+    const int height = GPU_texture_height(movie_clip_texture);
+    result.allocate_texture(Domain(int2(width, height)));
+
+    /* The movie clip texture already has an appropriate half float format, so just copy. */
+    if (GPU_texture_format(movie_clip_texture) == GPU_RGBA16F) {
+      GPU_texture_copy(result.texture(), movie_clip_texture);
+      return;
+    }
+
+    GPUShader *shader = GPU_shader_create_from_info_name("compositor_convert_color_to_half_color");
+    GPU_shader_bind(shader);
+
+    const int input_unit = GPU_shader_get_texture_binding(shader, "input_sampler");
+    GPU_texture_bind(movie_clip_texture, input_unit);
+
+    result.bind_as_image(shader, "output_image");
+
+    GPU_compute_dispatch(shader, width / 16 + 1, height / 16 + 1, 1);
+
+    GPU_shader_unbind();
+    GPU_texture_unbind(movie_clip_texture);
+    result.unbind_as_image();
+    GPU_shader_free(shader);
+  }
+
+  void compute_alpha(GPUTexture *movie_clip_texture)
+  {
+    if (!is_output_needed("Alpha")) {
+      return;
+    }
+
+    Result &result = get_result("Alpha");
+
+    /* The movie clip texture is invalid or missing, set an appropriate fallback value. */
+    if (!movie_clip_texture) {
+      result.allocate_single_value();
+      result.set_float_value(1.0f);
+      return;
+    }
+
+    const int width = GPU_texture_width(movie_clip_texture);
+    const int height = GPU_texture_height(movie_clip_texture);
+    result.allocate_texture(Domain(int2(width, height)));
+
+    GPUShader *shader = GPU_shader_create_from_info_name("compositor_convert_color_to_alpha");
+    GPU_shader_bind(shader);
+
+    const int input_unit = GPU_shader_get_texture_binding(shader, "input_sampler");
+    GPU_texture_bind(movie_clip_texture, input_unit);
+
+    result.bind_as_image(shader, "output_image");
+
+    GPU_compute_dispatch(shader, width / 16 + 1, height / 16 + 1, 1);
+
+    GPU_shader_unbind();
+    GPU_texture_unbind(movie_clip_texture);
+    result.unbind_as_image();
+    GPU_shader_free(shader);
+  }
+
+  void compute_stabilization_data(GPUTexture *movie_clip_texture)
+  {
+    /* The movie clip texture is invalid or missing, set appropriate fallback values. */
+    if (!movie_clip_texture) {
+      if (is_output_needed("Offset X")) {
+        Result &result = get_result("Offset X");
+        result.allocate_single_value();
+        result.set_float_value(0.0f);
+      }
+      if (is_output_needed("Offset Y")) {
+        Result &result = get_result("Offset Y");
+        result.allocate_single_value();
+        result.set_float_value(0.0f);
+      }
+      if (is_output_needed("Scale")) {
+        Result &result = get_result("Scale");
+        result.allocate_single_value();
+        result.set_float_value(1.0f);
+      }
+      if (is_output_needed("Angle")) {
+        Result &result = get_result("Angle");
+        result.allocate_single_value();
+        result.set_float_value(0.0f);
+      }
+      return;
+    }
+
+    MovieClip *movie_clip = get_movie_clip();
+    const int frame_number = BKE_movieclip_remap_scene_to_clip_frame(
+        movie_clip, context().get_scene()->r.cfra);
+    const int width = GPU_texture_width(movie_clip_texture);
+    const int height = GPU_texture_height(movie_clip_texture);
+
+    /* If the movie clip has no stabilization data, it will initialize the given values with
+     * fallback values regardless, so no need to handle that case. */
+    float2 offset;
+    float scale, angle;
+    BKE_tracking_stabilization_data_get(
+        movie_clip, frame_number, width, height, offset, &scale, &angle);
+
+    if (is_output_needed("Offset X")) {
+      Result &result = get_result("Offset X");
+      result.allocate_single_value();
+      result.set_float_value(offset.x);
+    }
+    if (is_output_needed("Offset Y")) {
+      Result &result = get_result("Offset Y");
+      result.allocate_single_value();
+      result.set_float_value(offset.y);
+    }
+    if (is_output_needed("Scale")) {
+      Result &result = get_result("Scale");
+      result.allocate_single_value();
+      result.set_float_value(scale);
+    }
+    if (is_output_needed("Angle")) {
+      Result &result = get_result("Angle");
+      result.allocate_single_value();
+      result.set_float_value(angle);
+    }
+  }
+
+  GPUTexture *get_movie_clip_texture()
+  {
+    MovieClip *movie_clip = get_movie_clip();
+    MovieClipUser *movie_clip_user = static_cast<MovieClipUser *>(node().storage);
+    BKE_movieclip_user_set_frame(movie_clip_user, context().get_scene()->r.cfra);
+    return BKE_movieclip_get_gpu_texture(movie_clip, movie_clip_user);
+  }
+
+  void free_movie_clip_texture()
+  {
+    MovieClip *movie_clip = get_movie_clip();
+    return BKE_movieclip_free_gputexture(movie_clip);
+  }
+
+  MovieClip *get_movie_clip()
+  {
+    return (MovieClip *)node().id;
+  }
+};
+
+static NodeOperation *get_compositor_operation(Context &context, DNode node)
+{
+  return new MovieClipOperation(context, node);
+}
+
 }  // namespace blender::nodes::node_composite_movieclip_cc
 
 void register_node_type_cmp_movieclip()
@@ -107,6 +297,7 @@ void register_node_type_cmp_movieclip()
   ntype.declare = file_ns::cmp_node_movieclip_declare;
   ntype.draw_buttons = file_ns::node_composit_buts_movieclip;
   ntype.draw_buttons_ex = file_ns::node_composit_buts_movieclip_ex;
+  ntype.get_compositor_operation = file_ns::get_compositor_operation;
   ntype.initfunc_api = file_ns::init;
   ntype.flag |= NODE_PREVIEW;
   node_type_storage(



More information about the Bf-blender-cvs mailing list