[Bf-blender-cvs] [44efcdd] strand_gpu: Fix incorrect tangent calculations for the "curl" effect.

Lukas Tönne noreply at git.blender.org
Mon Jul 18 17:18:25 CEST 2016


Commit: 44efcddec5da4754a7d06086ad5a6d976f580cd1
Author: Lukas Tönne
Date:   Mon Jul 18 17:16:19 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB44efcddec5da4754a7d06086ad5a6d976f580cd1

Fix incorrect tangent calculations for the "curl" effect.

The result for tangents under a mix transformation is essentially a mix
of the original and target tangents, plus a shape correction term.

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

M	source/blender/gpu/shaders/gpu_shader_strand_debug_geom.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_debug_vert.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_effects.glsl

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

diff --git a/source/blender/gpu/shaders/gpu_shader_strand_debug_geom.glsl b/source/blender/gpu/shaders/gpu_shader_strand_debug_geom.glsl
index 5a44cd7..0829a42 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_debug_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_debug_geom.glsl
@@ -1,12 +1,13 @@
-#define MAX_CURVE_VERTS 8
-
 layout(points) in;
-layout(line_strip, max_vertices = MAX_CURVE_VERTS) out;
+layout(line_strip, max_vertices = 16) out;
 
 uniform float debug_scale;
 
+in float vCurveParam[];
 in vec3 vPosition[];
+in vec3 vOldPosition[];
 in vec3 vTangent[];
+in vec3 vOldTangent[];
 in vec3 vTargetPosition[];
 in mat3 vTargetFrame[];
 in vec3 vColor[];
@@ -24,24 +25,62 @@ void main()
 {
 	fColor = vColor[0];
 
-	vec3 co = vPosition[0].xyz;
-
-	emit_vertex(co, vec3(1.0, 0.0, 1.0));
-	emit_vertex(co + vTangent[0] * debug_scale, vec3(1.0, 0.0, 1.0));
-	EndPrimitive();
-
+	vec3 loc = vPosition[0];
+	vec3 oldloc = vOldPosition[0];
+	vec3 nor = vTangent[0];
+	vec3 oldnor = vOldTangent[0];
 	vec3 target_loc = vTargetPosition[0];
 	mat3 target_frame = vTargetFrame[0];
 	vec3 red = vec3(1, 0, 0);
 	vec3 green = vec3(0, 1, 0);
 	vec3 blue = vec3(0, 0, 1);
-	emit_vertex(target_loc, red);
-	emit_vertex(target_loc + target_frame[0] * debug_scale, red);
+	vec3 magenta = vec3(1, 0, 1);
+	vec3 yellow = vec3(1, 1, 0);
+	vec3 cyan = vec3(0, 1, 1);
+
+#if 1
+	emit_vertex(loc, magenta);
+	emit_vertex(loc + vTangent[0] * debug_scale, magenta);
+	EndPrimitive();
+#endif
+
+#if 1
+	emit_vertex(loc, red);
+	emit_vertex(loc + target_frame[0] * debug_scale, red);
 	EndPrimitive();
-	emit_vertex(target_loc, green);
-	emit_vertex(target_loc + target_frame[1] * debug_scale, green);
+	emit_vertex(loc, green);
+	emit_vertex(loc + target_frame[1] * debug_scale, green);
 	EndPrimitive();
-	emit_vertex(target_loc, blue);
-	emit_vertex(target_loc + target_frame[2] * debug_scale, blue);
+	emit_vertex(loc, blue);
+	emit_vertex(loc + target_frame[2] * debug_scale, blue);
+	EndPrimitive();
+#endif
+
+	CurlParams params = curl_params(vCurveParam[0], 1.0, target_loc, target_frame);
+	
+#if 0
+	vec3 dcurl = (params.dcurlvec - nor) * params.factor;
+	vec3 dshape = (target_loc + params.curlvec - loc) * params.dfactor;
+	emit_vertex(loc, cyan);
+	emit_vertex(loc + dcurl * debug_scale, cyan);
+	EndPrimitive();
+	emit_vertex(loc, yellow);
+	emit_vertex(loc + dshape * debug_scale, yellow);
+	EndPrimitive();
+
+	emit_vertex(loc, magenta);
+	emit_vertex(loc + (oldnor + dcurl + dshape) * debug_scale, magenta);
+	EndPrimitive();
+#endif
+
+#if 0
+	vec3 dloc = (target_loc + params.curlvec - loc) * params.factor;
+	vec3 nloc = loc + dloc;
+	vec3 dshape = dloc / (vCurveParam[0] * curl_shape);
+	vec3 dtarget = target_frame[2] + params.turns * params.dcurlvec;
+	vec3 nnor = normalize(dshape + mix(oldnor, dtarget, params.factor));
+	emit_vertex(loc, cyan);
+	emit_vertex(loc + nnor * debug_scale, cyan);
 	EndPrimitive();
+#endif
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_debug_vert.glsl b/source/blender/gpu/shaders/gpu_shader_strand_debug_vert.glsl
index 6640f71..5991b20 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_debug_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_debug_vert.glsl
@@ -1,8 +1,11 @@
 in uint fiber_index;
 in float curve_param;
 
+out float vCurveParam;
 out vec3 vPosition;
+out vec3 vOldPosition;
 out vec3 vTangent;
+out vec3 vOldTangent;
 out vec3 vTargetPosition;
 out mat3 vTargetFrame;
 out vec3 vColor;
@@ -16,10 +19,15 @@ void main()
 	interpolate_vertex(int(fiber_index), curve_param, loc, nor, target_loc, target_frame);
 
 	// TODO define proper curve scale, independent of subdivision!
+	vec3 oldloc = loc;
+	vec3 oldnor = nor;
 	displace_vertex(loc, nor, curve_param, 1.0, target_loc, target_frame);
 
+	vCurveParam = curve_param;
 	vPosition = loc;
+	vOldPosition = oldloc;
 	vTangent = nor;
+	vOldTangent = oldnor;
 	vTargetPosition = target_loc;
 	vTargetFrame = target_frame;
 	vColor = vec3(1,0,1);
diff --git a/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl b/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
index 7078b7e..91cf653 100644
--- a/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_strand_effects.glsl
@@ -32,8 +32,7 @@ void clumping(inout vec3 loc, inout vec3 nor, in float t, in float tscale, in ve
 	vec3 nloc = mix(loc, target_loc, factor);
 	vec3 nnor;
 	if (t > 0.0) {
-		nnor = normalize(nor * (1.0 - factor)
-			   + (target_loc - loc) * factor / (t * clump_shape));
+		nnor = normalize(mix(nor, (target_loc - loc) / (t * clump_shape), factor));
 	}
 	else
 		nnor = nor;
@@ -42,26 +41,45 @@ void clumping(inout vec3 loc, inout vec3 nor, in float t, in float tscale, in ve
 	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)
 {
-	float taper = pow(t, 1.0 / curl_shape);
-	float factor = (1.0 - curl_thickness) * taper;
+	CurlParams params = curl_params(t, tscale, target_loc, target_frame);
 
-	float angle = 2.0*M_PI * t * tscale / curl_length;
-	vec3 curlvec = target_frame * vec3(cos(angle), sin(angle), 0.0) * curl_radius;
-	
-	vec3 nloc = mix(loc, target_loc + curlvec, factor);
-	vec3 nnor;
-	if (t > 0.0) {
-		nnor = normalize(nor * (1.0 - factor)
-			   + vec3(-curlvec.y, curlvec.x, 0.0) * 2.0*M_PI * tscale / curl_length
-			   + (target_loc + curlvec - loc) * factor / (t * clump_shape));
-	}
-	else
-		nnor = nor;
+	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;




More information about the Bf-blender-cvs mailing list