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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to