Math Node:

* Added a Modulo operation to the math node, available in Compositor, Shader and Texture Nodes.
This commit is contained in:
Thomas Dinges 2013-05-20 14:38:47 +00:00
parent 0fb5c9117f
commit 38dc85f296
12 changed files with 74 additions and 1 deletions

@ -30,6 +30,18 @@ float safe_divide(float a, float b)
return result;
}
float safe_modulo(float a, float b)
{
float result;
if (b == 0.0)
result = 0.0;
else
result = fmod(a, b);
return result;
}
float safe_log(float a, float b)
{
if (a < 0.0 || b < 0.0)
@ -81,6 +93,8 @@ shader node_math(
Value = Value1 < Value2;
else if (type == "Greater Than")
Value = Value1 > Value2;
else if (type == "Modulo")
Value = safe_modulo(Value1, Value2);
if (Clamp)
Value = clamp(Value1, 0.0, 1.0);

@ -56,6 +56,8 @@ __device float svm_math(NodeMath type, float Fac1, float Fac2)
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_CLAMP)
Fac = clamp(Fac1, 0.0f, 1.0f);
else

@ -210,6 +210,7 @@ typedef enum NodeMath {
NODE_MATH_ROUND,
NODE_MATH_LESS_THAN,
NODE_MATH_GREATER_THAN,
NODE_MATH_MODULO,
NODE_MATH_CLAMP /* used for the clamp UI option */
} NodeMath;

@ -2959,6 +2959,7 @@ static ShaderEnum math_type_init()
enm.insert("Round", NODE_MATH_ROUND);
enm.insert("Less Than", NODE_MATH_LESS_THAN);
enm.insert("Greater Than", NODE_MATH_GREATER_THAN);
enm.insert("Modulo", NODE_MATH_MODULO);
return enm;
}

@ -1166,6 +1166,11 @@ __device float safe_divide(float a, float b)
return (b != 0.0f)? a/b: 0.0f;
}
__device float safe_modulo(float a, float b)
{
return (b != 0.0f)? fmodf(a, b): 0.0f;
}
/* Ray Intersection */
__device bool ray_sphere_intersect(

@ -80,6 +80,9 @@ void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
case 16: /* Greater Than */
operation = new MathGreaterThanOperation();
break;
case 17: /* Modulo */
operation = new MathModuloOperation();
break;
}
if (operation != NULL) {

@ -317,4 +317,19 @@ void MathGreaterThanOperation::executePixel(float output[4], float x, float y, P
clampIfNeeded(output);
}
void MathModuloOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputValue1[4];
float inputValue2[4];
this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
if (inputValue2[0] == 0)
output[0] = 0.0;
else
output[0] = fmod(inputValue1[0], inputValue2[0]);
clampIfNeeded(output);
}

@ -157,4 +157,10 @@ public:
void executePixel(float output[4], float x, float y, PixelSampler sampler);
};
class MathModuloOperation : public MathBaseOperation {
public:
MathModuloOperation() : MathBaseOperation() {}
void executePixel(float output[4], float x, float y, PixelSampler sampler);
};
#endif

@ -279,6 +279,14 @@ void math_greater_than(float val1, float val2, out float outval)
outval = 0.0;
}
void math_modulo(float val1, float val2, out float outval)
{
if (val2 == 0.0)
outval = 0.0;
else
outval = mod(val1, val2);
}
void squeeze(float val, float width, float center, out float outval)
{
outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));

@ -127,6 +127,7 @@ EnumPropertyItem node_math_items[] = {
{14, "ROUND", 0, "Round", ""},
{15, "LESS_THAN", 0, "Less Than", ""},
{16, "GREATER_THAN", 0, "Greater Than", ""},
{17, "MODULO", 0, "Modulo", ""},
{0, NULL, 0, NULL, NULL}
};

@ -203,6 +203,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
out[0]->vec[0] = 0.0f;
}
break;
case 17: /* Modulo */
{
if (in[1]->vec[0] == 0.0f)
out[0]->vec[0] = 0.0f;
else
out[0]->vec[0] = fmod(in[0]->vec[0], in[1]->vec[0]);
}
break;
}
}
@ -211,7 +219,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
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_round", "math_less_than", "math_greater_than", "math_modulo"};
switch (node->custom1) {
case 0:

@ -174,6 +174,15 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
case 17: /* Modulo */
{
if (in1 == 0.0f)
*out = 0.0f;
else
*out= fmod(in0, in1);
}
break;
default:
fprintf(stderr,
"%s:%d: unhandeld value in switch statement: %d\n",