Compositor: Removing Sun Beams node
This patch removes the Sun Beams node since it is now part of the Glare node. It is versioned using a Glare node of Sun Beams type. Pull Request: https://projects.blender.org/blender/blender/pulls/144110
This commit is contained in:
committed by
Omar Emara
parent
69cf5e1ad7
commit
ce7759bae6
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<NodeGlare *>(glare_node->storage)->type = CMP_NODE_GLARE_SUN_BEAMS;
|
||||
static_cast<NodeGlare *>(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<bNodeSocketValueRGBA>()->value,
|
||||
old_image_input->default_value_typed<bNodeSocketValueRGBA>()->value);
|
||||
threshold_input->default_value_typed<bNodeSocketValueFloat>()->value = 0.0f;
|
||||
size_input->default_value_typed<bNodeSocketValueFloat>()->value =
|
||||
old_length_input->default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
copy_v2_v2(source_input->default_value_typed<bNodeSocketValueVector>()->value,
|
||||
old_source_input->default_value_typed<bNodeSocketValueVector>()->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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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<decl::Color>("Image")
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.structure_type(StructureType::Dynamic);
|
||||
b.add_input<decl::Vector>("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<decl::Float>("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<decl::Color>("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)
|
||||
Reference in New Issue
Block a user