[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