[Bf-blender-cvs] [01f5b36] strand_nodes: Each node gets expanded to two function calls for autodiff.
Lukas Tönne
noreply at git.blender.org
Thu Jul 21 20:17:09 CEST 2016
Commit: 01f5b367cf216b561e9de5993df8304a0be61ff2
Author: Lukas Tönne
Date: Thu Jul 21 20:11:35 2016 +0200
Branches: strand_nodes
https://developer.blender.org/rB01f5b367cf216b561e9de5993df8304a0be61ff2
Each node gets expanded to two function calls for autodiff.
The value is calculated without any derivative inputs (this is not a differential equation).
The derivatives in both variables also depend on the partial derivatives of the inputs.
===================================================================
M source/blender/blenvm/glsl/glsl_codegen.cc
M source/blender/gpu/CMakeLists.txt
M source/blender/gpu/intern/gpu_strands_shader.c
D source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
A source/blender/gpu/shaders/gpu_shader_strand_nodes.glsl
===================================================================
diff --git a/source/blender/blenvm/glsl/glsl_codegen.cc b/source/blender/blenvm/glsl/glsl_codegen.cc
index c5a175d..059d362 100644
--- a/source/blender/blenvm/glsl/glsl_codegen.cc
+++ b/source/blender/blenvm/glsl/glsl_codegen.cc
@@ -50,6 +50,7 @@ namespace blenvm {
static string sanitize_name(const string &name)
{
string s = name;
+
string::const_iterator it = s.begin();
string::iterator nit = s.begin();
for (; it != s.end(); ++it) {
@@ -59,6 +60,7 @@ static string sanitize_name(const string &name)
++nit;
}
}
+ s = s.substr(0, nit - s.begin());
return s;
}
@@ -164,8 +166,6 @@ void GLSLCodeGenerator::node_graph_begin(const string &name, const NodeGraph *gr
}
size_t num_outputs = graph->outputs.size();
- if (num_inputs > 0)
- m_code << ", ";
for (int i = 0; i < num_outputs; ++i) {
const NodeGraph::Output *output = graph->get_output(i);
const TypeSpec *typespec = output->typedesc.get_typespec();
@@ -179,7 +179,7 @@ void GLSLCodeGenerator::node_graph_begin(const string &name, const NodeGraph *gr
create_value(typespec, basename + "_DX", false),
create_value(typespec, basename + "_DY", false));
- if (i > 0)
+ if (i + num_inputs > 0)
m_code << ", ";
m_code << "out " << typestring << " " << dval.value()->name()
<< ", out " << typestring << " " << dval.dx()->name()
@@ -280,7 +280,10 @@ void GLSLCodeGenerator::eval_node(const NodeType *nodetype,
ArrayRef<ValueHandle> input_args,
ArrayRef<ValueHandle> output_args)
{
- m_code << nodetype->name() << "(";
+ stringstream args_value;
+ stringstream args_dx;
+ stringstream args_dy;
+ const char *sep;
// if (nodetype->use_globals()) {
// evalargs.push_back(m_globals_ptr);
@@ -292,38 +295,32 @@ void GLSLCodeGenerator::eval_node(const NodeType *nodetype,
bool is_constant = (input->value_type == INPUT_CONSTANT);
const DualValue &dval = get_value(input_args[i]);
- if (i > 0)
- m_code << ", ";
+ sep = (i > 0) ? ", " : "";
+ args_value << sep << dval.value()->name();
+ args_dx << sep << dval.value()->name();
+ args_dy << sep << dval.value()->name();
if (!is_constant && bvm_glsl_type_has_dual_value(typespec)) {
- m_code << dval.value()->name()
- << ", " << dval.dx()->name()
- << ", " << dval.dy()->name();
- }
- else {
- m_code << dval.value()->name();
+ args_dx << ", " << dval.dx()->name();
+ args_dy << ", " << dval.dy()->name();
}
}
- if (nodetype->num_inputs() > 0)
- m_code << ", ";
for (int i = 0; i < nodetype->num_outputs(); ++i) {
const NodeOutput *output = nodetype->find_output(i);
const TypeSpec *typespec = output->typedesc.get_typespec();
const DualValue &dval = get_value(output_args[i]);
- if (i > 0)
- m_code << ", ";
+ sep = (i + nodetype->num_inputs() > 0) ? ", " : "";
+ args_value << sep << dval.value()->name();
if (bvm_glsl_type_has_dual_value(typespec)) {
- m_code << dval.value()->name()
- << ", " << dval.dx()->name()
- << ", " << dval.dy()->name();
- }
- else {
- m_code << dval.value()->name();
+ args_dx << sep << dval.dx()->name();
+ args_dy << sep << dval.dy()->name();
}
}
- m_code << ");\n";
+ m_code << "V_" << nodetype->name() << "(" << args_value.str() << ");\n";
+ m_code << "D_" << nodetype->name() << "(" << args_dx.str() << ");\n";
+ m_code << "D_" << nodetype->name() << "(" << args_dy.str() << ");\n";
}
} /* namespace blenvm */
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 054abca..6bec940 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -133,7 +133,7 @@ data_to_c_simple(shaders/gpu_shader_strand_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_strand_debug_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_strand_debug_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_strand_debug_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_strand_effects.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_strand_nodes.glsl SRC)
data_to_c_simple(shaders/gpu_shader_strand_util.glsl SRC)
if(WITH_GAMEENGINE)
diff --git a/source/blender/gpu/intern/gpu_strands_shader.c b/source/blender/gpu/intern/gpu_strands_shader.c
index f4e2d2b..06d3910 100644
--- a/source/blender/gpu/intern/gpu_strands_shader.c
+++ b/source/blender/gpu/intern/gpu_strands_shader.c
@@ -76,7 +76,7 @@ extern char datatoc_gpu_shader_strand_vert_glsl[];
extern char datatoc_gpu_shader_strand_debug_frag_glsl[];
extern char datatoc_gpu_shader_strand_debug_geom_glsl[];
extern char datatoc_gpu_shader_strand_debug_vert_glsl[];
-extern char datatoc_gpu_shader_strand_effects_glsl[];
+extern char datatoc_gpu_shader_strand_nodes_glsl[];
extern char datatoc_gpu_shader_strand_util_glsl[];
static char *codegen(const char *basecode, const char *nodecode)
@@ -89,7 +89,7 @@ static char *codegen(const char *basecode, const char *nodecode)
DynStr *ds = BLI_dynstr_new();
BLI_dynstr_append(ds, datatoc_gpu_shader_strand_util_glsl);
- BLI_dynstr_append(ds, datatoc_gpu_shader_strand_effects_glsl);
+ BLI_dynstr_append(ds, datatoc_gpu_shader_strand_nodes_glsl);
if (nodecode)
BLI_dynstr_append(ds, nodecode);
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl b/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
deleted file mode 100644
index 91cf653..0000000
--- a/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
+++ /dev/null
@@ -1,96 +0,0 @@
-uniform int debug_value;
-
-uniform float clump_thickness;
-uniform float clump_shape;
-uniform float curl_thickness;
-uniform float curl_shape;
-uniform float curl_radius;
-uniform float curl_length;
-
-/* Note: The deformer functions below calculate a new location vector
- * as well as a new direction (aka "normal"), using the partial derivatives of the transformation.
- *
- * Each transformation function can depend on the location L as well as the curve parameter t:
- *
- * Lnew = f(L, t)
- * => dLnew/dt = del f/del L * dL/dt + del f/del t
- *
- * The first term is the Jacobian of the function f, dL/dt is the original direction vector.
- * Some more information can be found here:
- * http://http.developer.nvidia.com/GPUGems/gpugems_ch42.html
- */
-
-/* Hairs tend to stick together and run in parallel.
- * The effect increases with distance from the root,
- * as the stresses pulling fibers apart decrease.
- */
-void clumping(inout vec3 loc, inout vec3 nor, in float t, in float tscale, in vec3 target_loc, in mat3 target_frame)
-{
- float taper = pow(t, 1.0 / clump_shape);
- float factor = (1.0 - clump_thickness) * taper;
-
- vec3 nloc = mix(loc, target_loc, factor);
- vec3 nnor;
- if (t > 0.0) {
- nnor = normalize(mix(nor, (target_loc - loc) / (t * clump_shape), factor));
- }
- else
- nnor = nor;
-
- loc = nloc;
- nor = nnor;
-}
-
-struct CurlParams {
- float taper, dtaper;
- float factor, dfactor;
- float turns;
- float angle, dangle;
- vec3 curlvec, dcurlvec;
-};
-
-CurlParams curl_params(float t, float tscale, vec3 target_loc, mat3 target_frame)
-{
- CurlParams params;
-
- params.taper = pow(t, 1.0 / curl_shape);
- params.dtaper = (t > 0.0) ? params.taper / (t * curl_shape) : 0.0;
- params.factor = (1.0 - curl_thickness) * params.taper;
- params.dfactor = (1.0 - curl_thickness) * params.dtaper;
-
- params.turns = 2.0*M_PI * tscale / curl_length;
- params.angle = t * params.turns;
- params.dangle = params.turns;
-
- params.curlvec = target_frame * vec3(cos(params.angle), sin(params.angle), 0.0) * curl_radius;
- params.dcurlvec = target_frame * vec3(-sin(params.angle), cos(params.angle), 0.0) * curl_radius;
-
- return params;
-}
-
-/* Hairs often don't have a circular cross section, but are somewhat flattened.
- * This creates the local bending which results in the typical curly hair geometry.
- */
-void curl(inout vec3 loc, inout vec3 nor, in float t, in float tscale, in vec3 target_loc, in mat3 target_frame)
-{
- CurlParams params = curl_params(t, tscale, target_loc, target_frame);
-
- vec3 dloc = (target_loc + params.curlvec - loc) * params.factor;
- vec3 nloc = loc + dloc;
- vec3 dshape = dloc / (t * curl_shape);
- vec3 dtarget = target_frame[2] + params.turns * params.dcurlvec;
- vec3 nnor = normalize(dshape + mix(nor, dtarget, params.factor));
-
- loc = nloc;
- nor = nnor;
-}
-
-void displace_vertex(inout vec3 loc, inout vec3 nor, in float t, in float tscale, in vec3 target_loc, in mat3 target_frame)
-{
-#ifdef USE_EFFECT_CLUMPING
- clumping(loc, nor, t, tscale, target_loc, target_frame);
-#endif
-#ifdef USE_EFFECT_CURL
- curl(loc, nor, t, tscale, target_loc, target_frame);
-#endif
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_nodes.glsl b/source/blender/gpu/shaders/gpu_shader_strand_nodes.glsl
new file mode 100644
index 0000000..e69de29
More information about the Bf-blender-cvs
mailing list