[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