Index: intern/cycles/kernel/svm/svm_math.h =================================================================== --- intern/cycles/kernel/svm/svm_math.h (revision 50667) +++ intern/cycles/kernel/svm/svm_math.h (working copy) @@ -108,6 +108,16 @@ Fac = Fac1 < Fac2; else if(type == NODE_MATH_GREATER_THAN) Fac = Fac1 > Fac2; + else if(type == NODE_MATH_EQUALS) + Fac = Fac1 == Fac2; + else if(type == NODE_MATH_NOT) + Fac = 1-Fac1; + else if(type == NODE_MATH_AND) + Fac = (int)Fac1 & (int)Fac2; + else if(type == NODE_MATH_OR) + Fac = (int)Fac1 | (int)Fac2; + else if(type == NODE_MATH_XOR) + Fac = (int)Fac1 ^ (int)Fac2; else if(type == NODE_MATH_CLAMP) Fac = clamp(Fac1, 0.0f, 1.0f); else Index: intern/cycles/kernel/svm/svm_types.h =================================================================== --- intern/cycles/kernel/svm/svm_types.h (revision 50667) +++ intern/cycles/kernel/svm/svm_types.h (working copy) @@ -192,6 +192,11 @@ NODE_MATH_ROUND, NODE_MATH_LESS_THAN, NODE_MATH_GREATER_THAN, + NODE_MATH_EQUALS, + NODE_MATH_NOT, + NODE_MATH_AND, + NODE_MATH_OR, + NODE_MATH_XOR, NODE_MATH_CLAMP /* used for the clamp UI option */ } NodeMath; Index: intern/cycles/render/nodes.cpp =================================================================== --- intern/cycles/render/nodes.cpp (revision 50667) +++ intern/cycles/render/nodes.cpp (working copy) @@ -2598,6 +2598,11 @@ enm.insert("Round", NODE_MATH_ROUND); enm.insert("Less Than", NODE_MATH_LESS_THAN); enm.insert("Greater Than", NODE_MATH_GREATER_THAN); + enm.insert("Equals", NODE_MATH_EQUALS); + enm.insert("NOT", NODE_MATH_NOT); + enm.insert("AND", NODE_MATH_AND); + enm.insert("OR", NODE_MATH_OR); + enm.insert("XOR", NODE_MATH_XOR); return enm; } Index: source/blender/compositor/nodes/COM_MathNode.cpp =================================================================== --- source/blender/compositor/nodes/COM_MathNode.cpp (revision 50667) +++ source/blender/compositor/nodes/COM_MathNode.cpp (working copy) @@ -80,6 +80,21 @@ case 16: /* Greater Than */ operation = new MathGreaterThanOperation(); break; + case 17: /* Equals */ + operation = new MathEquals(); + break; + case 18: /* NOT */ + operation = new MathNOT(); + break; + case 19: /* AND */ + operation = new MathAND(); + break; + case 20: /* OR */ + operation = new MathOR(); + break; + case 21: /* XOR */ + operation = new MathXOR(); + break; } if (operation != NULL) { Index: source/blender/compositor/operations/COM_MathBaseOperation.cpp =================================================================== --- source/blender/compositor/operations/COM_MathBaseOperation.cpp (revision 50667) +++ source/blender/compositor/operations/COM_MathBaseOperation.cpp (working copy) @@ -317,4 +317,69 @@ clampIfNeeded(output); } +void MathEquals::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); + + output[0] = inputValue1[0] == inputValue2[0] ? 1.0f : 0.0f; + clampIfNeeded(output); +} + +void MathNOT::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); + + output[0] = 1- inputValue1[0]; + + clampIfNeeded(output); +} + +void MathAND::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); + + output[0] = (int)inputValue1[0] & (int)inputValue2[0]; + + clampIfNeeded(output); +} + +void MathOR::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); + + output[0] = (int)inputValue1[0] | (int)inputValue2[0]; + + clampIfNeeded(output); +} + +void MathXOR::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); + + output[0] = (int)inputValue1[0] ^ (int)inputValue2[0]; + + clampIfNeeded(output); +} + + Index: source/blender/compositor/operations/COM_MathBaseOperation.h =================================================================== --- source/blender/compositor/operations/COM_MathBaseOperation.h (revision 50667) +++ source/blender/compositor/operations/COM_MathBaseOperation.h (working copy) @@ -157,4 +157,30 @@ void executePixel(float output[4], float x, float y, PixelSampler sampler); }; +class MathEquals : public MathBaseOperation { +public: + MathEquals() : MathBaseOperation() {} + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; +class MathNOT : public MathBaseOperation { +public: + MathNOT() : MathBaseOperation() {} + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; +class MathAND : public MathBaseOperation { +public: + MathAND() : MathBaseOperation() {} + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; +class MathOR : public MathBaseOperation { +public: + MathOR() : MathBaseOperation() {} + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; +class MathXOR : public MathBaseOperation { +public: + MathXOR() : MathBaseOperation() {} + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; + #endif Index: source/blender/makesrna/intern/rna_nodetree.c =================================================================== --- source/blender/makesrna/intern/rna_nodetree.c (revision 50667) +++ source/blender/makesrna/intern/rna_nodetree.c (working copy) @@ -109,6 +109,11 @@ {14, "ROUND", 0, "Round", ""}, {15, "LESS_THAN", 0, "Less Than", ""}, {16, "GREATER_THAN", 0, "Greater Than", ""}, + {17, "EQUALS", 0, "Equals", ""}, + {18, "NOT", 0, "NOT", ""}, + {19, "AND", 0, "AND", ""}, + {20, "OR", 0, "OR", ""}, + {21, "XOR", 0, "XOR", ""}, {0, NULL, 0, NULL, NULL} }; Index: source/blender/nodes/composite/nodes/node_composite_math.c =================================================================== --- source/blender/nodes/composite/nodes/node_composite_math.c (revision 50667) +++ source/blender/nodes/composite/nodes/node_composite_math.c (working copy) @@ -164,6 +164,34 @@ out[0]= 0.0f; } break; + case 17: /* Equals */ + { + if ( in[0] == in2[0] ) + out[0]= 1.0f; + else + out[0]= 0.0f; + } + break; + case 18: /* NOT */ + { + out[0]= 1-(int)in[0]; + } + break; + case 19: /* AND */ + { + out[0]= (int)in[0] & (int)in2[0]; + } + break; + case 20: /* OR */ + { + out[0]= (int)in[0] | (int)in2[0]; + } + break; + case 21: /* XOR */ + { + out[0]= (int)in[0] ^ (int)in2[0]; + } + break; } } Index: source/blender/nodes/shader/nodes/node_shader_math.c =================================================================== --- source/blender/nodes/shader/nodes/node_shader_math.c (revision 50667) +++ source/blender/nodes/shader/nodes/node_shader_math.c (working copy) @@ -201,7 +201,7 @@ 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_Equals", "math_NOT", "math_AND", "math_OR", "math_XOR"}; switch (node->custom1) { case 0: @@ -214,6 +214,10 @@ case 13: case 15: case 16: + case 17: + case 19: + case 20: + case 21: GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0]), GPU_socket(&in[1])); break; @@ -224,6 +228,7 @@ case 8: case 9: case 14: + case 18: if (in[0].hasinput || !in[1].hasinput) GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0])); else Index: source/blender/nodes/texture/nodes/node_texture_math.c =================================================================== --- source/blender/nodes/texture/nodes/node_texture_math.c (revision 50667) +++ source/blender/nodes/texture/nodes/node_texture_math.c (working copy) @@ -173,6 +173,35 @@ *out= 0.0f; } break; + + case 17: /* Equals */ + { + if ( in0 == in1 ) + *out= 1.0f; + else + *out= 0.0f; + } + break; + case 18: /* NOT */ + { + *out= 1-(int)in0; + } + break; + case 19: /* AND */ + { + *out= (int)in0 & (int)in1; + } + break; + case 20: /* OR */ + { + *out= (int)in0 | (int)in1; + } + break; + case 21: /* XOR */ + { + *out= (int)in0 ^ (int)in1; + } + break; default: fprintf(stderr,