[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