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:
Omar Emara
2025-04-29 09:54:12 +02:00
committed by Omar Emara
parent f6a8993570
commit ddc0f9460d
13 changed files with 284 additions and 108 deletions

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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. */

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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");
}

View File

@@ -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(