diff --git a/scripts/startup/bl_ui/node_add_menu_compositor.py b/scripts/startup/bl_ui/node_add_menu_compositor.py index c97bf7f09c3..dc974fc951f 100644 --- a/scripts/startup/bl_ui/node_add_menu_compositor.py +++ b/scripts/startup/bl_ui/node_add_menu_compositor.py @@ -150,7 +150,6 @@ class NODE_MT_category_compositor_filter(Menu): node_add_menu.add_node_type(layout, "CompositorNodeKuwahara") node_add_menu.add_node_type(layout, "CompositorNodePixelate") node_add_menu.add_node_type(layout, "CompositorNodePosterize") - node_add_menu.add_node_type(layout, "CompositorNodeSunBeams") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 2a9b99c1db1..c82121e3dc8 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 56 +#define BLENDER_FILE_SUBVERSION 57 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenkernel/BKE_node_legacy_types.hh b/source/blender/blenkernel/BKE_node_legacy_types.hh index 553c25d1d7d..cb9f6a15fe1 100644 --- a/source/blender/blenkernel/BKE_node_legacy_types.hh +++ b/source/blender/blenkernel/BKE_node_legacy_types.hh @@ -228,7 +228,7 @@ #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 #define CMP_NODE_LENSDIST 303 -#define CMP_NODE_SUNBEAMS 304 +#define CMP_NODE_SUNBEAMS_DEPRECATED 304 #define CMP_NODE_COLORCORRECTION 312 #define CMP_NODE_MASK_BOX 313 diff --git a/source/blender/blenloader/intern/versioning_450.cc b/source/blender/blenloader/intern/versioning_450.cc index bb2ea31fb75..b39fad228e2 100644 --- a/source/blender/blenloader/intern/versioning_450.cc +++ b/source/blender/blenloader/intern/versioning_450.cc @@ -4606,7 +4606,7 @@ void do_versions_after_linking_450(FileData * /*fd*/, Main *bmain) FOREACH_NODETREE_BEGIN (bmain, node_tree, id) { if (node_tree->type == NTREE_COMPOSIT) { LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) { - if (node->type_legacy == CMP_NODE_SUNBEAMS) { + if (node->type_legacy == CMP_NODE_SUNBEAMS_DEPRECATED) { do_version_sun_beams_node_options_to_inputs_animation(node_tree, node); } } @@ -5637,7 +5637,7 @@ void blo_do_versions_450(FileData * /*fd*/, Library * /*lib*/, Main *bmain) FOREACH_NODETREE_BEGIN (bmain, node_tree, id) { if (node_tree->type == NTREE_COMPOSIT) { LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) { - if (node->type_legacy == CMP_NODE_SUNBEAMS) { + if (node->type_legacy == CMP_NODE_SUNBEAMS_DEPRECATED) { do_version_sun_beams_node_options_to_inputs(node_tree, node); } } diff --git a/source/blender/blenloader/intern/versioning_500.cc b/source/blender/blenloader/intern/versioning_500.cc index 17bd9bfb88e..7f7be2e09a7 100644 --- a/source/blender/blenloader/intern/versioning_500.cc +++ b/source/blender/blenloader/intern/versioning_500.cc @@ -1347,6 +1347,69 @@ static void do_version_convert_gp_jitter_values(Brush *brush) } } +/* The Sun beams node was removed and the Glare node should be used instead, so we need to + * make the replacement. */ +static void do_version_sun_beams(bNodeTree &node_tree, bNode &node) +{ + blender::bke::node_tree_set_type(node_tree); + + bNodeSocket *old_image_input = blender::bke::node_find_socket(node, SOCK_IN, "Image"); + bNodeSocket *old_source_input = blender::bke::node_find_socket(node, SOCK_IN, "Source"); + bNodeSocket *old_length_input = blender::bke::node_find_socket(node, SOCK_IN, "Length"); + bNodeSocket *old_image_output = blender::bke::node_find_socket(node, SOCK_OUT, "Image"); + + bNode *glare_node = blender::bke::node_add_node(nullptr, node_tree, "CompositorNodeGlare"); + static_cast(glare_node->storage)->type = CMP_NODE_GLARE_SUN_BEAMS; + static_cast(glare_node->storage)->quality = 0; + glare_node->parent = node.parent; + glare_node->location[0] = node.location[0]; + glare_node->location[1] = node.location[1]; + + bNodeSocket *image_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Image"); + bNodeSocket *threshold_input = blender::bke::node_find_socket( + *glare_node, SOCK_IN, "Highlights Threshold"); + bNodeSocket *size_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Size"); + bNodeSocket *source_input = blender::bke::node_find_socket(*glare_node, SOCK_IN, "Sun Position"); + bNodeSocket *glare_output = blender::bke::node_find_socket(*glare_node, SOCK_OUT, "Glare"); + + copy_v4_v4(image_input->default_value_typed()->value, + old_image_input->default_value_typed()->value); + threshold_input->default_value_typed()->value = 0.0f; + size_input->default_value_typed()->value = + old_length_input->default_value_typed()->value; + copy_v2_v2(source_input->default_value_typed()->value, + old_source_input->default_value_typed()->value); + + LISTBASE_FOREACH_BACKWARD_MUTABLE (bNodeLink *, link, &node_tree.links) { + if (link->tosock == old_image_input) { + version_node_add_link( + node_tree, *link->fromnode, *link->fromsock, *glare_node, *image_input); + blender::bke::node_remove_link(&node_tree, *link); + continue; + } + + if (link->tosock == old_source_input) { + version_node_add_link( + node_tree, *link->fromnode, *link->fromsock, *glare_node, *source_input); + blender::bke::node_remove_link(&node_tree, *link); + continue; + } + + if (link->tosock == old_length_input) { + version_node_add_link(node_tree, *link->fromnode, *link->fromsock, *glare_node, *size_input); + blender::bke::node_remove_link(&node_tree, *link); + continue; + } + + if (link->fromsock == old_image_output) { + version_node_add_link(node_tree, *link->tonode, *link->tosock, *glare_node, *glare_output); + blender::bke::node_remove_link(&node_tree, *link); + } + } + + version_node_remove(node_tree, node); +} + /* The Composite node was removed and a Group Output node should be used instead, so we need to * make the replacement. But first note that the Group Output node relies on the node tree * interface, so we ensure a default interface with a single input and output. This is only for @@ -1602,6 +1665,19 @@ void do_versions_after_linking_500(FileData *fd, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 57)) { + FOREACH_NODETREE_BEGIN (bmain, node_tree, id) { + if (node_tree->type == NTREE_COMPOSIT) { + LISTBASE_FOREACH_BACKWARD_MUTABLE (bNode *, node, &node_tree->nodes) { + if (node->type_legacy == CMP_NODE_SUNBEAMS_DEPRECATED) { + do_version_sun_beams(*node_tree, *node); + } + } + } + } + FOREACH_NODETREE_END; + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. @@ -1970,8 +2046,8 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain) } } - /* ImageFormatData gained a new media type which we need to be set according to the existing - * imtype. */ + /* ImageFormatData gained a new media type which we need to be set according to the + * existing imtype. */ if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 42)) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { update_format_media_type(&scene->r.im_format); @@ -2215,8 +2291,8 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain) * \note Keep this message at the bottom of the function. */ - /* Keep this versioning always enabled at the bottom of the function; it can only be moved behind - * a subversion bump when the file format is changed. */ + /* Keep this versioning always enabled at the bottom of the function; it can only be moved + * behind a subversion bump when the file format is changed. */ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { bke::mesh_freestyle_marks_to_generic(*mesh); } diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index e105205f63f..9c5bb9a3237 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -202,6 +202,7 @@ set(GLSL_SRC shaders/compositor_glare_simple_star_vertical_pass.glsl shaders/compositor_glare_streaks_accumulate.glsl shaders/compositor_glare_streaks_filter.glsl + shaders/compositor_glare_sun_beams.glsl shaders/compositor_glare_write_glare_output.glsl shaders/compositor_glare_write_highlights_output.glsl shaders/compositor_horizontal_lens_distortion.glsl @@ -256,7 +257,6 @@ set(GLSL_SRC shaders/compositor_summed_area_table_compute_complete_x_prologues.glsl shaders/compositor_summed_area_table_compute_complete_y_prologues.glsl shaders/compositor_summed_area_table_compute_incomplete_prologues.glsl - shaders/compositor_sun_beams.glsl shaders/compositor_symmetric_blur.glsl shaders/compositor_symmetric_blur_variable_size.glsl shaders/compositor_symmetric_separable_blur.glsl diff --git a/source/blender/compositor/shaders/compositor_sun_beams.glsl b/source/blender/compositor/shaders/compositor_glare_sun_beams.glsl similarity index 100% rename from source/blender/compositor/shaders/compositor_sun_beams.glsl rename to source/blender/compositor/shaders/compositor_glare_sun_beams.glsl diff --git a/source/blender/compositor/shaders/infos/compositor_glare_info.hh b/source/blender/compositor/shaders/infos/compositor_glare_info.hh index fc7852e07ec..b02da6f1ed9 100644 --- a/source/blender/compositor/shaders/infos/compositor_glare_info.hh +++ b/source/blender/compositor/shaders/infos/compositor_glare_info.hh @@ -168,3 +168,17 @@ IMAGE(0, SFLOAT_16_16_16_16, read_write, image2D, output_img) COMPUTE_SOURCE("compositor_glare_bloom_upsample.glsl") DO_STATIC_COMPILATION() GPU_SHADER_CREATE_END() + +/* ----- + * Sun Beams + * ----- */ + +GPU_SHADER_CREATE_INFO(compositor_glare_sun_beams) +LOCAL_GROUP_SIZE(16, 16) +PUSH_CONSTANT(float2, source) +PUSH_CONSTANT(int, max_steps) +SAMPLER(0, sampler2D, input_tx) +IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img) +COMPUTE_SOURCE("compositor_glare_sun_beams.glsl") +DO_STATIC_COMPILATION() +GPU_SHADER_CREATE_END() diff --git a/source/blender/compositor/shaders/infos/compositor_sun_beams_info.hh b/source/blender/compositor/shaders/infos/compositor_sun_beams_info.hh deleted file mode 100644 index 77ae2ebbcd5..00000000000 --- a/source/blender/compositor/shaders/infos/compositor_sun_beams_info.hh +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "gpu_shader_create_info.hh" - -GPU_SHADER_CREATE_INFO(compositor_sun_beams) -LOCAL_GROUP_SIZE(16, 16) -PUSH_CONSTANT(float2, source) -PUSH_CONSTANT(int, max_steps) -SAMPLER(0, sampler2D, input_tx) -IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img) -COMPUTE_SOURCE("compositor_sun_beams.glsl") -DO_STATIC_COMPILATION() -GPU_SHADER_CREATE_END() diff --git a/source/blender/gpu/intern/gpu_shader_create_info_list.hh b/source/blender/gpu/intern/gpu_shader_create_info_list.hh index 796066b03ed..935d4e9be6d 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info_list.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info_list.hh @@ -102,7 +102,6 @@ #include "compositor_smaa_info.hh" #include "compositor_split_info.hh" #include "compositor_summed_area_table_info.hh" -#include "compositor_sun_beams_info.hh" #include "compositor_symmetric_blur_info.hh" #include "compositor_symmetric_blur_variable_size_info.hh" #include "compositor_symmetric_separable_blur_info.hh" diff --git a/source/blender/makesrna/intern/rna_nodetree.cc b/source/blender/makesrna/intern/rna_nodetree.cc index 9eda06d54a7..b8176b8968c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.cc +++ b/source/blender/makesrna/intern/rna_nodetree.cc @@ -10592,7 +10592,6 @@ static void rna_def_nodes(BlenderRNA *brna) define("CompositorNode", "CompositorNodeSetAlpha", def_cmp_set_alpha); define("CompositorNode", "CompositorNodeSplit", def_cmp_split); define("CompositorNode", "CompositorNodeStabilize", def_cmp_stabilize2d); - define("CompositorNode", "CompositorNodeSunBeams"); define("CompositorNode", "CompositorNodeSwitch"); define("CompositorNode", "CompositorNodeSwitchView"); define("CompositorNode", "CompositorNodeTime", def_time); diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt index ec59734988d..9ab328227c9 100644 --- a/source/blender/nodes/composite/CMakeLists.txt +++ b/source/blender/nodes/composite/CMakeLists.txt @@ -95,7 +95,6 @@ set(SRC nodes/node_composite_setalpha.cc nodes/node_composite_split.cc nodes/node_composite_stabilize2d.cc - nodes/node_composite_sunbeams.cc nodes/node_composite_switch.cc nodes/node_composite_switchview.cc nodes/node_composite_tonemap.cc diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index eb857a98cfc..c282921dccf 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -2247,7 +2247,7 @@ class GlareOperation : public NodeOperation { Result execute_sun_beams_gpu(Result &highlights, const int max_steps) { - gpu::Shader *shader = context().get_shader("compositor_sun_beams"); + gpu::Shader *shader = context().get_shader("compositor_glare_sun_beams"); GPU_shader_bind(shader); GPU_shader_uniform_2fv(shader, "source", this->get_sun_position()); diff --git a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc b/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc deleted file mode 100644 index 0bd60e4f4ab..00000000000 --- a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup cmpnodes - */ - -#include "BLI_math_base.hh" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -#include "UI_resources.hh" - -#include "GPU_shader.hh" - -#include "COM_node_operation.hh" -#include "COM_utilities.hh" - -#include "node_composite_util.hh" - -namespace blender::nodes::node_composite_sunbeams_cc { - -static void cmp_node_sunbeams_declare(NodeDeclarationBuilder &b) -{ - b.add_input("Image") - .default_value({1.0f, 1.0f, 1.0f, 1.0f}) - .structure_type(StructureType::Dynamic); - b.add_input("Source") - .subtype(PROP_FACTOR) - .dimensions(2) - .default_value({0.5f, 0.5f}) - .min(0.0f) - .max(1.0f) - .description( - "The position of the source of the rays in normalized coordinates. 0 means lower left " - "corner and 1 means upper right corner"); - b.add_input("Length") - .subtype(PROP_FACTOR) - .min(0.0f) - .max(1.0f) - .default_value(0.2f) - .description( - "The length of rays relative to the size of the image. 0 means no rays and 1 means the " - "rays cover the full extent of the image"); - - b.add_output("Image"); -} - -using namespace blender::compositor; - -class SunBeamsOperation : public NodeOperation { - public: - using NodeOperation::NodeOperation; - - void execute() override - { - const Result &input_image = this->get_input("Image"); - - const int2 input_size = input_image.domain().size; - const int max_steps = int(this->get_length() * math::length(input_size)); - if (max_steps == 0) { - Result &output_image = this->get_result("Image"); - output_image.share_data(input_image); - return; - } - - if (this->context().use_gpu()) { - this->execute_gpu(max_steps); - } - else { - this->execute_cpu(max_steps); - } - } - - void execute_gpu(const int max_steps) - { - gpu::Shader *shader = context().get_shader("compositor_sun_beams"); - GPU_shader_bind(shader); - - GPU_shader_uniform_2fv(shader, "source", this->get_source()); - GPU_shader_uniform_1i(shader, "max_steps", max_steps); - - Result &input_image = get_input("Image"); - GPU_texture_filter_mode(input_image, true); - GPU_texture_extend_mode(input_image, GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER); - input_image.bind_as_texture(shader, "input_tx"); - - Result &output_image = get_result("Image"); - const Domain domain = compute_domain(); - output_image.allocate_texture(domain); - output_image.bind_as_image(shader, "output_img"); - - compute_dispatch_threads_at_least(shader, domain.size); - - GPU_shader_unbind(); - output_image.unbind_as_image(); - input_image.unbind_as_texture(); - } - - void execute_cpu(const int max_steps) - { - const float2 source = this->get_source(); - - Result &input = get_input("Image"); - - const Domain domain = compute_domain(); - Result &output = get_result("Image"); - output.allocate_texture(domain); - - const int2 input_size = domain.size; - parallel_for(input_size, [&](const int2 texel) { - /* The number of steps is the distance in pixels from the source to the current texel. With - * at least a single step and at most the user specified maximum ray length, which is - * proportional to the diagonal pixel count. */ - float unbounded_steps = math::max( - 1.0f, math::distance(float2(texel), source * float2(input_size))); - int steps = math::min(max_steps, int(unbounded_steps)); - - /* We integrate from the current pixel to the source pixel, so compute the start coordinates - * and step vector in the direction to source. Notice that the step vector is still computed - * from the unbounded steps, such that the total integration length becomes limited by the - * bounded steps, and thus by the maximum ray length. */ - float2 coordinates = (float2(texel) + float2(0.5f)) / float2(input_size); - float2 vector_to_source = source - coordinates; - float2 step_vector = vector_to_source / unbounded_steps; - - float accumulated_weight = 0.0f; - float4 accumulated_color = float4(0.0f); - for (int i = 0; i <= steps; i++) { - float2 position = coordinates + i * step_vector; - - /* We are already past the image boundaries, and any future steps are also past the image - * boundaries, so break. */ - if (position.x < 0.0f || position.y < 0.0f || position.x > 1.0f || position.y > 1.0f) { - break; - } - - float4 sample_color = input.sample_bilinear_zero(position); - - /* Attenuate the contributions of pixels that are further away from the source using a - * quadratic falloff. */ - float weight = math::square(1.0f - i / float(steps)); - - accumulated_weight += weight; - accumulated_color += sample_color * weight; - } - - accumulated_color /= accumulated_weight != 0.0f ? accumulated_weight : 1.0f; - output.store_pixel(texel, accumulated_color); - }); - } - - float2 get_source() - { - return this->get_input("Source").get_single_value_default(float2(0.5f)); - } - - float get_length() - { - return math::clamp(this->get_input("Length").get_single_value_default(0.2f), 0.0f, 1.0f); - } -}; - -static NodeOperation *get_compositor_operation(Context &context, DNode node) -{ - return new SunBeamsOperation(context, node); -} - -} // namespace blender::nodes::node_composite_sunbeams_cc - -static void register_node_type_cmp_sunbeams() -{ - namespace file_ns = blender::nodes::node_composite_sunbeams_cc; - - static blender::bke::bNodeType ntype; - - cmp_node_type_base(&ntype, "CompositorNodeSunBeams", CMP_NODE_SUNBEAMS); - ntype.ui_name = "Sun Beams"; - ntype.ui_description = "Create sun beams based on image brightness"; - ntype.enum_name_legacy = "SUNBEAMS"; - ntype.nclass = NODE_CLASS_OP_FILTER; - ntype.declare = file_ns::cmp_node_sunbeams_declare; - ntype.get_compositor_operation = file_ns::get_compositor_operation; - - blender::bke::node_register_type(ntype); -} -NOD_REGISTER_NODE(register_node_type_cmp_sunbeams)