forked from bartvdbraak/blender
Math Node:
* Added a Modulo operation to the math node, available in Compositor, Shader and Texture Nodes.
This commit is contained in:
parent
0fb5c9117f
commit
38dc85f296
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user