[Bf-blender-cvs] [0e30440] object_nodes: New node "Get Derivative" for using a derivative as the value.

Lukas Tönne noreply at git.blender.org
Wed May 25 17:36:09 CEST 2016


Commit: 0e30440080769b723b17f9f6a56bcca65ff808f6
Author: Lukas Tönne
Date:   Wed May 25 17:20:50 2016 +0200
Branches: object_nodes
https://developer.blender.org/rB0e30440080769b723b17f9f6a56bcca65ff808f6

New node "Get Derivative" for using a derivative as the value.

This is mostly a debugging feature for getting visual feedback about
the derivatives. The function doesn't work in the regular scheme of
decomposing a function into the value and derivative parts, so it is
only implemented in the internal IR (making it directly inlineable).

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

M	release/scripts/nodes/texture_nodes.py
M	source/blender/blenvm/compile/node_graph.cc
M	source/blender/blenvm/intern/bvm_api.cc
M	source/blender/blenvm/llvm/llvm_compiler.h
M	source/blender/blenvm/llvm/llvm_compiler_dual.cc
M	source/blender/blenvm/llvm/llvm_types.cc
M	source/blender/blenvm/llvm/llvm_types.h
M	source/blender/blenvm/modules/mod_base.h
M	source/blender/blenvm/util/util_opcode.h

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

diff --git a/release/scripts/nodes/texture_nodes.py b/release/scripts/nodes/texture_nodes.py
index c7f4988..c421574 100644
--- a/release/scripts/nodes/texture_nodes.py
+++ b/release/scripts/nodes/texture_nodes.py
@@ -131,6 +131,50 @@ class TextureCoordinateNode(TextureNodeBase, ObjectNode):
     def compile(self, compiler):
         compiler.map_output(0, compiler.graph_input("texture.co"))
 
+
+class TextureGetDerivativeNode(TextureNodeBase, ObjectNode):
+    '''Get a partial derivative of a value'''
+    bl_idname = 'TextureGetDerivativeNode'
+    bl_label = 'Get Derivative'
+
+    _variable_items = [
+        ('X', 'x', '', 'NONE', 0),
+        ('Y', 'y', '', 'NONE', 1),
+        ]
+    variable = EnumProperty(name="Variable",
+                            description="Get derivative wrt. this variable",
+                            items=_variable_items)
+    @property
+    def variable_index(self):
+        return self.bl_rna.properties['variable'].enum_items_static[self.variable].value
+
+    def draw_buttons(self, context, layout):
+        layout.prop(self, "variable")
+
+    def init(self, context):
+        self.inputs.new('NodeSocketFloat', "Value")
+        self.inputs.new('NodeSocketVector', "Value")
+        self.inputs.new('NodeSocketColor', "Value")
+        self.outputs.new('NodeSocketFloat', "Derivative")
+        self.outputs.new('NodeSocketVector', "Derivative")
+        self.outputs.new('NodeSocketColor', "Derivative")
+
+    def compile(self, compiler):
+        node = compiler.add_node("GET_DERIVATIVE_FLOAT")
+        node.inputs[0].set_value(self.variable_index)
+        compiler.map_input(0, node.inputs[1])
+        compiler.map_output(0, node.outputs[0])
+
+        node = compiler.add_node("GET_DERIVATIVE_FLOAT3")
+        node.inputs[0].set_value(self.variable_index)
+        compiler.map_input(1, node.inputs[1])
+        compiler.map_output(1, node.outputs[0])
+
+        node = compiler.add_node("GET_DERIVATIVE_FLOAT4")
+        node.inputs[0].set_value(self.variable_index)
+        compiler.map_input(2, node.inputs[1])
+        compiler.map_output(2, node.outputs[0])
+
 ###############################################################################
 
 def register():
@@ -154,6 +198,7 @@ def register():
         TextureNodeCategory("TEX_CONVERTER", "Converter", items=[
             NodeItem("ObjectSeparateVectorNode"),
             NodeItem("ObjectCombineVectorNode"),
+            NodeItem("TextureGetDerivativeNode"),
             ]),
         TextureNodeCategory("TEX_MATH", "Math", items=[
             NodeItem("ObjectMathNode"),
diff --git a/source/blender/blenvm/compile/node_graph.cc b/source/blender/blenvm/compile/node_graph.cc
index d99256c..297bb94 100644
--- a/source/blender/blenvm/compile/node_graph.cc
+++ b/source/blender/blenvm/compile/node_graph.cc
@@ -1461,6 +1461,21 @@ static void register_opcode_node_types()
 	nt->add_input("value_w", "FLOAT", 0.0f);
 	nt->add_output("value", "FLOAT4");
 	
+	nt = NodeGraph::add_node_type("GET_DERIVATIVE_FLOAT");
+	nt->add_input("variable", "INT", 0, INPUT_CONSTANT);
+	nt->add_input("value", "FLOAT", 0.0f);
+	nt->add_output("derivative", "FLOAT");
+	
+	nt = NodeGraph::add_node_type("GET_DERIVATIVE_FLOAT3");
+	nt->add_input("variable", "INT", 0, INPUT_CONSTANT);
+	nt->add_input("value", "FLOAT3", float3(0.0f, 0.0f, 0.0f));
+	nt->add_output("derivative", "FLOAT3");
+	
+	nt = NodeGraph::add_node_type("GET_DERIVATIVE_FLOAT4");
+	nt->add_input("variable", "INT", 0, INPUT_CONSTANT);
+	nt->add_input("value", "FLOAT4", float4(0.0f, 0.0f, 0.0f, 0.0f));
+	nt->add_output("derivative", "FLOAT4");
+	
 	#define BINARY_MATH_NODE(name) \
 	nt = NodeGraph::add_node_type(STRINGIFY(name)); \
 	nt->add_input("value_a", "FLOAT", 0.0f); \
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index d51df61..5abf92c 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -664,8 +664,12 @@ void BVM_eval_texture_llvm(struct BVMEvalContext *UNUSED(ctx), struct BVMFunctio
 	coord_v.set_value(float3(coord[0], coord[1], coord[2]));
 	if (dxt)
 		coord_v.set_dx(float3(dxt[0], dxt[1], dxt[2]));
+	else
+		coord_v.set_dx(float3(0.0f, 0.0f, 0.0f));
 	if (dyt)
 		coord_v.set_dy(float3(dyt[0], dyt[1], dyt[2]));
+	else
+		coord_v.set_dy(float3(0.0f, 0.0f, 0.0f));
 	
 	fp(&r_color, &r_normal, &coord_v, cfra, osatex);
 #else
diff --git a/source/blender/blenvm/llvm/llvm_compiler.h b/source/blender/blenvm/llvm/llvm_compiler.h
index 535150a..b9dcff7 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.h
+++ b/source/blender/blenvm/llvm/llvm_compiler.h
@@ -140,11 +140,14 @@ struct LLVMTextureCompiler : public LLVMCompilerBase {
 	
 	llvm::Constant *create_node_value_constant(const NodeValue *node_value);
 	
+	void define_node_function(llvm::Module *mod, OpCode op, const string &nodetype_name);
+	void define_nodes_module();
+	
 	bool set_node_function_impl(OpCode op, const NodeType *nodetype,
 	                            llvm::Function *value_func, llvm::Function * dual_func);
-	void define_elementary_functions(OpCode op, llvm::Module *mod, const string &nodetype_name);
-	void define_dual_function_wrapper(llvm::Module *mod, const string &nodetype_name);
-	void define_nodes_module();
+	void define_elementary_functions(llvm::Module *mod, OpCode op, const NodeType *nodetype);
+	void define_dual_function_wrapper(llvm::Module *mod, OpCode op, const NodeType *nodetype);
+	void define_get_derivative(llvm::Module *mod, OpCode op, const NodeType *nodetype);
 	
 private:
 	static llvm::Module *m_nodes_module;
diff --git a/source/blender/blenvm/llvm/llvm_compiler_dual.cc b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
index 36eba7a..6f4a145 100644
--- a/source/blender/blenvm/llvm/llvm_compiler_dual.cc
+++ b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
@@ -127,6 +127,47 @@ llvm::Constant *LLVMTextureCompiler::create_node_value_constant(const NodeValue
 	return bvm_create_llvm_constant(context(), node_value);
 }
 
+/* ------------------------------------------------------------------------- */
+
+void LLVMTextureCompiler::define_node_function(llvm::Module *mod, OpCode op, const string &nodetype_name)
+{
+	const NodeType *nodetype = NodeGraph::find_node_type(nodetype_name);
+	if (nodetype == NULL)
+		return;
+	
+	switch (op) {
+		/* special cases */
+		case OP_GET_DERIVATIVE_FLOAT:
+		case OP_GET_DERIVATIVE_FLOAT3:
+		case OP_GET_DERIVATIVE_FLOAT4:
+			define_get_derivative(mod, op, nodetype);
+			break;
+		
+		default:
+			define_elementary_functions(mod, op, nodetype);
+			define_dual_function_wrapper(mod, op, nodetype);
+			break;
+	}
+}
+
+void LLVMTextureCompiler::define_nodes_module()
+{
+	using namespace llvm;
+	
+	Module *mod = new llvm::Module("texture_nodes", context());
+	
+#define DEF_OPCODE(op) \
+	define_node_function(mod, OP_##op, STRINGIFY(op));
+	
+	BVM_DEFINE_OPCODES
+	
+#undef DEF_OPCODE
+	
+	m_nodes_module = mod;
+}
+
+/* ------------------------------------------------------------------------- */
+
 llvm::Function *LLVMTextureCompiler::declare_elementary_node_function(
         llvm::Module *mod, const NodeType *nodetype, const string &name,
         bool with_derivatives)
@@ -149,7 +190,8 @@ llvm::Function *LLVMTextureCompiler::declare_elementary_node_function(
 			type = type->getPointerTo();
 		
 		input_types.push_back(type);
-		if (with_derivatives && bvm_type_has_dual_value(typespec)) {
+		if (with_derivatives &&
+		    input->value_type != INPUT_CONSTANT && bvm_type_has_dual_value(typespec)) {
 			/* second argument for derivative */
 			input_types.push_back(type);
 		}
@@ -164,7 +206,13 @@ llvm::Function *LLVMTextureCompiler::declare_elementary_node_function(
 			break;
 		}
 		
-		output_types.push_back(type);
+		if (with_derivatives &&
+		    bvm_type_has_dual_value(typespec)) {
+			output_types.push_back(type);
+		}
+		else {
+			output_types.push_back(type);
+		}
 	}
 	if (error) {
 		/* some arguments could not be handled */
@@ -225,36 +273,30 @@ bool LLVMTextureCompiler::set_node_function_impl(OpCode op, const NodeType *UNUS
 	}
 }
 
-void LLVMTextureCompiler::define_elementary_functions(OpCode op, llvm::Module *mod, const string &nodetype_name)
+void LLVMTextureCompiler::define_elementary_functions(llvm::Module *mod, OpCode op, const NodeType *nodetype)
 {
 	using namespace llvm;
 	
-	const NodeType *nodetype = NodeGraph::find_node_type(nodetype_name);
-	if (nodetype == NULL)
-		return;
+	/* declare functions */
+	Function *value_func = NULL, *deriv_func = NULL;
 	
-	/* declare function */
-	BLI_assert(llvm_has_external_impl_value(op));
-	Function *value_func = declare_elementary_node_function(
-	                           mod, nodetype, llvm_value_function_name(nodetype->name()), false);
+	if (llvm_has_external_impl_value(op)) {
+		value_func = declare_elementary_node_function(
+		                 mod, nodetype, llvm_value_function_name(nodetype->name()), false);
+	}
 	
-	Function *deriv_func = NULL;
 	if (llvm_has_external_impl_deriv(op)) {
 		deriv_func = declare_elementary_node_function(
-		                mod, nodetype, llvm_deriv_function_name(nodetype->name()), true);
+		                 mod, nodetype, llvm_deriv_function_name(nodetype->name()), true);
 	}
 	
 	set_node_function_impl(op, nodetype, value_func, deriv_func);
 }
 
-void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const string &nodetype_name)
+void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, OpCode UNUSED(op), const NodeType *nodetype)
 {
 	using namespace llvm;
 	
-	const NodeType *nodetype = NodeGraph::find_node_type(nodetype_name);
-	if (nodetype == NULL)
-		return;
-	
 	/* get evaluation function(s) */
 	string value_name = llvm_value_function_name(nodetype->name());
 	Function *value_func = llvm_find_external_function(mod, value_name);
@@ -273,9 +315,6 @@ void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const
 	builder.SetInsertPoint(block);
 	
 	/* collect arguments for calling internal elementary functions */
-	/* value and derivative components of input/output duals */
-	std::vector<Value*> in_value, in_dx, in_dy;
-	std::vector<Value*> out_value, ou

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list