Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/composite/nodes/node_composite_pixelate.cc')
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_pixelate.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
index 529aa0f84de..c65bb7bb747 100644
--- a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc
@@ -5,6 +5,11 @@
* \ingroup cmpnodes
*/
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "COM_node_operation.hh"
+
#include "node_composite_util.hh"
/* **************** Pixelate ******************** */
@@ -17,6 +22,52 @@ static void cmp_node_pixelate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>(N_("Color"));
}
+using namespace blender::realtime_compositor;
+
+class PixelateOperation : public NodeOperation {
+ public:
+ using NodeOperation::NodeOperation;
+
+ void execute() override
+ {
+ /* It might seems strange that the input is passed through without any processing, but note
+ * that the actual processing happens inside the domain realization input processor of the
+ * input. Indeed, the pixelate node merely realizes its input on a smaller-sized domain that
+ * matches its apparent size, that is, its size after the domain transformation. The pixelate
+ * node has no effect if the input is scaled-up. See the compute_domain method for more
+ * information. */
+ Result &result = get_result("Color");
+ get_input("Color").pass_through(result);
+
+ result.get_realization_options().interpolation = Interpolation::Nearest;
+ }
+
+ /* Compute a smaller-sized domain that matches the apparent size of the input while having a unit
+ * scale transformation, see the execute method for more information. */
+ Domain compute_domain() override
+ {
+ Domain domain = get_input("Color").domain();
+
+ /* Get the scaling component of the domain transformation, but make sure it doesn't exceed 1,
+ * because pixelation should only happen if the input is scaled down. */
+ const float2 scale = math::min(float2(1.0f), domain.transformation.scale_2d());
+
+ /* Multiply the size of the domain by its scale to match its apparent size, but make sure it is
+ * at least 1 pixel in both axis. */
+ domain.size = math::max(int2(float2(domain.size) * scale), int2(1));
+
+ /* Reset the scale of the transformation by transforming it with the inverse of the scale. */
+ domain.transformation *= float3x3::from_scale(math::safe_divide(float2(1.0f), scale));
+
+ return domain;
+ }
+};
+
+static NodeOperation *get_compositor_operation(Context &context, DNode node)
+{
+ return new PixelateOperation(context, node);
+}
+
} // namespace blender::nodes::node_composite_pixelate_cc
void register_node_type_cmp_pixelate()
@@ -27,6 +78,7 @@ void register_node_type_cmp_pixelate()
cmp_node_type_base(&ntype, CMP_NODE_PIXELATE, "Pixelate", NODE_CLASS_OP_FILTER);
ntype.declare = file_ns::cmp_node_pixelate_declare;
+ ntype.get_compositor_operation = file_ns::get_compositor_operation;
nodeRegisterType(&ntype);
}