[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