[Bf-blender-cvs] [30bffb5a3af] master: Nodes: add sqrt, ceil, floor and fract to math nodes.

Charlie Jolly noreply at git.blender.org
Fri Jul 13 11:00:39 CEST 2018


Commit: 30bffb5a3afa2fde165d4fb63a115310d5ddc3e3
Author: Charlie Jolly
Date:   Thu Jul 12 23:40:18 2018 +0200
Branches: master
https://developer.blender.org/rB30bffb5a3afa2fde165d4fb63a115310d5ddc3e3

Nodes: add sqrt, ceil, floor and fract to math nodes.

This works for Cycles, Eevee, texture nodes and compositing. It helps to
reduce the number of math nodes required in various node setups.

Differential Revision: https://developer.blender.org/D3537

===================================================================

M	intern/cycles/kernel/shaders/node_math.osl
M	intern/cycles/kernel/svm/svm_math_util.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/nodes.cpp
M	source/blender/compositor/nodes/COM_MathNode.cpp
M	source/blender/compositor/operations/COM_MathBaseOperation.cpp
M	source/blender/compositor/operations/COM_MathBaseOperation.h
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/shader/nodes/node_shader_math.c
M	source/blender/nodes/texture/nodes/node_texture_math.c

===================================================================

diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index c5fcbc311d3..aa9f6e671c3 100644
--- a/intern/cycles/kernel/shaders/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -40,6 +40,18 @@ float safe_modulo(float a, float b)
 	return result;
 }
 
+float safe_sqrt(float a)
+{
+	float result;
+
+	if (a > 0.0)
+		result = sqrt(a);
+	else
+		result = 0.0;
+
+	return result;
+}
+
 float safe_log(float a, float b)
 {
 	if (a < 0.0 || b < 0.0)
@@ -97,6 +109,14 @@ shader node_math(
 		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);
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
index 04864bd610a..d3490ab284f 100644
--- a/intern/cycles/kernel/svm/svm_math_util.h
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -94,6 +94,14 @@ ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
 		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
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index b94a83b6712..0fde5126434 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -261,6 +261,10 @@ typedef enum NodeMath {
 	NODE_MATH_MODULO,
 	NODE_MATH_ABSOLUTE,
 	NODE_MATH_ARCTAN2,
+	NODE_MATH_FLOOR,
+	NODE_MATH_CEIL,
+	NODE_MATH_FRACT,
+	NODE_MATH_SQRT,
 	NODE_MATH_CLAMP /* used for the clamp UI option */
 } NodeMath;
 
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index beff7f91348..fe2916d21d4 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -5071,6 +5071,10 @@ NODE_DEFINE(MathNode)
 	type_enum.insert("modulo", NODE_MATH_MODULO);
 	type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
 	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("sqrt", NODE_MATH_SQRT);
 	SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD);
 
 	SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp
index d16300ebff4..25c617a3487 100644
--- a/source/blender/compositor/nodes/COM_MathNode.cpp
+++ b/source/blender/compositor/nodes/COM_MathNode.cpp
@@ -89,6 +89,18 @@ void MathNode::convertToOperations(NodeConverter &converter, const CompositorCon
 		case NODE_MATH_ATAN2:
 			operation = new MathArcTan2Operation();
 			break;
+		case NODE_MATH_FLOOR:
+			operation = new MathFloorOperation();
+			break;
+		case NODE_MATH_CEIL:
+			operation = new MathCeilOperation();
+			break;
+		case NODE_MATH_FRACT:
+			operation = new MathFractOperation();
+			break;
+		case NODE_MATH_SQRT:
+			operation = new MathSqrtOperation();
+			break;
 	}
 
 	if (operation) {
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
index 0a515da1877..99385a5073a 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
@@ -356,3 +356,50 @@ void MathArcTan2Operation::executePixelSampled(float output[4], float x, float y
 
 	clampIfNeeded(output);
 }
+
+void MathFloorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+	float inputValue1[4];
+
+	this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+
+	output[0] = floor(inputValue1[0]);
+
+	clampIfNeeded(output);
+}
+
+void MathCeilOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+	float inputValue1[4];
+
+	this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+
+	output[0] = ceil(inputValue1[0]);
+
+	clampIfNeeded(output);
+}
+
+void MathFractOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+	float inputValue1[4];
+
+	this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+
+	output[0] = inputValue1[0] - floor(inputValue1[0]);
+
+	clampIfNeeded(output);
+}
+
+void MathSqrtOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+	float inputValue1[4];
+
+	this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+
+	if (inputValue1[0] > 0)
+		output[0] = sqrt(inputValue1[0]);
+	else
+		output[0] = 0.0f;
+
+	clampIfNeeded(output);
+}
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h
index c636117451f..5435cc82ba7 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.h
@@ -175,4 +175,28 @@ public:
 	void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
 };
 
+class MathFloorOperation : public MathBaseOperation {
+public:
+	MathFloorOperation() : MathBaseOperation() {}
+	void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
+class MathCeilOperation : public MathBaseOperation {
+public:
+	MathCeilOperation() : MathBaseOperation() {}
+	void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
+class MathFractOperation : public MathBaseOperation {
+public:
+	MathFractOperation() : MathBaseOperation() {}
+	void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
+class MathSqrtOperation : public MathBaseOperation {
+public:
+	MathSqrtOperation() : MathBaseOperation() {}
+	void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
 #endif
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index ce9e82b34f8..2cb92fd1cbc 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -418,6 +418,29 @@ void math_atan2(float val1, float val2, out float outval)
 	outval = atan(val1, val2);
 }
 
+void math_floor(float val, out float outval)
+{
+	outval = floor(val);
+}
+
+void math_ceil(float val, out float outval)
+{
+	outval = ceil(val);
+}
+
+void math_fract(float val, out float outval)
+{
+	outval = val - floor(val);
+}
+
+void math_sqrt(float val, out float outval)
+{
+	if (val > 0.0)
+		outval = sqrt(val);
+	else
+		outval = 0.0;
+}
+
 void squeeze(float val, float width, float center, out float outval)
 {
 	outval = 1.0 / (1.0 + pow(2.71828183, -((val - center) * width)));
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index b95506cea48..f6d92a95c3a 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1073,6 +1073,10 @@ enum {
 	NODE_MATH_MOD     = 17,
 	NODE_MATH_ABS     = 18,
 	NODE_MATH_ATAN2   = 19,
+	NODE_MATH_FLOOR   = 20,
+	NODE_MATH_CEIL    = 21,
+	NODE_MATH_FRACT   = 22,
+	NODE_MATH_SQRT    = 23,
 };
 
 /* mix rgb node flags */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a2ab00a482b..5fe42e11765 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -141,6 +141,10 @@ const EnumPropertyItem rna_enum_node_math_items[] = {
 	{NODE_MATH_MOD,     "MODULO",       0, "Modulo",       ""},
 	{NODE_MATH_ABS,     "ABSOLUTE",     0, "Absolute",     ""},
 	{NODE_MATH_ATAN2,   "ARCTAN2",      0, "Arctan2",      ""},
+	{NODE_MATH_FLOOR,   "FLOOR",        0, "Floor",        ""},
+	{NODE_MATH_CEIL,    "CEIL",         0, "Ceil",         ""},
+	{NODE_MATH_FRACT,   "FRACT",        0, "Fract",        ""},
+	{NODE_MATH_SQRT,    "SQRT",         0, "Square Root",  ""},
 	{0, NULL, 0, NULL, NULL}
 };
 
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 0a75a0f8bf0..605c869099a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -226,6 +226,46 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
 			r = atan2(a, b);
 			break;
 		}
+		case NODE_MATH_FLOOR:
+		{
+			if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
+				r = floorf(a);
+			else
+				r = floorf(b);
+			break;
+		}
+		case NODE_MATH_CEIL:
+		{
+			if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
+				r = ceilf(a);
+			else
+				r = ceilf(b);
+			break;
+		}
+		case NODE_MATH_FRACT:
+		{
+			if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
+				r = a - floorf(a);
+			else
+				r = b - floorf(b);
+			break;
+		}
+		case NODE_MATH_SQRT:
+		{
+			if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
+				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);
@@ -240,7 +280,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
 	    "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_great

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list