Shading: Refactor Math node and use dynamic inputs.

- Implement dynamic inputs. The second input is now unavailable in single
operand math operators.
- Reimplemenet the clamp option using graph expansion for Cycles.
- Clean up code and unify naming between Blender and Cycles.
- Remove unused code.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D5481
This commit is contained in:
OmarSquircleArt 2019-08-18 11:16:04 +02:00
parent e12c17b305
commit e5618725fd
19 changed files with 416 additions and 682 deletions

View File

@ -326,10 +326,10 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeMath)) {
BL::ShaderNodeMath b_math_node(b_node);
MathNode *math = new MathNode();
math->type = (NodeMath)b_math_node.operation();
math->use_clamp = b_math_node.use_clamp();
node = math;
MathNode *math_node = new MathNode();
math_node->type = (NodeMathType)b_math_node.operation();
math_node->use_clamp = b_math_node.use_clamp();
node = math_node;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
BL::ShaderNodeVectorMath b_vector_math_node(b_node);

View File

@ -17,57 +17,31 @@
#include "stdosl.h"
float safe_divide(float a, float b)
{
float result;
if (b == 0.0)
result = 0.0;
else
result = a / b;
return result;
{
return (b != 0.0) ? a / b : 0.0;
}
float safe_modulo(float a, float b)
{
float result;
if (b == 0.0)
result = 0.0;
else
result = fmod(a, b);
return result;
return (b != 0.0) ? fmod(a, b) : 0.0;
}
float safe_sqrt(float a)
{
float result;
if (a > 0.0)
result = sqrt(a);
else
result = 0.0;
return result;
return (a > 0.0) ? sqrt(a) : 0.0;
}
float safe_log(float a, float b)
{
if (a < 0.0 || b < 0.0)
return 0.0;
return log(a) / log(b);
return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0;
}
/* OSL asin, acos, and pow functions are safe by default. */
shader node_math(string type = "add",
int use_clamp = 0,
float Value1 = 0.0,
float Value2 = 0.0,
float Value1 = 0.5,
float Value2 = 0.5,
output float Value = 0.0)
{
/* OSL asin, acos, pow check for values that could give rise to nan */
if (type == "add")
Value = Value1 + Value2;
else if (type == "subtract")
@ -76,6 +50,32 @@ shader node_math(string type = "add",
Value = Value1 * Value2;
else if (type == "divide")
Value = safe_divide(Value1, Value2);
else if (type == "power")
Value = pow(Value1, Value2);
else if (type == "logarithm")
Value = safe_log(Value1, Value2);
else if (type == "sqrt")
Value = safe_sqrt(Value1);
else if (type == "absolute")
Value = fabs(Value1);
else if (type == "minimum")
Value = min(Value1, Value2);
else if (type == "maximum")
Value = max(Value1, Value2);
else if (type == "less_than")
Value = Value1 < Value2;
else if (type == "greater_than")
Value = Value1 > Value2;
else if (type == "round")
Value = floor(Value1 + 0.5);
else if (type == "floor")
Value = floor(Value1);
else if (type == "ceil")
Value = ceil(Value1);
else if (type == "fraction")
Value = Value1 - floor(Value1);
else if (type == "modulo")
Value = safe_modulo(Value1, Value2);
else if (type == "sine")
Value = sin(Value1);
else if (type == "cosine")
@ -88,35 +88,8 @@ shader node_math(string type = "add",
Value = acos(Value1);
else if (type == "arctangent")
Value = atan(Value1);
else if (type == "power")
Value = pow(Value1, Value2);
else if (type == "logarithm")
Value = safe_log(Value1, Value2);
else if (type == "minimum")
Value = min(Value1, Value2);
else if (type == "maximum")
Value = max(Value1, Value2);
else if (type == "round")
Value = floor(Value1 + 0.5);
else if (type == "less_than")
Value = Value1 < Value2;
else if (type == "greater_than")
Value = Value1 > Value2;
else if (type == "modulo")
Value = safe_modulo(Value1, Value2);
else if (type == "absolute")
Value = fabs(Value1);
else if (type == "arctan2")
Value = atan2(Value1, Value2);
else if (type == "floor")
Value = floor(Value1);
else if (type == "ceil")
Value = ceil(Value1);
else if (type == "fract")
Value = Value1 - floor(Value1);
else if (type == "sqrt")
Value = safe_sqrt(Value1);
if (use_clamp)
Value = clamp(Value, 0.0, 1.0);
else
warning("%s", "Unknown math operator!");
}

View File

@ -16,24 +16,22 @@
CCL_NAMESPACE_BEGIN
/* Nodes */
ccl_device void svm_node_math(KernelGlobals *kg,
ShaderData *sd,
float *stack,
uint itype,
uint f1_offset,
uint f2_offset,
uint type,
uint inputs_stack_offsets,
uint result_stack_offset,
int *offset)
{
NodeMath type = (NodeMath)itype;
float f1 = stack_load_float(stack, f1_offset);
float f2 = stack_load_float(stack, f2_offset);
float f = svm_math(type, f1, f2);
uint a_stack_offset, b_stack_offset;
decode_node_uchar4(inputs_stack_offsets, &a_stack_offset, &b_stack_offset, NULL, NULL);
uint4 node1 = read_node(kg, offset);
float a = stack_load_float(stack, a_stack_offset);
float b = stack_load_float(stack, b_stack_offset);
float result = svm_math((NodeMathType)type, a, b);
stack_store_float(stack, node1.y, f);
stack_store_float(stack, result_stack_offset, result);
}
ccl_device void svm_node_vector_math(KernelGlobals *kg,

View File

@ -51,64 +51,60 @@ ccl_device void svm_vector_math(
}
}
ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
ccl_device float svm_math(NodeMathType type, float a, float b)
{
float Fac;
if (type == NODE_MATH_ADD)
Fac = Fac1 + Fac2;
else if (type == NODE_MATH_SUBTRACT)
Fac = Fac1 - Fac2;
else if (type == NODE_MATH_MULTIPLY)
Fac = Fac1 * Fac2;
else if (type == NODE_MATH_DIVIDE)
Fac = safe_divide(Fac1, Fac2);
else if (type == NODE_MATH_SINE)
Fac = sinf(Fac1);
else if (type == NODE_MATH_COSINE)
Fac = cosf(Fac1);
else if (type == NODE_MATH_TANGENT)
Fac = tanf(Fac1);
else if (type == NODE_MATH_ARCSINE)
Fac = safe_asinf(Fac1);
else if (type == NODE_MATH_ARCCOSINE)
Fac = safe_acosf(Fac1);
else if (type == NODE_MATH_ARCTANGENT)
Fac = atanf(Fac1);
else if (type == NODE_MATH_POWER)
Fac = safe_powf(Fac1, Fac2);
else if (type == NODE_MATH_LOGARITHM)
Fac = safe_logf(Fac1, Fac2);
else if (type == NODE_MATH_MINIMUM)
Fac = fminf(Fac1, Fac2);
else if (type == NODE_MATH_MAXIMUM)
Fac = fmaxf(Fac1, Fac2);
else if (type == NODE_MATH_ROUND)
Fac = floorf(Fac1 + 0.5f);
else if (type == NODE_MATH_LESS_THAN)
Fac = Fac1 < Fac2;
else if (type == NODE_MATH_GREATER_THAN)
Fac = Fac1 > Fac2;
else if (type == NODE_MATH_MODULO)
Fac = safe_modulo(Fac1, Fac2);
else if (type == NODE_MATH_ABSOLUTE)
Fac = fabsf(Fac1);
else if (type == NODE_MATH_ARCTAN2)
Fac = atan2f(Fac1, Fac2);
else if (type == NODE_MATH_FLOOR)
Fac = floorf(Fac1);
else if (type == NODE_MATH_CEIL)
Fac = ceilf(Fac1);
else if (type == NODE_MATH_FRACT)
Fac = Fac1 - floorf(Fac1);
else if (type == NODE_MATH_SQRT)
Fac = safe_sqrtf(Fac1);
else if (type == NODE_MATH_CLAMP)
Fac = saturate(Fac1);
else
Fac = 0.0f;
return Fac;
switch (type) {
case NODE_MATH_ADD:
return a + b;
case NODE_MATH_SUBTRACT:
return a - b;
case NODE_MATH_MULTIPLY:
return a * b;
case NODE_MATH_DIVIDE:
return safe_divide(a, b);
case NODE_MATH_POWER:
return safe_powf(a, b);
case NODE_MATH_LOGARITHM:
return safe_logf(a, b);
case NODE_MATH_SQRT:
return safe_sqrtf(a);
case NODE_MATH_ABSOLUTE:
return fabsf(a);
case NODE_MATH_MINIMUM:
return fminf(a, b);
case NODE_MATH_MAXIMUM:
return fmaxf(a, b);
case NODE_MATH_LESS_THAN:
return a < b;
case NODE_MATH_GREATER_THAN:
return a > b;
case NODE_MATH_ROUND:
return floorf(a + 0.5f);
case NODE_MATH_FLOOR:
return floorf(a);
case NODE_MATH_CEIL:
return ceilf(a);
case NODE_MATH_FRACTION:
return a - floorf(a);
case NODE_MATH_MODULO:
return safe_modulo(a, b);
case NODE_MATH_SINE:
return sinf(a);
case NODE_MATH_COSINE:
return cosf(a);
case NODE_MATH_TANGENT:
return tanf(a);
case NODE_MATH_ARCSINE:
return safe_asinf(a);
case NODE_MATH_ARCCOSINE:
return safe_acosf(a);
case NODE_MATH_ARCTANGENT:
return atanf(a);
case NODE_MATH_ARCTAN2:
return atan2f(a, b);
default:
return 0.0f;
}
}
/* Calculate color in range 800..12000 using an approximation

View File

@ -244,7 +244,7 @@ typedef enum NodeMix {
NODE_MIX_CLAMP /* used for the clamp UI option */
} NodeMix;
typedef enum NodeMath {
typedef enum NodeMathType {
NODE_MATH_ADD,
NODE_MATH_SUBTRACT,
NODE_MATH_MULTIPLY,
@ -267,10 +267,9 @@ typedef enum NodeMath {
NODE_MATH_ARCTAN2,
NODE_MATH_FLOOR,
NODE_MATH_CEIL,
NODE_MATH_FRACT,
NODE_MATH_FRACTION,
NODE_MATH_SQRT,
NODE_MATH_CLAMP /* used for the clamp UI option */
} NodeMath;
} NodeMathType;
typedef enum NodeVectorMath {
NODE_VECTOR_MATH_ADD,

View File

@ -301,7 +301,7 @@ void ConstantFolder::fold_mix(NodeMix type, bool clamp) const
}
}
void ConstantFolder::fold_math(NodeMath type, bool clamp) const
void ConstantFolder::fold_math(NodeMathType type) const
{
ShaderInput *value1_in = node->input("Value1");
ShaderInput *value2_in = node->input("Value2");
@ -310,25 +310,25 @@ void ConstantFolder::fold_math(NodeMath type, bool clamp) const
case NODE_MATH_ADD:
/* X + 0 == 0 + X == X */
if (is_zero(value1_in)) {
try_bypass_or_make_constant(value2_in, clamp);
try_bypass_or_make_constant(value2_in);
}
else if (is_zero(value2_in)) {
try_bypass_or_make_constant(value1_in, clamp);
try_bypass_or_make_constant(value1_in);
}
break;
case NODE_MATH_SUBTRACT:
/* X - 0 == X */
if (is_zero(value2_in)) {
try_bypass_or_make_constant(value1_in, clamp);
try_bypass_or_make_constant(value1_in);
}
break;
case NODE_MATH_MULTIPLY:
/* X * 1 == 1 * X == X */
if (is_one(value1_in)) {
try_bypass_or_make_constant(value2_in, clamp);
try_bypass_or_make_constant(value2_in);
}
else if (is_one(value2_in)) {
try_bypass_or_make_constant(value1_in, clamp);
try_bypass_or_make_constant(value1_in);
}
/* X * 0 == 0 * X == 0 */
else if (is_zero(value1_in) || is_zero(value2_in)) {
@ -338,7 +338,7 @@ void ConstantFolder::fold_math(NodeMath type, bool clamp) const
case NODE_MATH_DIVIDE:
/* X / 1 == X */
if (is_one(value2_in)) {
try_bypass_or_make_constant(value1_in, clamp);
try_bypass_or_make_constant(value1_in);
}
/* 0 / X == 0 */
else if (is_zero(value1_in)) {
@ -352,7 +352,7 @@ void ConstantFolder::fold_math(NodeMath type, bool clamp) const
}
/* X ^ 1 == X */
else if (is_one(value2_in)) {
try_bypass_or_make_constant(value1_in, clamp);
try_bypass_or_make_constant(value1_in);
}
default:
break;

View File

@ -64,7 +64,7 @@ class ConstantFolder {
/* Specific nodes. */
void fold_mix(NodeMix type, bool clamp) const;
void fold_math(NodeMath type, bool clamp) const;
void fold_math(NodeMathType type) const;
void fold_vector_math(NodeVectorMath type) const;
};

View File

@ -5422,14 +5422,12 @@ NODE_DEFINE(MathNode)
type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
type_enum.insert("floor", NODE_MATH_FLOOR);
type_enum.insert("ceil", NODE_MATH_CEIL);
type_enum.insert("fract", NODE_MATH_FRACT);
type_enum.insert("fraction", NODE_MATH_FRACTION);
type_enum.insert("sqrt", NODE_MATH_SQRT);
SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD);
SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
SOCKET_IN_FLOAT(value1, "Value1", 0.0f);
SOCKET_IN_FLOAT(value2, "Value2", 0.0f);
SOCKET_IN_FLOAT(value1, "Value1", 0.5f);
SOCKET_IN_FLOAT(value2, "Value2", 0.5f);
SOCKET_OUT_FLOAT(value, "Value");
@ -5440,13 +5438,28 @@ MathNode::MathNode() : ShaderNode(node_type)
{
}
void MathNode::expand(ShaderGraph *graph)
{
if (use_clamp) {
ShaderOutput *result_out = output("Value");
if (!result_out->links.empty()) {
ClampNode *clamp_node = new ClampNode();
clamp_node->min = 0.0f;
clamp_node->max = 1.0f;
graph->add(clamp_node);
graph->relink(result_out, clamp_node->output("Result"));
graph->connect(result_out, clamp_node->input("Value"));
}
}
}
void MathNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
folder.make_constant_clamp(svm_math(type, value1, value2), use_clamp);
folder.make_constant(svm_math(type, value1, value2));
}
else {
folder.fold_math(type, use_clamp);
folder.fold_math(type);
}
}
@ -5456,20 +5469,19 @@ void MathNode::compile(SVMCompiler &compiler)
ShaderInput *value2_in = input("Value2");
ShaderOutput *value_out = output("Value");
compiler.add_node(
NODE_MATH, type, compiler.stack_assign(value1_in), compiler.stack_assign(value2_in));
compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
int value1_stack_offset = compiler.stack_assign(value1_in);
int value2_stack_offset = compiler.stack_assign(value2_in);
int value_stack_offset = compiler.stack_assign(value_out);
if (use_clamp) {
compiler.add_node(NODE_MATH, NODE_MATH_CLAMP, compiler.stack_assign(value_out));
compiler.add_node(NODE_MATH, compiler.stack_assign(value_out));
}
compiler.add_node(NODE_MATH,
type,
compiler.encode_uchar4(value1_stack_offset, value2_stack_offset),
value_stack_offset);
}
void MathNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "type");
compiler.parameter(this, "use_clamp");
compiler.add(this, "node_math");
}

View File

@ -1260,11 +1260,12 @@ class MathNode : public ShaderNode {
{
return NODE_GROUP_LEVEL_1;
}
void expand(ShaderGraph *graph);
void constant_fold(const ConstantFolder &folder);
float value1;
float value2;
NodeMath type;
NodeMathType type;
bool use_clamp;
};

View File

@ -1003,7 +1003,7 @@ TEST_F(RenderGraph, constant_fold_math_clamp)
* Includes 2 tests: constant on each side.
*/
static void build_math_partial_test_graph(ShaderGraphBuilder &builder,
NodeMath type,
NodeMathType type,
float constval)
{
builder

View File

@ -615,6 +615,7 @@ void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node);
int nodeSocketIsHidden(struct bNodeSocket *sock);
void ntreeTagUsedSockets(struct bNodeTree *ntree);
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available);
/* Node Clipboard */
void BKE_node_clipboard_init(struct bNodeTree *ntree);

View File

@ -2799,6 +2799,16 @@ int nodeSocketIsHidden(bNodeSocket *sock)
return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0);
}
void nodeSetSocketAvailability(bNodeSocket *sock, bool is_available)
{
if (is_available) {
sock->flag &= ~SOCK_UNAVAIL;
}
else {
sock->flag |= SOCK_UNAVAIL;
}
}
/* ************** Node Clipboard *********** */
#define USE_NODE_CB_VALIDATE

View File

@ -26,6 +26,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "DNA_color_types.h"
@ -185,7 +186,7 @@ static void square_roughness_node_insert(bNodeTree *ntree)
/* Add sqrt node. */
bNode *node = nodeAddStaticNode(NULL, ntree, SH_NODE_MATH);
node->custom1 = NODE_MATH_POW;
node->custom1 = NODE_MATH_POWER;
node->locx = 0.5f * (fromnode->locx + tonode->locx);
node->locy = 0.5f * (fromnode->locy + tonode->locy);
@ -385,6 +386,46 @@ static void light_emission_unify(Light *light, const char *engine)
}
}
/* The B input of the Math node is no longer used for single-operand operators.
* Previously, if the B input was linked and the A input was not, the B input
* was used as the input of the operator. To correct this, we move the link
* from B to A if B is linked and A is not.
*/
static void update_math_node_single_operand_operators(bNodeTree *ntree)
{
bool need_update = false;
for (bNode *node = ntree->nodes.first; node; node = node->next) {
if (node->type == SH_NODE_MATH) {
if (ELEM(node->custom1,
NODE_MATH_SQRT,
NODE_MATH_CEIL,
NODE_MATH_SINE,
NODE_MATH_ROUND,
NODE_MATH_FLOOR,
NODE_MATH_COSINE,
NODE_MATH_ARCSINE,
NODE_MATH_TANGENT,
NODE_MATH_ABSOLUTE,
NODE_MATH_FRACTION,
NODE_MATH_ARCCOSINE,
NODE_MATH_ARCTANGENT)) {
bNodeSocket *sockA = BLI_findlink(&node->inputs, 0);
bNodeSocket *sockB = BLI_findlink(&node->inputs, 1);
if (!sockA->link && sockB->link) {
nodeAddLink(ntree, sockB->link->fromnode, sockB->link->fromsock, node, sockA);
nodeRemLink(ntree, sockB->link);
need_update = true;
}
}
}
}
if (need_update) {
ntreeUpdateTree(NULL, ntree);
}
}
void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain)
{
/* Particle shape shared with Eevee. */
@ -526,4 +567,13 @@ void do_versions_after_linking_cycles(Main *bmain)
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 281, 2)) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
update_math_node_single_operand_operators(ntree);
}
}
FOREACH_NODETREE_END;
}
}

View File

@ -29,61 +29,61 @@ void MathNode::convertToOperations(NodeConverter &converter,
case NODE_MATH_ADD:
operation = new MathAddOperation();
break;
case NODE_MATH_SUB:
case NODE_MATH_SUBTRACT:
operation = new MathSubtractOperation();
break;
case NODE_MATH_MUL:
case NODE_MATH_MULTIPLY:
operation = new MathMultiplyOperation();
break;
case NODE_MATH_DIVIDE:
operation = new MathDivideOperation();
break;
case NODE_MATH_SIN:
case NODE_MATH_SINE:
operation = new MathSineOperation();
break;
case NODE_MATH_COS:
case NODE_MATH_COSINE:
operation = new MathCosineOperation();
break;
case NODE_MATH_TAN:
case NODE_MATH_TANGENT:
operation = new MathTangentOperation();
break;
case NODE_MATH_ASIN:
case NODE_MATH_ARCSINE:
operation = new MathArcSineOperation();
break;
case NODE_MATH_ACOS:
case NODE_MATH_ARCCOSINE:
operation = new MathArcCosineOperation();
break;
case NODE_MATH_ATAN:
case NODE_MATH_ARCTANGENT:
operation = new MathArcTangentOperation();
break;
case NODE_MATH_POW:
case NODE_MATH_POWER:
operation = new MathPowerOperation();
break;
case NODE_MATH_LOG:
case NODE_MATH_LOGARITHM:
operation = new MathLogarithmOperation();
break;
case NODE_MATH_MIN:
case NODE_MATH_MINIMUM:
operation = new MathMinimumOperation();
break;
case NODE_MATH_MAX:
case NODE_MATH_MAXIMUM:
operation = new MathMaximumOperation();
break;
case NODE_MATH_ROUND:
operation = new MathRoundOperation();
break;
case NODE_MATH_LESS:
case NODE_MATH_LESS_THAN:
operation = new MathLessThanOperation();
break;
case NODE_MATH_GREATER:
case NODE_MATH_GREATER_THAN:
operation = new MathGreaterThanOperation();
break;
case NODE_MATH_MOD:
case NODE_MATH_MODULO:
operation = new MathModuloOperation();
break;
case NODE_MATH_ABS:
case NODE_MATH_ABSOLUTE:
operation = new MathAbsoluteOperation();
break;
case NODE_MATH_ATAN2:
case NODE_MATH_ARCTAN2:
operation = new MathArcTan2Operation();
break;
case NODE_MATH_FLOOR:
@ -92,7 +92,7 @@ void MathNode::convertToOperations(NodeConverter &converter,
case NODE_MATH_CEIL:
operation = new MathCeilOperation();
break;
case NODE_MATH_FRACT:
case NODE_MATH_FRACTION:
operation = new MathFractOperation();
break;
case NODE_MATH_SQRT:

View File

@ -250,178 +250,138 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
outview = normalize(co);
}
void math_add(float val1, float val2, out float outval)
void math_add(float a, float b, out float result)
{
outval = val1 + val2;
result = a + b;
}
void math_subtract(float val1, float val2, out float outval)
void math_subtract(float a, float b, out float result)
{
outval = val1 - val2;
result = a - b;
}
void math_multiply(float val1, float val2, out float outval)
void math_multiply(float a, float b, out float result)
{
outval = val1 * val2;
result = a * b;
}
void math_divide(float val1, float val2, out float outval)
void math_divide(float a, float b, out float result)
{
if (val2 == 0.0) {
outval = 0.0;
result = (b != 0.0) ? a / b : 0.0;
}
void math_power(float a, float b, out float result)
{
if (a >= 0.0) {
result = compatible_pow(a, b);
}
else {
outval = val1 / val2;
}
}
void math_sine(float val, out float outval)
{
outval = sin(val);
}
void math_cosine(float val, out float outval)
{
outval = cos(val);
}
void math_tangent(float val, out float outval)
{
outval = tan(val);
}
void math_asin(float val, out float outval)
{
if (val <= 1.0 && val >= -1.0) {
outval = asin(val);
}
else {
outval = 0.0;
}
}
void math_acos(float val, out float outval)
{
if (val <= 1.0 && val >= -1.0) {
outval = acos(val);
}
else {
outval = 0.0;
}
}
void math_atan(float val, out float outval)
{
outval = atan(val);
}
void math_pow(float val1, float val2, out float outval)
{
if (val1 >= 0.0) {
outval = compatible_pow(val1, val2);
}
else {
float val2_mod_1 = mod(abs(val2), 1.0);
if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001) {
outval = compatible_pow(val1, floor(val2 + 0.5));
float fraction = mod(abs(b), 1.0);
if (fraction > 0.999 || fraction < 0.001) {
result = compatible_pow(a, floor(b + 0.5));
}
else {
outval = 0.0;
result = 0.0;
}
}
}
void math_log(float val1, float val2, out float outval)
void math_logarithm(float a, float b, out float result)
{
if (val1 > 0.0 && val2 > 0.0) {
outval = log2(val1) / log2(val2);
}
else {
outval = 0.0;
}
result = (a > 0.0 && b > 0.0) ? log2(a) / log2(b) : 0.0;
}
void math_max(float val1, float val2, out float outval)
void math_sqrt(float a, float b, out float result)
{
outval = max(val1, val2);
result = (a > 0.0) ? sqrt(a) : 0.0;
}
void math_min(float val1, float val2, out float outval)
void math_absolute(float a, float b, out float result)
{
outval = min(val1, val2);
result = abs(a);
}
void math_round(float val, out float outval)
void math_minimum(float a, float b, out float result)
{
outval = floor(val + 0.5);
result = min(a, b);
}
void math_less_than(float val1, float val2, out float outval)
void math_maximum(float a, float b, out float result)
{
if (val1 < val2) {
outval = 1.0;
}
else {
outval = 0.0;
}
result = max(a, b);
}
void math_greater_than(float val1, float val2, out float outval)
void math_less_than(float a, float b, out float result)
{
if (val1 > val2) {
outval = 1.0;
}
else {
outval = 0.0;
}
result = (a < b) ? 1.0 : 0.0;
}
void math_modulo(float val1, float val2, out float outval)
void math_greater_than(float a, float b, out float result)
{
if (val2 == 0.0 || val1 == val2) {
outval = 0.0;
}
else {
/* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
* see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
outval = sign(val1) * mod(abs(val1), val2);
}
result = (a > b) ? 1.0 : 0.0;
}
void math_abs(float val1, out float outval)
void math_round(float a, float b, out float result)
{
outval = abs(val1);
result = floor(a + 0.5);
}
void math_atan2(float val1, float val2, out float outval)
void math_floor(float a, float b, out float result)
{
outval = atan(val1, val2);
result = floor(a);
}
void math_floor(float val, out float outval)
void math_ceil(float a, float b, out float result)
{
outval = floor(val);
result = ceil(a);
}
void math_ceil(float val, out float outval)
void math_fraction(float a, float b, out float result)
{
outval = ceil(val);
result = a - floor(a);
}
void math_fract(float val, out float outval)
/* Change sign to match C convention. mod in GLSL will take absolute for negative numbers.
* See https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/mod.xhtml
*/
void math_modulo(float a, float b, out float result)
{
outval = val - floor(val);
result = (b != 0.0) ? sign(a) * mod(abs(a), b) : 0.0;
}
void math_sqrt(float val, out float outval)
void math_sine(float a, float b, out float result)
{
if (val > 0.0) {
outval = sqrt(val);
}
else {
outval = 0.0;
}
result = sin(a);
}
void math_cosine(float a, float b, out float result)
{
result = cos(a);
}
void math_tangent(float a, float b, out float result)
{
result = tan(a);
}
void math_arcsine(float a, float b, out float result)
{
result = (a <= 1.0 && a >= -1.0) ? asin(a) : 0.0;
}
void math_arccosine(float a, float b, out float result)
{
result = (a <= 1.0 && a >= -1.0) ? acos(a) : 0.0;
}
void math_arctangent(float a, float b, out float result)
{
result = atan(a);
}
void math_arctan2(float a, float b, out float result)
{
result = atan(a, b);
}
void squeeze(float val, float width, float center, out float outval)

View File

@ -1167,31 +1167,31 @@ typedef struct NodeDenoise {
/* math node clamp */
#define SHD_MATH_CLAMP 1
/* Math node operation/ */
/* Math node operations. */
enum {
NODE_MATH_ADD = 0,
NODE_MATH_SUB = 1,
NODE_MATH_MUL = 2,
NODE_MATH_SUBTRACT = 1,
NODE_MATH_MULTIPLY = 2,
NODE_MATH_DIVIDE = 3,
NODE_MATH_SIN = 4,
NODE_MATH_COS = 5,
NODE_MATH_TAN = 6,
NODE_MATH_ASIN = 7,
NODE_MATH_ACOS = 8,
NODE_MATH_ATAN = 9,
NODE_MATH_POW = 10,
NODE_MATH_LOG = 11,
NODE_MATH_MIN = 12,
NODE_MATH_MAX = 13,
NODE_MATH_SINE = 4,
NODE_MATH_COSINE = 5,
NODE_MATH_TANGENT = 6,
NODE_MATH_ARCSINE = 7,
NODE_MATH_ARCCOSINE = 8,
NODE_MATH_ARCTANGENT = 9,
NODE_MATH_POWER = 10,
NODE_MATH_LOGARITHM = 11,
NODE_MATH_MINIMUM = 12,
NODE_MATH_MAXIMUM = 13,
NODE_MATH_ROUND = 14,
NODE_MATH_LESS = 15,
NODE_MATH_GREATER = 16,
NODE_MATH_MOD = 17,
NODE_MATH_ABS = 18,
NODE_MATH_ATAN2 = 19,
NODE_MATH_LESS_THAN = 15,
NODE_MATH_GREATER_THAN = 16,
NODE_MATH_MODULO = 17,
NODE_MATH_ABSOLUTE = 18,
NODE_MATH_ARCTAN2 = 19,
NODE_MATH_FLOOR = 20,
NODE_MATH_CEIL = 21,
NODE_MATH_FRACT = 22,
NODE_MATH_FRACTION = 22,
NODE_MATH_SQRT = 23,
};

View File

@ -100,34 +100,38 @@ static const EnumPropertyItem node_chunksize_items[] = {
#endif
const EnumPropertyItem rna_enum_node_math_items[] = {
{NODE_MATH_ADD, "ADD", 0, "Add", ""},
{NODE_MATH_SUB, "SUBTRACT", 0, "Subtract", ""},
{NODE_MATH_MUL, "MULTIPLY", 0, "Multiply", ""},
{NODE_MATH_DIVIDE, "DIVIDE", 0, "Divide", ""},
{NODE_MATH_ADD, "ADD", 0, "Add", "A + B"},
{NODE_MATH_SUBTRACT, "SUBTRACT", 0, "Subtract", "A - B"},
{NODE_MATH_MULTIPLY, "MULTIPLY", 0, "Multiply", "A * B"},
{NODE_MATH_DIVIDE, "DIVIDE", 0, "Divide", "A / B"},
{0, "", ICON_NONE, NULL, NULL},
{NODE_MATH_POW, "POWER", 0, "Power", ""},
{NODE_MATH_LOG, "LOGARITHM", 0, "Logarithm", ""},
{NODE_MATH_SQRT, "SQRT", 0, "Square Root", ""},
{NODE_MATH_ABS, "ABSOLUTE", 0, "Absolute", ""},
{NODE_MATH_POWER, "POWER", 0, "Power", "A power B"},
{NODE_MATH_LOGARITHM, "LOGARITHM", 0, "Logarithm", "Logarithm A base B"},
{NODE_MATH_SQRT, "SQRT", 0, "Square Root", "Square root of A"},
{NODE_MATH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Magnitude of A"},
{0, "", ICON_NONE, NULL, NULL},
{NODE_MATH_MIN, "MINIMUM", 0, "Minimum", ""},
{NODE_MATH_MAX, "MAXIMUM", 0, "Maximum", ""},
{NODE_MATH_LESS, "LESS_THAN", 0, "Less Than", ""},
{NODE_MATH_GREATER, "GREATER_THAN", 0, "Greater Than", ""},
{NODE_MATH_MINIMUM, "MINIMUM", 0, "Minimum", "The minimum from A and B"},
{NODE_MATH_MAXIMUM, "MAXIMUM", 0, "Maximum", "The maximum from A and B"},
{NODE_MATH_LESS_THAN, "LESS_THAN", 0, "Less Than", "1 if A < B else 0"},
{NODE_MATH_GREATER_THAN, "GREATER_THAN", 0, "Greater Than", "1 if A > B else 0"},
{0, "", ICON_NONE, NULL, NULL},
{NODE_MATH_ROUND, "ROUND", 0, "Round", ""},
{NODE_MATH_FLOOR, "FLOOR", 0, "Floor", ""},
{NODE_MATH_CEIL, "CEIL", 0, "Ceil", ""},
{NODE_MATH_FRACT, "FRACT", 0, "Fract", ""},
{NODE_MATH_MOD, "MODULO", 0, "Modulo", ""},
{NODE_MATH_ROUND,
"ROUND",
0,
"Round",
"Round A to the nearest integer. Round upward if the fraction part is 0.5"},
{NODE_MATH_FLOOR, "FLOOR", 0, "Floor", "The largest integer smaller than or equal A"},
{NODE_MATH_CEIL, "CEIL", 0, "Ceil", "The smallest integer greater than or equal A"},
{NODE_MATH_FRACTION, "FRACT", 0, "Fraction", "The fraction part of A"},
{NODE_MATH_MODULO, "MODULO", 0, "Modulo", "A mod B"},
{0, "", ICON_NONE, NULL, NULL},
{NODE_MATH_SIN, "SINE", 0, "Sine", ""},
{NODE_MATH_COS, "COSINE", 0, "Cosine", ""},
{NODE_MATH_TAN, "TANGENT", 0, "Tangent", ""},
{NODE_MATH_ASIN, "ARCSINE", 0, "Arcsine", ""},
{NODE_MATH_ACOS, "ARCCOSINE", 0, "Arccosine", ""},
{NODE_MATH_ATAN, "ARCTANGENT", 0, "Arctangent", ""},
{NODE_MATH_ATAN2, "ARCTAN2", 0, "Arctan2", ""},
{NODE_MATH_SINE, "SINE", 0, "Sine", "sin(A)"},
{NODE_MATH_COSINE, "COSINE", 0, "Cosine", "cos(A)"},
{NODE_MATH_TANGENT, "TANGENT", 0, "Tangent", "tan(A)"},
{NODE_MATH_ARCSINE, "ARCSINE", 0, "Arcsine", "arcsin(A)"},
{NODE_MATH_ARCCOSINE, "ARCCOSINE", 0, "Arccosine", "arccos(A)"},
{NODE_MATH_ARCTANGENT, "ARCTANGENT", 0, "Arctangent", "arctan(A)"},
{NODE_MATH_ARCTAN2, "ARCTAN2", 0, "Arctan2", "The signed angle arctan(A / B)"},
{0, NULL, 0, NULL, NULL},
};
@ -3852,7 +3856,7 @@ static void def_math(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_math_items);
RNA_def_property_ui_text(prop, "Operation", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MATH_CLAMP);

View File

@ -31,272 +31,6 @@ static bNodeSocketTemplate sh_node_math_in[] = {
static bNodeSocketTemplate sh_node_math_out[] = {{SOCK_FLOAT, 0, N_("Value")}, {-1, 0, ""}};
static void node_shader_exec_math(void *UNUSED(data),
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float a, b, r = 0.0f;
nodestack_get_vec(&a, SOCK_FLOAT, in[0]);
nodestack_get_vec(&b, SOCK_FLOAT, in[1]);
switch (node->custom1) {
case NODE_MATH_ADD:
r = a + b;
break;
case NODE_MATH_SUB:
r = a - b;
break;
case NODE_MATH_MUL:
r = a * b;
break;
case NODE_MATH_DIVIDE: {
if (b == 0) { /* We don't want to divide by zero. */
r = 0.0;
}
else {
r = a / b;
}
break;
}
case NODE_MATH_SIN: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = sinf(a);
}
else {
r = sinf(b);
}
break;
}
case NODE_MATH_COS: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = cosf(a);
}
else {
r = cosf(b);
}
break;
}
case NODE_MATH_TAN: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = tanf(a);
}
else {
r = tanf(b);
}
break;
}
case NODE_MATH_ASIN: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
/* Can't do the impossible... */
if (a <= 1 && a >= -1) {
r = asinf(a);
}
else {
r = 0.0;
}
}
else {
/* Can't do the impossible... */
if (b <= 1 && b >= -1) {
r = asinf(b);
}
else {
r = 0.0;
}
}
break;
}
case NODE_MATH_ACOS: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
/* Can't do the impossible... */
if (a <= 1 && a >= -1) {
r = acosf(a);
}
else {
r = 0.0;
}
}
else {
/* Can't do the impossible... */
if (b <= 1 && b >= -1) {
r = acosf(b);
}
else {
r = 0.0;
}
}
break;
}
case NODE_MATH_ATAN: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = atan(a);
}
else {
r = atan(b);
}
break;
}
case NODE_MATH_POW: {
/* Only raise negative numbers by full integers */
if (a >= 0) {
r = pow(a, b);
}
else {
float y_mod_1 = fabsf(fmodf(b, 1.0f));
/* if input value is not nearly an integer,
* fall back to zero, nicer than straight rounding. */
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
r = powf(a, floorf(b + 0.5f));
}
else {
r = 0.0f;
}
}
break;
}
case NODE_MATH_LOG: {
/* Don't want any imaginary numbers... */
if (a > 0 && b > 0) {
r = log(a) / log(b);
}
else {
r = 0.0;
}
break;
}
case NODE_MATH_MIN: {
if (a < b) {
r = a;
}
else {
r = b;
}
break;
}
case NODE_MATH_MAX: {
if (a > b) {
r = a;
}
else {
r = b;
}
break;
}
case NODE_MATH_ROUND: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f);
}
else {
r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f);
}
break;
}
case NODE_MATH_LESS: {
if (a < b) {
r = 1.0f;
}
else {
r = 0.0f;
}
break;
}
case NODE_MATH_GREATER: {
if (a > b) {
r = 1.0f;
}
else {
r = 0.0f;
}
break;
}
case NODE_MATH_MOD: {
if (b == 0.0f) {
r = 0.0f;
}
else {
r = fmod(a, b);
}
break;
}
case NODE_MATH_ABS: {
r = fabsf(a);
break;
}
case NODE_MATH_ATAN2: {
r = atan2(a, b);
break;
}
case NODE_MATH_FLOOR: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = floorf(a);
}
else {
r = floorf(b);
}
break;
}
case NODE_MATH_CEIL: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = ceilf(a);
}
else {
r = ceilf(b);
}
break;
}
case NODE_MATH_FRACT: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
r = a - floorf(a);
}
else {
r = b - floorf(b);
}
break;
}
case NODE_MATH_SQRT: {
/* This one only takes one input, so we've got to choose. */
if (in[0]->hasinput || !in[1]->hasinput) {
if (a > 0) {
r = sqrt(a);
}
else {
r = 0.0;
}
}
else {
if (b > 0) {
r = sqrt(b);
}
else {
r = 0.0;
}
}
break;
}
}
if (node->custom2 & SHD_MATH_CLAMP) {
CLAMP(r, 0.0f, 1.0f);
}
out[0]->vec[0] = r;
}
static int gpu_shader_math(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
@ -304,68 +38,65 @@ static int gpu_shader_math(GPUMaterial *mat,
GPUNodeStack *out)
{
static const char *names[] = {
"math_add", "math_subtract", "math_multiply", "math_divide", "math_sine",
"math_cosine", "math_tangent", "math_asin", "math_acos", "math_atan",
"math_pow", "math_log", "math_min", "math_max", "math_round",
"math_less_than", "math_greater_than", "math_modulo", "math_abs", "math_atan2",
"math_floor", "math_ceil", "math_fract", "math_sqrt",
[NODE_MATH_ADD] = "math_add",
[NODE_MATH_SUBTRACT] = "math_subtract",
[NODE_MATH_MULTIPLY] = "math_multiply",
[NODE_MATH_DIVIDE] = "math_divide",
[NODE_MATH_POWER] = "math_power",
[NODE_MATH_LOGARITHM] = "math_logarithm",
[NODE_MATH_SQRT] = "math_sqrt",
[NODE_MATH_ABSOLUTE] = "math_absolute",
[NODE_MATH_MINIMUM] = "math_minimum",
[NODE_MATH_MAXIMUM] = "math_maximum",
[NODE_MATH_LESS_THAN] = "math_less_than",
[NODE_MATH_GREATER_THAN] = "math_greater_than",
[NODE_MATH_ROUND] = "math_round",
[NODE_MATH_FLOOR] = "math_floor",
[NODE_MATH_CEIL] = "math_ceil",
[NODE_MATH_FRACTION] = "math_fraction",
[NODE_MATH_MODULO] = "math_modulo",
[NODE_MATH_SINE] = "math_sine",
[NODE_MATH_COSINE] = "math_cosine",
[NODE_MATH_TANGENT] = "math_tangent",
[NODE_MATH_ARCSINE] = "math_arcsine",
[NODE_MATH_ARCCOSINE] = "math_arccosine",
[NODE_MATH_ARCTANGENT] = "math_arctangent",
[NODE_MATH_ARCTAN2] = "math_arctan2",
};
switch (node->custom1) {
case NODE_MATH_ADD:
case NODE_MATH_SUB:
case NODE_MATH_MUL:
case NODE_MATH_DIVIDE:
case NODE_MATH_POW:
case NODE_MATH_LOG:
case NODE_MATH_MIN:
case NODE_MATH_MAX:
case NODE_MATH_LESS:
case NODE_MATH_GREATER:
case NODE_MATH_MOD:
case NODE_MATH_ATAN2:
GPU_stack_link(mat, node, names[node->custom1], in, out);
break;
case NODE_MATH_SIN:
case NODE_MATH_COS:
case NODE_MATH_TAN:
case NODE_MATH_ASIN:
case NODE_MATH_ACOS:
case NODE_MATH_ATAN:
case NODE_MATH_ROUND:
case NODE_MATH_ABS:
case NODE_MATH_FLOOR:
case NODE_MATH_FRACT:
case NODE_MATH_CEIL:
case NODE_MATH_SQRT:
if (in[0].hasinput || !in[1].hasinput) {
/* use only first item and terminator */
GPUNodeStack tmp_in[2];
memcpy(&tmp_in[0], &in[0], sizeof(GPUNodeStack));
memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack));
GPU_stack_link(mat, node, names[node->custom1], tmp_in, out);
}
else {
/* use only second item and terminator */
GPUNodeStack tmp_in[2];
memcpy(&tmp_in[0], &in[1], sizeof(GPUNodeStack));
memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack));
GPU_stack_link(mat, node, names[node->custom1], tmp_in, out);
}
break;
default:
return 0;
}
GPU_stack_link(mat, node, names[node->custom1], in, out);
if (node->custom2 & SHD_MATH_CLAMP) {
float min[3] = {0.0f, 0.0f, 0.0f};
float max[3] = {1.0f, 1.0f, 1.0f};
GPU_link(mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
}
return 1;
}
static void node_shader_update_math(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock = BLI_findlink(&node->inputs, 1);
nodeSetSocketAvailability(sock,
!ELEM(node->custom1,
NODE_MATH_SQRT,
NODE_MATH_CEIL,
NODE_MATH_SINE,
NODE_MATH_ROUND,
NODE_MATH_FLOOR,
NODE_MATH_COSINE,
NODE_MATH_ARCSINE,
NODE_MATH_TANGENT,
NODE_MATH_ABSOLUTE,
NODE_MATH_FRACTION,
NODE_MATH_ARCCOSINE,
NODE_MATH_ARCTANGENT));
}
void register_node_type_sh_math(void)
{
static bNodeType ntype;
@ -373,9 +104,8 @@ void register_node_type_sh_math(void)
sh_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out);
node_type_label(&ntype, node_math_label);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_math);
node_type_gpu(&ntype, gpu_shader_math);
node_type_update(&ntype, node_shader_update_math);
nodeRegisterType(&ntype);
}

View File

@ -46,10 +46,10 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
case NODE_MATH_ADD:
*out = in0 + in1;
break;
case NODE_MATH_SUB:
case NODE_MATH_SUBTRACT:
*out = in0 - in1;
break;
case NODE_MATH_MUL:
case NODE_MATH_MULTIPLY:
*out = in0 * in1;
break;
case NODE_MATH_DIVIDE: {
@ -62,19 +62,19 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_SIN: {
case NODE_MATH_SINE: {
*out = sinf(in0);
break;
}
case NODE_MATH_COS: {
case NODE_MATH_COSINE: {
*out = cosf(in0);
break;
}
case NODE_MATH_TAN: {
case NODE_MATH_TANGENT: {
*out = tanf(in0);
break;
}
case NODE_MATH_ASIN: {
case NODE_MATH_ARCSINE: {
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1) {
*out = asinf(in0);
@ -84,7 +84,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_ACOS: {
case NODE_MATH_ARCCOSINE: {
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1) {
*out = acosf(in0);
@ -94,11 +94,11 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_ATAN: {
case NODE_MATH_ARCTANGENT: {
*out = atan(in0);
break;
}
case NODE_MATH_POW: {
case NODE_MATH_POWER: {
/* Only raise negative numbers by full integers */
if (in0 >= 0) {
out[0] = pow(in0, in1);
@ -114,7 +114,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_LOG: {
case NODE_MATH_LOGARITHM: {
/* Don't want any imaginary numbers... */
if (in0 > 0 && in1 > 0) {
*out = log(in0) / log(in1);
@ -124,7 +124,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_MIN: {
case NODE_MATH_MINIMUM: {
if (in0 < in1) {
*out = in0;
}
@ -133,7 +133,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
case NODE_MATH_MAX: {
case NODE_MATH_MAXIMUM: {
if (in0 > in1) {
*out = in0;
}
@ -147,7 +147,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
case NODE_MATH_LESS: {
case NODE_MATH_LESS_THAN: {
if (in0 < in1) {
*out = 1.0f;
}
@ -157,7 +157,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
case NODE_MATH_GREATER: {
case NODE_MATH_GREATER_THAN: {
if (in0 > in1) {
*out = 1.0f;
}
@ -167,7 +167,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
case NODE_MATH_MOD: {
case NODE_MATH_MODULO: {
if (in1 == 0.0f) {
*out = 0.0f;
}
@ -177,12 +177,12 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
case NODE_MATH_ABS: {
case NODE_MATH_ABSOLUTE: {
*out = fabsf(in0);
break;
}
case NODE_MATH_ATAN2: {
case NODE_MATH_ARCTAN2: {
*out = atan2(in0, in1);
break;
}
@ -197,7 +197,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
case NODE_MATH_FRACT: {
case NODE_MATH_FRACTION: {
*out = in0 - floorf(in0);
break;
}