[Bf-blender-cvs] [c891621d73d] hair_guides_grooming: Calculate and store length for each vertex in the guides texture.

Lukas Tönne noreply at git.blender.org
Wed Jun 13 22:14:42 CEST 2018


Commit: c891621d73d709162a454b6418dfac998e57c51c
Author: Lukas Tönne
Date:   Wed Jun 13 21:13:40 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rBc891621d73d709162a454b6418dfac998e57c51c

Calculate and store length for each vertex in the guides texture.

This allows accurate and consistent deformation based on hair length,
rather than relying on the relative parameterization.

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

M	source/blender/blenkernel/intern/hair_draw.c
M	source/blender/draw/modes/shaders/common_hair_guides_lib.glsl

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

diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index 5b7e6e7cb67..18b81b243d2 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -84,7 +84,7 @@ typedef struct HairStrandVertexTextureBuffer {
 	float co[3];
 	float nor[3];
 	float tang[3];
-	int pad;
+	float len;
 } HairStrandVertexTextureBuffer;
 BLI_STATIC_ASSERT_ALIGN(HairStrandVertexTextureBuffer, 8)
 
@@ -116,11 +116,18 @@ static void hair_get_strand_buffer(
 		smap->taper_length = curve->taper_length;
 		smap->taper_thickness = curve->taper_thickness;
 		
+		float len = 0.0f;
 		for (int j = 0; j < curve->numverts; ++j)
 		{
 			copy_v3_v3(svert[j].co, verts[j].co);
 			copy_v3_v3(svert[j].tang, tangents[j]);
 			copy_v3_v3(svert[j].nor, normals[j]);
+			
+			if (j > 0)
+			{
+				len += len_v3v3(verts[j-1].co, verts[j].co);
+			}
+			svert[j].len = len;
 		}
 	}
 }
diff --git a/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl b/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
index 86afcc67827..e1d7c31d830 100644
--- a/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
@@ -98,8 +98,7 @@ void deform_taper(DeformParams params, float t, out float taper, out float dtape
  * The effect increases with distance from the root,
  * as the stresses pulling fibers apart decrease.
  */
-void deform_clump(DeformParams params,
-                  float t, float tscale, mat4 target_matrix,
+void deform_clump(DeformParams params, float t, mat4 target_matrix,
                   inout vec3 co, inout vec3 tang)
 {
 	float taper, dtaper;
@@ -119,23 +118,21 @@ void deform_clump(DeformParams 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 deform_curl(DeformParams params,
-                 float t, float tscale,
+void deform_curl(DeformParams params, float t,
                  inout mat4 target_matrix)
 {
 	float pitch = 2.0*M_PI * params.curl_radius * tan(params.curl_angle);
-	float turns = tscale / (params.curl_radius * tan(params.curl_angle));
-	float angle = t * turns;
+	float angle = t / (params.curl_radius * tan(params.curl_angle));
 	mat4 local_mat = rotateX(angle) * translate(vec3(0.0, params.curl_radius, 0.0)) * rotateY(params.curl_angle);
 	target_matrix = target_matrix * local_mat;
 }
 
 void deform_fiber(DeformParams params,
-                  float t, float tscale, mat4 target_matrix,
+                  float t, mat4 target_matrix,
                   inout vec3 loc, inout vec3 tang)
 {
-	//deform_curl(params, t, tscale, target_matrix);
-	deform_clump(params, t, tscale, target_matrix, loc, tang);
+	//deform_curl(params, t, target_matrix);
+	deform_clump(params, t, target_matrix, loc, tang);
 }
 
 /*===================================*/
@@ -177,7 +174,7 @@ void get_strand_data(int index, out int start, out int count, out DeformParams d
 	deform_params.curl_angle = 0.2;
 }
 
-void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang)
+void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang, out float len)
 {
 	int offset = strand_vertex_start + index * 5;
 	vec2 a = read_texdata(offset);
@@ -189,6 +186,7 @@ void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang)
 	co = vec3(a.rg, b.r);
 	nor = vec3(b.g, c.rg);
 	tang = vec3(d.rg, e.r);
+	len = e.g;
 }
 
 void get_strand_root(int index, out vec3 co)
@@ -220,6 +218,7 @@ struct ParentCurveResult
 	vec3 co;
 	vec3 nor;
 	vec3 tang;
+	float len;
 
 	// Only needed for the primary parent curve
 	vec3 rootco;
@@ -250,51 +249,59 @@ bool interpolate_parent_curve(int index, float curve_param, out ParentCurveResul
 	float lerpfac = arclength - floor(arclength);
 #endif
 	
-	vec3 co0, nor0, tang0;
-	vec3 co1, nor1, tang1;
-	get_strand_vertex(start + segment, co0, nor0, tang0);
-	get_strand_vertex(start + segment + 1, co1, nor1, tang1);
-	
+	vec3 co0, co1;
+	vec3 nor0, nor1;
+	vec3 tang0, tang1;
+	float len0, len1;
+	get_strand_vertex(start + segment, co0, nor0, tang0, len0);
+	get_strand_vertex(start + segment + 1, co1, nor1, tang1, len1);
+
 	result.co = mix(co0, co1, lerpfac) - result.rootco;
 	result.nor = mix(nor0, nor1, lerpfac);
 	result.tang = mix(tang0, tang1, lerpfac);
+	result.len = mix(len0, len1, lerpfac);
 
 	return true;
 }
 
 void interpolate_vertex(int fiber_index, float curve_param,
-	                    out vec3 co, out vec3 tang,
+	                    out vec3 co, out vec3 tang, out float len,
 	                    out mat4 target_matrix, out DeformParams deform_params)
 {
-	co = vec3(0.0);
-	tang = vec3(0.0);
-	target_matrix = mat4(1.0);
-
 	ivec4 parent_index;
 	vec4 parent_weight;
 	vec3 rootco;
 	get_fiber_data(fiber_index, parent_index, parent_weight, rootco);
 
+	co = vec3(0.0);
+	tang = vec3(0.0);
+	len = 0.0;
+	target_matrix = mat4(1.0);
+
 	ParentCurveResult p1, p2, p3, p4;
 	if (interpolate_parent_curve(parent_index.x, curve_param, p1))
 	{
 		co += parent_weight.x * p1.co;
 		tang += parent_weight.x * normalize(p1.tang);
+		len += parent_weight.x * p1.len;
 	}
 	if (interpolate_parent_curve(parent_index.y, curve_param, p2))
 	{
 		co += parent_weight.y * p2.co;
 		tang += parent_weight.y * normalize(p2.tang);
+		len += parent_weight.y * p2.len;
 	}
 	if (interpolate_parent_curve(parent_index.z, curve_param, p3))
 	{
 		co += parent_weight.z * p3.co;
 		tang += parent_weight.z * normalize(p3.tang);
+		len += parent_weight.z * p3.len;
 	}
 	if (interpolate_parent_curve(parent_index.w, curve_param, p4))
 	{
 		co += parent_weight.w * p4.co;
 		tang += parent_weight.w * normalize(p4.tang);
+		len += parent_weight.w * p4.len;
 	}
 	
 	co += rootco;
@@ -309,15 +316,15 @@ void hair_fiber_get_vertex(
         out vec3 pos, out vec3 tang, out vec3 binor,
         out float time, out float thickness, out float thick_time)
 {
+	float len;
 	mat4 target_matrix;
 	DeformParams deform_params;
-	interpolate_vertex(fiber_index, curve_param, pos, tang, target_matrix, deform_params);
+	interpolate_vertex(fiber_index, curve_param, pos, tang, len, target_matrix, deform_params);
 
 	vec3 camera_vec = (is_persp) ? pos - camera_pos : -camera_z;
 	binor = normalize(cross(camera_vec, tang));
 
-	// TODO define proper curve scale, independent of subdivision!
-	deform_fiber(deform_params, curve_param, 1.0, target_matrix, pos, tang);
+	deform_fiber(deform_params, len, target_matrix, pos, tang);
 
 	time = curve_param;
 	thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time);



More information about the Bf-blender-cvs mailing list