WIP: Compositor: Add interpolation option to displace node in compositor #119908
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "COM_DisplaceNode.h"
|
||||
#include "BKE_node.hh"
|
||||
#include "COM_DisplaceOperation.h"
|
||||
#include "COM_DisplaceSimpleOperation.h"
|
||||
|
||||
|
@ -16,20 +17,46 @@ DisplaceNode::DisplaceNode(bNode *editor_node) : Node(editor_node)
|
|||
void DisplaceNode::convert_to_operations(NodeConverter &converter,
|
||||
const CompositorContext &context) const
|
||||
{
|
||||
NodeOperation *operation;
|
||||
const bNode *bnode = this->get_bnode();
|
||||
|
||||
PixelSampler sampler = PixelSampler::Nearest;
|
||||
|
||||
switch (bnode->custom1) {
|
||||
case 0:
|
||||
sampler = PixelSampler::Nearest;
|
||||
break;
|
||||
case 1:
|
||||
sampler = PixelSampler::Bilinear;
|
||||
break;
|
||||
case 2:
|
||||
sampler = PixelSampler::Bicubic;
|
||||
break;
|
||||
}
|
||||
|
||||
if (context.get_quality() == eCompositorQuality::Low) {
|
||||
operation = new DisplaceSimpleOperation();
|
||||
DisplaceSimpleOperation *operation = new DisplaceSimpleOperation();
|
||||
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0));
|
||||
converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1));
|
||||
converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2));
|
||||
converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3));
|
||||
converter.map_output_socket(get_output_socket(0), operation->get_output_socket());
|
||||
}
|
||||
else {
|
||||
operation = new DisplaceOperation();
|
||||
}
|
||||
converter.add_operation(operation);
|
||||
DisplaceOperation *operation = new DisplaceOperation();
|
||||
|
||||
converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0));
|
||||
converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1));
|
||||
converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2));
|
||||
converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3));
|
||||
converter.map_output_socket(get_output_socket(0), operation->get_output_socket());
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0));
|
||||
converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1));
|
||||
converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2));
|
||||
converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3));
|
||||
converter.map_output_socket(get_output_socket(0), operation->get_output_socket());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
|
@ -141,19 +141,14 @@ void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
|||
Span<MemoryBuffer *> inputs)
|
||||
{
|
||||
const MemoryBuffer *input_color = inputs[0];
|
||||
PixelSampler sampler = (PixelSampler)sampler_;
|
||||
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
|
||||
const float xy[2] = {float(it.x), float(it.y)};
|
||||
float uv[2];
|
||||
float deriv[2][2];
|
||||
|
||||
pixel_transform(xy, uv, deriv);
|
||||
if (is_zero_v2(deriv[0]) && is_zero_v2(deriv[1])) {
|
||||
input_color->read_elem_bilinear(uv[0], uv[1], it.out);
|
||||
}
|
||||
else {
|
||||
/* EWA filtering (without nearest it gets blurry with NO distortion). */
|
||||
input_color->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], false, it.out);
|
||||
}
|
||||
input_color->read_elem_sampled(uv[0], uv[1], sampler, it.out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,14 @@ class DisplaceOperation : public MultiThreadedOperation {
|
|||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
|
||||
void set_sampler(PixelSampler sampler)
|
||||
{
|
||||
sampler_ = (int)sampler;
|
||||
}
|
||||
|
||||
protected:
|
||||
int sampler_;
|
||||
|
||||
private:
|
||||
bool read_displacement(
|
||||
float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v);
|
||||
|
|
|
@ -46,6 +46,7 @@ void DisplaceSimpleOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
|||
const float width = this->get_width();
|
||||
const float height = this->get_height();
|
||||
const MemoryBuffer *input_color = inputs[0];
|
||||
PixelSampler sampler = (PixelSampler)sampler_;
|
||||
for (BuffersIterator<float> it = output->iterate_with(inputs.drop_front(1), area); !it.is_end();
|
||||
++it)
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ void DisplaceSimpleOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
|||
CLAMP(u, 0.0f, width - 1.0f);
|
||||
CLAMP(v, 0.0f, height - 1.0f);
|
||||
|
||||
input_color->read_elem_checked(u, v, it.out);
|
||||
input_color->read_elem_sampled(u, v, sampler, it.out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,14 @@ class DisplaceSimpleOperation : public MultiThreadedOperation {
|
|||
void update_memory_buffer_partial(MemoryBuffer *output,
|
||||
const rcti &area,
|
||||
Span<MemoryBuffer *> inputs) override;
|
||||
|
||||
void set_sampler(PixelSampler sampler)
|
||||
{
|
||||
sampler_ = (int)sampler;
|
||||
}
|
||||
|
||||
protected:
|
||||
int sampler_;
|
||||
};
|
||||
|
||||
} // namespace blender::compositor
|
||||
|
|
|
@ -6636,6 +6636,36 @@ static void def_cmp_scale(StructRNA *srna)
|
|||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_displace(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem interpolation_items[] = {
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_NEAREST,
|
||||
"NEAREST",
|
||||
0,
|
||||
"Nearest",
|
||||
"Use nearest interpolation"},
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_BILINEAR,
|
||||
"BILINEAR",
|
||||
0,
|
||||
"Bilinear",
|
||||
"Use bilinear interpolation"},
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_BICUBIC,
|
||||
"BICUBIC",
|
||||
0,
|
||||
"Bicubic",
|
||||
"Use bicubic interpolation"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "custom1");
|
||||
RNA_def_property_enum_items(prop, interpolation_items);
|
||||
RNA_def_property_ui_text(prop, "Interpolation", "Which interpolation method to use");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_rotate(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -172,7 +172,7 @@ DefNode(CompositorNode, CMP_NODE_MAP_UV, def_cmp_map_uv, "MAP_UV
|
|||
DefNode(CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MASK", IDMask, "ID Mask", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_DISPLACE, def_cmp_displace, "DISPLACE", Displace, "Displace", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_COMBHSVA_LEGACY,0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "GPU_shader.hh"
|
||||
#include "GPU_texture.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
#include "COM_node_operation.hh"
|
||||
#include "COM_utilities.hh"
|
||||
|
||||
|
@ -44,6 +47,11 @@ static void cmp_node_displace_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Color>("Image");
|
||||
}
|
||||
|
||||
static void node_composit_buts_displace(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "interpolation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
}
|
||||
|
||||
using namespace blender::realtime_compositor;
|
||||
|
||||
class DisplaceOperation : public NodeOperation {
|
||||
|
@ -129,6 +137,7 @@ void register_node_type_cmp_displace()
|
|||
|
||||
cmp_node_type_base(&ntype, CMP_NODE_DISPLACE, "Displace", NODE_CLASS_DISTORT);
|
||||
ntype.declare = file_ns::cmp_node_displace_declare;
|
||||
ntype.draw_buttons = file_ns::node_composit_buts_displace;
|
||||
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
|
|
Loading…
Reference in New Issue