Both the `Math` node and the `Vector Math` currently only explicitly support modulo using truncated division which is oftentimes not the type of modulo desired as it behaves differently for negative numbers and positive numbers. Floored Modulo can be created by either using the `Wrap` operation or a combination of multiple `Math` nodes. However both methods obfuscate the actual intend of the artist and the math operation that is actually used. This patch adds modulo using floored division to the scalar `Math` node, explicitly stating the intended math operation and renames the already existing `"Modulo"` operation to `"Truncated Modulo"` to avoid confusion. Only the ui name is changed, so this should not break compatibility. Pull Request: https://projects.blender.org/blender/blender/pulls/110728
100 lines
3.2 KiB
Plaintext
100 lines
3.2 KiB
Plaintext
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
#include "node_math.h"
|
|
#include "stdcycles.h"
|
|
|
|
/* OSL asin, acos, and pow functions are safe by default. */
|
|
shader node_math(string math_type = "add",
|
|
float Value1 = 0.5,
|
|
float Value2 = 0.5,
|
|
float Value3 = 0.5,
|
|
output float Value = 0.0)
|
|
{
|
|
if (math_type == "add")
|
|
Value = Value1 + Value2;
|
|
else if (math_type == "subtract")
|
|
Value = Value1 - Value2;
|
|
else if (math_type == "multiply")
|
|
Value = Value1 * Value2;
|
|
else if (math_type == "divide")
|
|
Value = safe_divide(Value1, Value2);
|
|
else if (math_type == "power")
|
|
Value = pow(Value1, Value2);
|
|
else if (math_type == "logarithm")
|
|
Value = safe_log(Value1, Value2);
|
|
else if (math_type == "sqrt")
|
|
Value = safe_sqrt(Value1);
|
|
else if (math_type == "inversesqrt")
|
|
Value = inversesqrt(Value1);
|
|
else if (math_type == "absolute")
|
|
Value = fabs(Value1);
|
|
else if (math_type == "radians")
|
|
Value = radians(Value1);
|
|
else if (math_type == "degrees")
|
|
Value = degrees(Value1);
|
|
else if (math_type == "minimum")
|
|
Value = min(Value1, Value2);
|
|
else if (math_type == "maximum")
|
|
Value = max(Value1, Value2);
|
|
else if (math_type == "less_than")
|
|
Value = Value1 < Value2;
|
|
else if (math_type == "greater_than")
|
|
Value = Value1 > Value2;
|
|
else if (math_type == "round")
|
|
Value = floor(Value1 + 0.5);
|
|
else if (math_type == "floor")
|
|
Value = floor(Value1);
|
|
else if (math_type == "ceil")
|
|
Value = ceil(Value1);
|
|
else if (math_type == "fraction")
|
|
Value = Value1 - floor(Value1);
|
|
else if (math_type == "modulo")
|
|
Value = safe_modulo(Value1, Value2);
|
|
else if (math_type == "floored_modulo")
|
|
Value = safe_floored_modulo(Value1, Value2);
|
|
else if (math_type == "trunc")
|
|
Value = trunc(Value1);
|
|
else if (math_type == "snap")
|
|
Value = floor(safe_divide(Value1, Value2)) * Value2;
|
|
else if (math_type == "wrap")
|
|
Value = wrap(Value1, Value2, Value3);
|
|
else if (math_type == "pingpong")
|
|
Value = pingpong(Value1, Value2);
|
|
else if (math_type == "sine")
|
|
Value = sin(Value1);
|
|
else if (math_type == "cosine")
|
|
Value = cos(Value1);
|
|
else if (math_type == "tangent")
|
|
Value = tan(Value1);
|
|
else if (math_type == "sinh")
|
|
Value = sinh(Value1);
|
|
else if (math_type == "cosh")
|
|
Value = cosh(Value1);
|
|
else if (math_type == "tanh")
|
|
Value = tanh(Value1);
|
|
else if (math_type == "arcsine")
|
|
Value = asin(Value1);
|
|
else if (math_type == "arccosine")
|
|
Value = acos(Value1);
|
|
else if (math_type == "arctangent")
|
|
Value = atan(Value1);
|
|
else if (math_type == "arctan2")
|
|
Value = atan2(Value1, Value2);
|
|
else if (math_type == "sign")
|
|
Value = sign(Value1);
|
|
else if (math_type == "exponent")
|
|
Value = exp(Value1);
|
|
else if (math_type == "compare")
|
|
Value = ((Value1 == Value2) || (abs(Value1 - Value2) <= max(Value3, 1e-5))) ? 1.0 : 0.0;
|
|
else if (math_type == "multiply_add")
|
|
Value = Value1 * Value2 + Value3;
|
|
else if (math_type == "smoothmin")
|
|
Value = smoothmin(Value1, Value2, Value3);
|
|
else if (math_type == "smoothmax")
|
|
Value = -(smoothmin(-Value1, -Value2, Value3));
|
|
else
|
|
warning("%s", "Unknown math operator!");
|
|
}
|