Compositor: Turn Lens Distortion options to inputs
This patch turns the options of the Lens Distortion node into inputs. The Projector option was turned into an enum between two options. Reference #137223. Pull Request: https://projects.blender.org/blender/blender/pulls/138113
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 52
|
||||
#define BLENDER_FILE_SUBVERSION 53
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -951,6 +951,13 @@ static void write_compositor_legacy_properties(bNodeTree &node_tree)
|
||||
write_input_to_property_bool_int16_flag("Apply On Green", node->custom1, 1 << 1);
|
||||
write_input_to_property_bool_int16_flag("Apply On Blue", node->custom1, 1 << 2);
|
||||
}
|
||||
|
||||
if (node->type_legacy == CMP_NODE_LENSDIST) {
|
||||
NodeLensDist *storage = static_cast<NodeLensDist *>(node->storage);
|
||||
write_input_to_property_bool_short("Jitter", storage->jit);
|
||||
write_input_to_property_bool_short("Fit", storage->fit);
|
||||
storage->proj = storage->distortion_type == CMP_NODE_LENS_DISTORTION_HORIZONTAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3824,6 +3824,67 @@ static void do_version_color_correction_node_options_to_inputs_animation(bNodeTr
|
||||
});
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_lens_distortion_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
|
||||
{
|
||||
NodeLensDist *storage = static_cast<NodeLensDist *>(node->storage);
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use Projector boolean option is now an enum between two types. */
|
||||
storage->distortion_type = storage->proj ? CMP_NODE_LENS_DISTORTION_HORIZONTAL :
|
||||
CMP_NODE_LENS_DISTORTION_RADIAL;
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Jitter")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Jitter", "Jitter");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->jit);
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Fit")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Fit", "Fit");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(storage->fit);
|
||||
}
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_lens_distortion_node_options_to_inputs_animation(bNodeTree *node_tree,
|
||||
bNode *node)
|
||||
{
|
||||
/* Compute the RNA path of the node. */
|
||||
char escaped_node_name[sizeof(node->name) * 2 + 1];
|
||||
BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
|
||||
const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
|
||||
|
||||
BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
|
||||
/* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
|
||||
* path. */
|
||||
if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
|
||||
* values of the FCurves frames when needed. */
|
||||
char *old_rna_path = fcurve->rna_path;
|
||||
if (BLI_str_endswith(fcurve->rna_path, "use_jitter")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "use_fit")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "use_projector")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "distortion_type");
|
||||
}
|
||||
|
||||
/* The RNA path was changed, free the old path. */
|
||||
if (fcurve->rna_path != old_rna_path) {
|
||||
MEM_freeN(old_rna_path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void do_version_viewer_shortcut(bNodeTree *node_tree)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
|
||||
@@ -4642,6 +4703,19 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 53)) {
|
||||
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_LENSDIST) {
|
||||
do_version_lens_distortion_node_options_to_inputs_animation(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.
|
||||
@@ -9614,6 +9688,19 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 53)) {
|
||||
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_LENSDIST) {
|
||||
do_version_lens_distortion_node_options_to_inputs(node_tree, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/* Always run this versioning (keep at the bottom of the function). Meshes are written with the
|
||||
* legacy format which always needs to be converted to the new format on file load. To be moved
|
||||
* to a subversion check in 5.0. */
|
||||
|
||||
@@ -204,6 +204,7 @@ set(GLSL_SRC
|
||||
shaders/compositor_glare_streaks_filter.glsl
|
||||
shaders/compositor_glare_write_glare_output.glsl
|
||||
shaders/compositor_glare_write_highlights_output.glsl
|
||||
shaders/compositor_horizontal_lens_distortion.glsl
|
||||
shaders/compositor_id_mask.glsl
|
||||
shaders/compositor_image_crop.glsl
|
||||
shaders/compositor_inpaint_compute_boundary.glsl
|
||||
@@ -239,11 +240,10 @@ set(GLSL_SRC
|
||||
shaders/compositor_plane_deform_motion_blur_mask.glsl
|
||||
shaders/compositor_plane_deform.glsl
|
||||
shaders/compositor_premultiply_alpha.glsl
|
||||
shaders/compositor_projector_lens_distortion.glsl
|
||||
shaders/compositor_radial_lens_distortion.glsl
|
||||
shaders/compositor_read_input.glsl
|
||||
shaders/compositor_realize_on_domain.glsl
|
||||
shaders/compositor_scale_variable.glsl
|
||||
shaders/compositor_screen_lens_distortion.glsl
|
||||
shaders/compositor_smaa_blending_weight_calculation.glsl
|
||||
shaders/compositor_smaa_edge_detection.glsl
|
||||
shaders/compositor_smaa_neighborhood_blending.glsl
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
/* Radial Lens Distortion. */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_radial_lens_distortion_shared)
|
||||
LOCAL_GROUP_SIZE(16, 16)
|
||||
PUSH_CONSTANT(float3, chromatic_distortion)
|
||||
PUSH_CONSTANT(float, scale)
|
||||
SAMPLER(0, sampler2D, input_tx)
|
||||
IMAGE(0, GPU_RGBA16F, write, image2D, output_img)
|
||||
COMPUTE_SOURCE("compositor_radial_lens_distortion.glsl")
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_radial_lens_distortion)
|
||||
ADDITIONAL_INFO(compositor_radial_lens_distortion_shared)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_radial_lens_distortion_jitter)
|
||||
ADDITIONAL_INFO(compositor_radial_lens_distortion_shared)
|
||||
DEFINE("JITTER")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* Horizontal Lens Distortion. */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_horizontal_lens_distortion)
|
||||
LOCAL_GROUP_SIZE(16, 16)
|
||||
PUSH_CONSTANT(float, dispersion)
|
||||
SAMPLER(0, sampler2D, input_tx)
|
||||
IMAGE(0, GPU_RGBA16F, write, image2D, output_img)
|
||||
COMPUTE_SOURCE("compositor_horizontal_lens_distortion.glsl")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
@@ -1,14 +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_projector_lens_distortion)
|
||||
LOCAL_GROUP_SIZE(16, 16)
|
||||
PUSH_CONSTANT(float, dispersion)
|
||||
SAMPLER(0, sampler2D, input_tx)
|
||||
IMAGE(0, GPU_RGBA16F, write, image2D, output_img)
|
||||
COMPUTE_SOURCE("compositor_projector_lens_distortion.glsl")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
@@ -1,25 +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_screen_lens_distortion_shared)
|
||||
LOCAL_GROUP_SIZE(16, 16)
|
||||
PUSH_CONSTANT(float3, chromatic_distortion)
|
||||
PUSH_CONSTANT(float, scale)
|
||||
SAMPLER(0, sampler2D, input_tx)
|
||||
IMAGE(0, GPU_RGBA16F, write, image2D, output_img)
|
||||
COMPUTE_SOURCE("compositor_screen_lens_distortion.glsl")
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion)
|
||||
ADDITIONAL_INFO(compositor_screen_lens_distortion_shared)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_jitter)
|
||||
ADDITIONAL_INFO(compositor_screen_lens_distortion_shared)
|
||||
DEFINE("JITTER")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "compositor_keying_info.hh"
|
||||
#include "compositor_keying_screen_info.hh"
|
||||
#include "compositor_kuwahara_info.hh"
|
||||
#include "compositor_lens_distortion_info.hh"
|
||||
#include "compositor_map_uv_info.hh"
|
||||
#include "compositor_morphological_blur_info.hh"
|
||||
#include "compositor_morphological_distance_feather_info.hh"
|
||||
@@ -93,11 +94,9 @@
|
||||
#include "compositor_pixelate_info.hh"
|
||||
#include "compositor_plane_deform_info.hh"
|
||||
#include "compositor_premultiply_alpha_info.hh"
|
||||
#include "compositor_projector_lens_distortion_info.hh"
|
||||
#include "compositor_read_input_info.hh"
|
||||
#include "compositor_realize_on_domain_info.hh"
|
||||
#include "compositor_scale_variable_info.hh"
|
||||
#include "compositor_screen_lens_distortion_info.hh"
|
||||
#include "compositor_smaa_info.hh"
|
||||
#include "compositor_split_info.hh"
|
||||
#include "compositor_summed_area_table_info.hh"
|
||||
|
||||
@@ -1289,10 +1289,13 @@ typedef struct NodeTonemap {
|
||||
int type;
|
||||
} NodeTonemap;
|
||||
|
||||
/** Lens distortion node. */
|
||||
/* Lens Distortion node. */
|
||||
typedef struct NodeLensDist {
|
||||
short jit, proj, fit;
|
||||
short jit DNA_DEPRECATED;
|
||||
short proj DNA_DEPRECATED;
|
||||
short fit DNA_DEPRECATED;
|
||||
char _pad[2];
|
||||
int distortion_type;
|
||||
} NodeLensDist;
|
||||
|
||||
typedef struct NodeColorBalance {
|
||||
@@ -3012,6 +3015,12 @@ typedef enum CMPNodeChannelMatteColorSpace {
|
||||
CMP_NODE_CHANNEL_MATTE_CS_YCC = 4,
|
||||
} CMPNodeChannelMatteColorSpace;
|
||||
|
||||
/* NodeLensDist.distortion_type. */
|
||||
typedef enum CMPNodeLensDistortionType {
|
||||
CMP_NODE_LENS_DISTORTION_RADIAL = 0,
|
||||
CMP_NODE_LENS_DISTORTION_HORIZONTAL = 1,
|
||||
} CMPNodeLensDistortionType;
|
||||
|
||||
/* Point Density shader node */
|
||||
|
||||
enum {
|
||||
|
||||
@@ -3857,6 +3857,18 @@ static void rna_NodeColorSpill_unspill_blue_set(PointerRNA *ptr, const float val
|
||||
RNA_float_set_array(&input_rna_pointer, "default_value", spill_strength);
|
||||
}
|
||||
|
||||
static bool rna_NodeLensDistortion_projector_get(PointerRNA *ptr)
|
||||
{
|
||||
return RNA_enum_get(ptr, "distortion_type") == CMP_NODE_LENS_DISTORTION_HORIZONTAL;
|
||||
}
|
||||
|
||||
static void rna_NodeLensDistortion_projector_set(PointerRNA *ptr, const bool value)
|
||||
{
|
||||
RNA_enum_set(ptr,
|
||||
"distortion_type",
|
||||
value ? CMP_NODE_LENS_DISTORTION_HORIZONTAL : CMP_NODE_LENS_DISTORTION_RADIAL);
|
||||
}
|
||||
|
||||
/* A getter that returns the value of the input socket with the given template identifier and type.
|
||||
* The RNA pointer is assumed to represent a node. */
|
||||
template<typename T, const char *identifier>
|
||||
@@ -4042,6 +4054,10 @@ static const char node_input_apply_on_red[] = "Apply On Red";
|
||||
static const char node_input_apply_on_green[] = "Apply On Green";
|
||||
static const char node_input_apply_on_blue[] = "Apply On Blue";
|
||||
|
||||
/* Lens Distortion node. */
|
||||
static const char node_input_fit[] = "Fit";
|
||||
static const char node_input_jitter[] = "Jitter";
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* White Balance Node.
|
||||
*/
|
||||
@@ -8847,28 +8863,56 @@ static void def_cmp_lensdist(BlenderRNA * /*brna*/, StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem type_items[] = {
|
||||
{CMP_NODE_LENS_DISTORTION_RADIAL,
|
||||
"RADIAL",
|
||||
0,
|
||||
"Radial",
|
||||
"Radially distorts the image to create a barrel or a Pincushion distortion"},
|
||||
{CMP_NODE_LENS_DISTORTION_HORIZONTAL,
|
||||
"HORIZONTAL",
|
||||
0,
|
||||
"Horizontal",
|
||||
"Horizontally distorts the image to create a channel/color shifting effect"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
RNA_def_struct_sdna_from(srna, "NodeLensDist", "storage");
|
||||
|
||||
prop = RNA_def_property(srna, "distortion_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "distortion_type");
|
||||
RNA_def_property_enum_items(prop, type_items);
|
||||
RNA_def_property_ui_text(prop, "Type", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_projector", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "proj", 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Projector",
|
||||
"Enable/disable projector mode (the effect is applied in horizontal direction only)");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_NodeLensDistortion_projector_get", "rna_NodeLensDistortion_projector_set");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Projector",
|
||||
"Enable/disable projector mode (the effect is applied in horizontal "
|
||||
"direction only). (Deprecated: Use distortion_type property instead.)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_jitter", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "jit", 1);
|
||||
RNA_def_property_ui_text(prop, "Jitter", "Enable/disable jittering (faster, but also noisier)");
|
||||
RNA_def_property_boolean_funcs(prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_jitter>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_jitter>");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Jitter",
|
||||
"Enable/disable jittering (faster, but also noisier). (Deprecated: Use "
|
||||
"Jitter input instead.)");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_NODETREE);
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_fit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "fit", 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Fit",
|
||||
"For positive distortion factor only: scale image such that black areas are not visible");
|
||||
RNA_def_property_boolean_funcs(prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_fit>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_fit>");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Fit",
|
||||
"For positive distortion factor only: scale image such that black "
|
||||
"areas are not visible. (Deprecated: Use Fit input instead.)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
|
||||
/* Distortion can't be exactly -1.0 as it will cause infinite pincushion distortion. */
|
||||
#define MINIMUM_DISTORTION -0.999f
|
||||
/* Arbitrary scaling factor for the dispersion input in projector distortion mode. */
|
||||
#define PROJECTOR_DISPERSION_SCALE 5.0f
|
||||
/* Arbitrary scaling factor for the dispersion input in screen distortion mode. */
|
||||
#define SCREEN_DISPERSION_SCALE 4.0f
|
||||
/* Arbitrary scaling factor for the dispersion input in horizontal distortion mode. */
|
||||
#define HORIZONTAL_DISPERSION_SCALE 5.0f
|
||||
/* Arbitrary scaling factor for the dispersion input in radial distortion mode. */
|
||||
#define RADIAL_DISPERSION_SCALE 4.0f
|
||||
/* Arbitrary scaling factor for the distortion input. */
|
||||
#define DISTORTION_SCALE 4.0f
|
||||
|
||||
@@ -40,40 +40,66 @@ NODE_STORAGE_FUNCS(NodeLensDist)
|
||||
|
||||
static void cmp_node_lensdist_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Image")
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.compositor_domain_priority(0);
|
||||
b.add_input<decl::Color>("Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Float>("Distortion")
|
||||
.default_value(0.0f)
|
||||
.subtype(PROP_FACTOR)
|
||||
.min(MINIMUM_DISTORTION)
|
||||
.max(1.0f)
|
||||
.description(
|
||||
"The amount of distortion. 0 means no distortion, -1 means full Pincushion distortion, "
|
||||
"and 1 means full Barrel distortion")
|
||||
.compositor_expects_single_value();
|
||||
b.add_input<decl::Float>("Dispersion")
|
||||
.default_value(0.0f)
|
||||
.subtype(PROP_FACTOR)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.description("The amount of chromatic aberration to add to the distortion")
|
||||
.compositor_expects_single_value();
|
||||
b.add_input<decl::Bool>("Jitter")
|
||||
.default_value(false)
|
||||
.description(
|
||||
"Introduces jitter while doing distortion, which can be faster but can produce grainy "
|
||||
"or noisy results")
|
||||
.compositor_expects_single_value();
|
||||
b.add_input<decl::Bool>("Fit")
|
||||
.default_value(false)
|
||||
.description(
|
||||
"Scales the image such that it fits entirely in the frame, leaving no empty spaces at "
|
||||
"the corners")
|
||||
.compositor_expects_single_value();
|
||||
b.add_output<decl::Color>("Image");
|
||||
}
|
||||
|
||||
static void node_composit_init_lensdist(bNodeTree * /*ntree*/, bNode *node)
|
||||
{
|
||||
NodeLensDist *nld = MEM_callocN<NodeLensDist>(__func__);
|
||||
nld->jit = nld->proj = nld->fit = 0;
|
||||
node->storage = nld;
|
||||
NodeLensDist *data = MEM_callocN<NodeLensDist>(__func__);
|
||||
data->distortion_type = CMP_NODE_LENS_DISTORTION_RADIAL;
|
||||
node->storage = data;
|
||||
}
|
||||
|
||||
static void node_composit_buts_lensdist(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiLayout *col;
|
||||
uiItemR(layout, ptr, "distortion_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
}
|
||||
|
||||
col = &layout->column(false);
|
||||
uiItemR(col, ptr, "use_projector", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
static void node_update(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
const CMPNodeLensDistortionType distortion_type = CMPNodeLensDistortionType(
|
||||
node_storage(*node).distortion_type);
|
||||
|
||||
col = &col->column(false);
|
||||
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == false);
|
||||
uiItemR(col, ptr, "use_jitter", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
uiItemR(col, ptr, "use_fit", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
bNodeSocket *distortion_input = bke::node_find_socket(*node, SOCK_IN, "Distortion");
|
||||
blender::bke::node_set_socket_availability(
|
||||
*ntree, *distortion_input, distortion_type == CMP_NODE_LENS_DISTORTION_RADIAL);
|
||||
|
||||
bNodeSocket *jitter_input = bke::node_find_socket(*node, SOCK_IN, "Jitter");
|
||||
blender::bke::node_set_socket_availability(
|
||||
*ntree, *jitter_input, distortion_type == CMP_NODE_LENS_DISTORTION_RADIAL);
|
||||
|
||||
bNodeSocket *fit_input = bke::node_find_socket(*node, SOCK_IN, "Fit");
|
||||
blender::bke::node_set_socket_availability(
|
||||
*ntree, *fit_input, distortion_type == CMP_NODE_LENS_DISTORTION_RADIAL);
|
||||
}
|
||||
|
||||
using namespace blender::compositor;
|
||||
@@ -206,7 +232,7 @@ static float3 integrate_distortion(const int2 &texel,
|
||||
return accumulated_color;
|
||||
}
|
||||
|
||||
static void screen_lens_distortion(const int2 texel,
|
||||
static void radial_lens_distortion(const int2 texel,
|
||||
const Result &input,
|
||||
Result &output,
|
||||
const int2 &size,
|
||||
@@ -284,27 +310,29 @@ class LensDistortionOperation : public NodeOperation {
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_is_projector()) {
|
||||
execute_projector_distortion();
|
||||
}
|
||||
else {
|
||||
execute_screen_distortion();
|
||||
switch (this->get_type()) {
|
||||
case CMP_NODE_LENS_DISTORTION_RADIAL:
|
||||
this->execute_radial_distortion();
|
||||
break;
|
||||
case CMP_NODE_LENS_DISTORTION_HORIZONTAL:
|
||||
this->execute_horizontal_distortion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void execute_projector_distortion()
|
||||
void execute_horizontal_distortion()
|
||||
{
|
||||
if (this->context().use_gpu()) {
|
||||
this->execute_projector_distortion_gpu();
|
||||
this->execute_horizontal_distortion_gpu();
|
||||
}
|
||||
else {
|
||||
this->execute_projector_distortion_cpu();
|
||||
this->execute_horizontal_distortion_cpu();
|
||||
}
|
||||
}
|
||||
|
||||
void execute_projector_distortion_gpu()
|
||||
void execute_horizontal_distortion_gpu()
|
||||
{
|
||||
GPUShader *shader = context().get_shader("compositor_projector_lens_distortion");
|
||||
GPUShader *shader = context().get_shader("compositor_horizontal_lens_distortion");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
const Result &input_image = get_input("Image");
|
||||
@@ -314,7 +342,7 @@ class LensDistortionOperation : public NodeOperation {
|
||||
|
||||
const Domain domain = compute_domain();
|
||||
|
||||
const float dispersion = (get_dispersion() * PROJECTOR_DISPERSION_SCALE) / domain.size.x;
|
||||
const float dispersion = (get_dispersion() * HORIZONTAL_DISPERSION_SCALE) / domain.size.x;
|
||||
GPU_shader_uniform_1f(shader, "dispersion", dispersion);
|
||||
|
||||
Result &output_image = get_result("Image");
|
||||
@@ -328,10 +356,10 @@ class LensDistortionOperation : public NodeOperation {
|
||||
GPU_shader_unbind();
|
||||
}
|
||||
|
||||
void execute_projector_distortion_cpu()
|
||||
void execute_horizontal_distortion_cpu()
|
||||
{
|
||||
const Domain domain = compute_domain();
|
||||
const float dispersion = (get_dispersion() * PROJECTOR_DISPERSION_SCALE) / domain.size.x;
|
||||
const float dispersion = (get_dispersion() * HORIZONTAL_DISPERSION_SCALE) / domain.size.x;
|
||||
|
||||
const Result &input = get_input("Image");
|
||||
|
||||
@@ -352,19 +380,19 @@ class LensDistortionOperation : public NodeOperation {
|
||||
});
|
||||
}
|
||||
|
||||
void execute_screen_distortion()
|
||||
void execute_radial_distortion()
|
||||
{
|
||||
if (this->context().use_gpu()) {
|
||||
this->execute_screen_distortion_gpu();
|
||||
this->execute_radial_distortion_gpu();
|
||||
}
|
||||
else {
|
||||
this->execute_screen_distortion_cpu();
|
||||
this->execute_radial_distortion_cpu();
|
||||
}
|
||||
}
|
||||
|
||||
void execute_screen_distortion_gpu()
|
||||
void execute_radial_distortion_gpu()
|
||||
{
|
||||
GPUShader *shader = context().get_shader(get_screen_distortion_shader());
|
||||
GPUShader *shader = context().get_shader(get_radial_distortion_shader());
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
const Result &input_image = get_input("Image");
|
||||
@@ -390,15 +418,15 @@ class LensDistortionOperation : public NodeOperation {
|
||||
GPU_shader_unbind();
|
||||
}
|
||||
|
||||
const char *get_screen_distortion_shader()
|
||||
const char *get_radial_distortion_shader()
|
||||
{
|
||||
if (get_use_jitter()) {
|
||||
return "compositor_screen_lens_distortion_jitter";
|
||||
return "compositor_radial_lens_distortion_jitter";
|
||||
}
|
||||
return "compositor_screen_lens_distortion";
|
||||
return "compositor_radial_lens_distortion";
|
||||
}
|
||||
|
||||
void execute_screen_distortion_cpu()
|
||||
void execute_radial_distortion_cpu()
|
||||
{
|
||||
const float scale = this->compute_scale();
|
||||
const bool use_jitter = this->get_use_jitter();
|
||||
@@ -412,7 +440,7 @@ class LensDistortionOperation : public NodeOperation {
|
||||
|
||||
const int2 size = domain.size;
|
||||
parallel_for(size, [&](const int2 texel) {
|
||||
screen_lens_distortion(texel, input, output, size, chromatic_distortion, scale, use_jitter);
|
||||
radial_lens_distortion(texel, input, output, size, chromatic_distortion, scale, use_jitter);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -434,7 +462,7 @@ class LensDistortionOperation : public NodeOperation {
|
||||
float3 compute_chromatic_distortion()
|
||||
{
|
||||
const float green_distortion = get_distortion();
|
||||
const float dispersion = get_dispersion() / SCREEN_DISPERSION_SCALE;
|
||||
const float dispersion = get_dispersion() / RADIAL_DISPERSION_SCALE;
|
||||
const float red_distortion = clamp_f(green_distortion + dispersion, MINIMUM_DISTORTION, 1.0f);
|
||||
const float blue_distortion = clamp_f(green_distortion - dispersion, MINIMUM_DISTORTION, 1.0f);
|
||||
return float3(red_distortion, green_distortion, blue_distortion) * DISTORTION_SCALE;
|
||||
@@ -456,37 +484,39 @@ class LensDistortionOperation : public NodeOperation {
|
||||
return 1.0f / (1.0f + maximum_distortion);
|
||||
}
|
||||
|
||||
bool get_is_projector()
|
||||
CMPNodeLensDistortionType get_type()
|
||||
{
|
||||
return node_storage(bnode()).proj;
|
||||
return CMPNodeLensDistortionType(node_storage(bnode()).distortion_type);
|
||||
}
|
||||
|
||||
bool get_use_jitter()
|
||||
{
|
||||
return node_storage(bnode()).jit;
|
||||
return this->get_input("Jitter").get_single_value_default(false);
|
||||
}
|
||||
|
||||
bool get_is_fit()
|
||||
{
|
||||
return node_storage(bnode()).fit;
|
||||
return this->get_input("Fit").get_single_value_default(false);
|
||||
}
|
||||
|
||||
/* Returns true if the operation does nothing and the input can be passed through. */
|
||||
bool is_identity()
|
||||
{
|
||||
/* The input is a single value and the operation does nothing. */
|
||||
if (get_input("Image").is_single_value()) {
|
||||
if (this->get_input("Image").is_single_value()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Projector have zero dispersion and does nothing. */
|
||||
if (get_is_projector() && get_dispersion() == 0.0f) {
|
||||
return true;
|
||||
if (this->get_type() == CMP_NODE_LENS_DISTORTION_HORIZONTAL) {
|
||||
return this->get_dispersion() == 0.0f;
|
||||
}
|
||||
|
||||
/* Both distortion and dispersion are zero and the operation does nothing. Jittering has an
|
||||
* effect regardless, so its gets an exemption. */
|
||||
if (!get_use_jitter() && get_distortion() == 0.0f && get_dispersion() == 0.0f) {
|
||||
if (!this->get_use_jitter() && this->get_distortion() == 0.0f &&
|
||||
this->get_dispersion() == 0.0f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -513,6 +543,7 @@ void register_node_type_cmp_lensdist()
|
||||
ntype.enum_name_legacy = "LENSDIST";
|
||||
ntype.nclass = NODE_CLASS_DISTORT;
|
||||
ntype.declare = file_ns::cmp_node_lensdist_declare;
|
||||
ntype.updatefunc = file_ns::node_update;
|
||||
ntype.draw_buttons = file_ns::node_composit_buts_lensdist;
|
||||
ntype.initfunc = file_ns::node_composit_init_lensdist;
|
||||
blender::bke::node_type_storage(
|
||||
|
||||
Reference in New Issue
Block a user