[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