Compositor: Port Integer Math node

This patch ports the Integer Math node to the compositor.

Pull Request: https://projects.blender.org/blender/blender/pulls/160924
This commit is contained in:
Criss-Ivana 2026-07-28 12:16:55 +02:00 • committed by Omar Emara
parent 3e936544d5
commit fae91bee18
6 changed files with 214 additions and 1 deletions

View file

@ -355,6 +355,12 @@ class NODE_MT_compositor_node_math_base(node_add_menu.NodeMenu):
self.node_operator_with_searchable_enum(context, layout, "FunctionNodeBooleanMath", "operation")
self.node_operator(layout, "ShaderNodeClamp")
self.node_operator(layout, "FunctionNodeCompare")
self.node_operator_with_searchable_enum(
context,
layout,
"FunctionNodeIntegerMath",
"operation",
defaults_callback=node_add_menu.set_int_math_node_default_props)
self.node_operator_with_searchable_enum(context, layout, "FunctionNodeFloatToInt", "rounding_mode")
self.node_operator(layout, "ShaderNodeFloatCurve")
self.node_operator(layout, "ShaderNodeMapRange")

View file

@ -689,6 +689,7 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_holdout.glsl
shaders/material/gpu_shader_material_hue_sat_val.glsl
shaders/material/gpu_shader_material_implicit_defaults.glsl
shaders/material/gpu_shader_material_integer_math.glsl
shaders/material/gpu_shader_material_invert.glsl
shaders/material/gpu_shader_material_invert_rotation.glsl
shaders/material/gpu_shader_material_layer_weight.glsl

View file

@ -0,0 +1,138 @@
/* SPDX-FileCopyrightText: 2026 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
int divide_floor(int a, int b)
{
int d = a / b;
int r = a % b;
return (r != 0) ? (d - int((a < 0) != (b < 0))) : d;
}
int euclid_gcd(int a, int b)
{
a = abs(a);
b = abs(b);
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
[[node]]
void integer_math_add(int a, int b, int c, out int result)
{
result = a + b;
}
[[node]]
void integer_math_subtract(int a, int b, int c, out int result)
{
result = a - b;
}
[[node]]
void integer_math_multiply(int a, int b, int c, out int result)
{
result = a * b;
}
[[node]]
void integer_math_divide(int a, int b, int c, out int result)
{
result = (b != 0) ? (a / b) : 0;
}
[[node]]
void integer_math_multiply_add(int a, int b, int c, out int result)
{
result = a * b + c;
}
[[node]]
void integer_math_power(int base, int exponent, int c, out int result)
{
result = int(pow(float(base), float(exponent)));
}
[[node]]
void integer_math_floored_modulo(int a, int b, int c, out int result)
{
result = (b != 0) ? (((a % b) + b) % b) : 0;
}
[[node]]
void integer_math_absolute(int a, int b, int c, out int result)
{
result = abs(a);
}
[[node]]
void integer_math_minimum(int a, int b, int c, out int result)
{
result = min(a, b);
}
[[node]]
void integer_math_maximum(int a, int b, int c, out int result)
{
result = max(a, b);
}
[[node]]
void integer_math_gcd(int a, int b, int c, out int result)
{
result = euclid_gcd(a, b);
}
[[node]]
void integer_math_lcm(int a, int b, int c, out int result)
{
int gcd = euclid_gcd(a, b);
result = (gcd != 0) ? abs(a / gcd * b) : 0;
}
[[node]]
void integer_math_negate(int a, int b, int c, out int result)
{
result = -a;
}
[[node]]
void integer_math_sign(int a, int b, int c, out int result)
{
result = int(0 < a) - int(a < 0);
}
[[node]]
void integer_math_divide_floor(int a, int b, int c, out int result)
{
result = (b != 0) ? divide_floor(a, b) : 0;
}
[[node]]
void integer_math_divide_ceil(int a, int b, int c, out int result)
{
result = (b != 0) ? -divide_floor(a, -b) : 0;
}
[[node]]
void integer_math_divide_round(int a, int b, int c, out int result)
{
int abs_b = abs(b);
int sign_b = int(0 < b) - int(b < 0);
if (a >= 0) {
result = ((abs_b != 0) ? ((2 * a + abs_b) / (2 * abs_b)) : 0) * sign_b;
}
else {
result = -((abs_b != 0) ? ((2 * -a + abs_b) / (2 * abs_b)) : 0) * sign_b;
}
}
[[node]]
void integer_math_modulo(int a, int b, int c, out int result)
{
result = (b != 0) ? (a % b) : 0;
}

View file

@ -17,6 +17,7 @@
#include "NOD_value_elem_eval.hh"
#include "node_function_util.hh"
#include "node_shader_util.hh"
namespace blender::nodes::node_fn_integer_math_cc {
@ -195,6 +196,66 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
builder.set_matching_fn(fn);
}
static const char *gpu_shader_get_name(const NodeIntegerMathOperation operation)
{
switch (operation) {
case NODE_INTEGER_MATH_ADD:
return "integer_math_add";
case NODE_INTEGER_MATH_SUBTRACT:
return "integer_math_subtract";
case NODE_INTEGER_MATH_MULTIPLY:
return "integer_math_multiply";
case NODE_INTEGER_MATH_DIVIDE:
return "integer_math_divide";
case NODE_INTEGER_MATH_MULTIPLY_ADD:
return "integer_math_multiply_add";
case NODE_INTEGER_MATH_POWER:
return "integer_math_power";
case NODE_INTEGER_MATH_FLOORED_MODULO:
return "integer_math_floored_modulo";
case NODE_INTEGER_MATH_ABSOLUTE:
return "integer_math_absolute";
case NODE_INTEGER_MATH_MINIMUM:
return "integer_math_minimum";
case NODE_INTEGER_MATH_MAXIMUM:
return "integer_math_maximum";
case NODE_INTEGER_MATH_GCD:
return "integer_math_gcd";
case NODE_INTEGER_MATH_LCM:
return "integer_math_lcm";
case NODE_INTEGER_MATH_NEGATE:
return "integer_math_negate";
case NODE_INTEGER_MATH_SIGN:
return "integer_math_sign";
case NODE_INTEGER_MATH_DIVIDE_FLOOR:
return "integer_math_divide_floor";
case NODE_INTEGER_MATH_DIVIDE_CEIL:
return "integer_math_divide_ceil";
case NODE_INTEGER_MATH_DIVIDE_ROUND:
return "integer_math_divide_round";
case NODE_INTEGER_MATH_MODULO:
return "integer_math_modulo";
}
BLI_assert_unreachable();
return nullptr;
}
static int node_gpu_material(GPUMaterial *mat,
bNode *node,
bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
const char *name = gpu_shader_get_name(NodeIntegerMathOperation(node->custom1));
if (name == nullptr) {
return 0;
}
return GPU_stack_link(mat, node, name, in, out);
}
static void node_eval_elem(value_elem::ElemEvalParams &params)
{
using namespace value_elem;
@ -284,7 +345,7 @@ static void node_register()
{
static bke::bNodeType ntype;
fn_node_type_base(&ntype, "FunctionNodeIntegerMath"_ustr, FN_NODE_INTEGER_MATH);
fn_cmp_node_type_base(&ntype, "FunctionNodeIntegerMath"_ustr, FN_NODE_INTEGER_MATH);
ntype.ui_name = "Integer Math";
ntype.ui_description = "Perform various math operations on the given integer inputs";
ntype.enum_name_legacy = "INTEGER_MATH";
@ -293,6 +354,7 @@ static void node_register()
ntype.labelfunc = node_label;
ntype.updatefunc = node_update;
ntype.build_multi_function = node_build_multi_function;
ntype.gpu_fn = node_gpu_material;
ntype.draw_buttons = node_layout;
ntype.gather_link_search_ops = node_gather_link_searches;
ntype.eval_elem = node_eval_elem;

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c9e5eab3c41faf837808ac32d8c12fd71b67146e7d2f6b938741e0ce883f3bc
size 18324

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e08a29bdc42047c58483eea2931b5012617559b0969c1008d2f900db1e1e8fa5
size 108900