[Bf-blender-cvs] [fd603e4] strand_gpu: Added "effects" to the hair modifier for testing deformation of the hair in the shader.

Lukas Tönne noreply at git.blender.org
Mon Jul 11 09:24:26 CEST 2016


Commit: fd603e4f21591f7ae04f531f5a80a32a6abe239c
Author: Lukas Tönne
Date:   Mon Jul 11 09:22:22 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rBfd603e4f21591f7ae04f531f5a80a32a6abe239c

Added "effects" to the hair modifier for testing deformation of the hair in the shader.

These features will ultimately be implemented through nodes, but they are quite useful
for testing the shading itself and the performance.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/intern/strands.c
M	source/blender/editors/space_view3d/drawstrands.c
M	source/blender/gpu/GPU_strands.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_strands.c
M	source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_vert.glsl
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_strand_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_strands.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 66d1918..4328546 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -897,6 +897,19 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 
         col.label("Shader Model:")
         col.prop(md, "shader_model", text="")
+        
+        layout.separator()
+
+        box = layout.box()
+        box.prop(md, "use_clumping_effect")
+        if md.use_clumping_effect:
+            box.prop(md, "clumping_factor")
+            box.prop(md, "clumping_shape")
+        
+        box = layout.box()
+        box.prop(md, "use_curl_effect")
+        if md.use_curl_effect:
+            pass
 
     def SUBSURF(self, layout, ob, md):
         layout.row().prop(md, "subdivision_type", expand=True)
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index b5236e7..07ded24 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -388,6 +388,61 @@ static void sort_fiber_weights(StrandFiber *fiber)
 #undef FIBERSWAP
 }
 
+static void strand_find_closest(StrandFiber *fiber, const float loc[3],
+                                const KDTree *tree, const float (*strandloc)[3])
+{
+	/* Use the 3 closest strands for interpolation.
+	 * Note that we have up to 4 possible weights, but we
+	 * only look for a triangle with this method.
+	 */
+	KDTreeNearest nearest[3];
+	const float *sloc[3] = {NULL};
+	int k, found = BLI_kdtree_find_nearest_n(tree, loc, nearest, 3);
+	for (k = 0; k < found; ++k) {
+		fiber->control_index[k] = nearest[k].index;
+		sloc[k] = strandloc[nearest[k].index];
+	}
+	
+	/* calculate barycentric interpolation weights */
+	if (found == 3) {
+		float closest[3];
+		closest_on_tri_to_point_v3(closest, loc, sloc[0], sloc[1], sloc[2]);
+		
+		float w[4];
+		interp_weights_face_v3(w, sloc[0], sloc[1], sloc[2], NULL, closest);
+		copy_v3_v3(fiber->control_weight, w);
+		/* float precisions issues can cause slightly negative weights */
+		CLAMP3(fiber->control_weight, 0.0f, 1.0f);
+	}
+	else if (found == 2) {
+		fiber->control_weight[1] = line_point_factor_v3(loc, sloc[0], sloc[1]);
+		fiber->control_weight[0] = 1.0f - fiber->control_weight[1];
+		/* float precisions issues can cause slightly negative weights */
+		CLAMP2(fiber->control_weight, 0.0f, 1.0f);
+	}
+	else if (found == 1) {
+		fiber->control_weight[0] = 1.0f;
+	}
+	
+	sort_fiber_weights(fiber);
+}
+
+static void strand_calc_root_distance(StrandFiber *fiber, const float loc[3], const float nor[3], const float tang[3],
+                                      const float (*strandloc)[3])
+{
+	if (fiber->control_index[0] == STRAND_INDEX_NONE)
+		return;
+	
+	float cotang[3];
+	cross_v3_v3v3(cotang, nor, tang);
+	
+	const float *sloc0 = strandloc[fiber->control_index[0]];
+	float dist[3];
+	sub_v3_v3v3(dist, loc, sloc0);
+	fiber->root_distance[0] = dot_v3v3(dist, tang);
+	fiber->root_distance[1] = dot_v3v3(dist, cotang);
+}
+
 static void strands_calc_weights(const Strands *strands, struct DerivedMesh *scalp, StrandFiber *fibers, int num_fibers)
 {
 	float (*strandloc)[3] = MEM_mallocN(sizeof(float) * 3 * strands->totcurves, "strand locations");
@@ -409,41 +464,10 @@ static void strands_calc_weights(const Strands *strands, struct DerivedMesh *sca
 		float loc[3], nor[3], tang[3];
 		if (BKE_mesh_sample_eval(scalp, &fiber->root, loc, nor, tang)) {
 			
-			/* Use the 3 closest strands for interpolation.
-			 * Note that we have up to 4 possible weights, but we
-			 * only look for a triangle with this method.
-			 */
-			KDTreeNearest nearest[3];
-			float *sloc[3] = {NULL};
-			int k, found = BLI_kdtree_find_nearest_n(tree, loc, nearest, 3);
-			for (k = 0; k < found; ++k) {
-				fiber->control_index[k] = nearest[k].index;
-				sloc[k] = strandloc[nearest[k].index];
-			}
-			
-			/* calculate barycentric interpolation weights */
-			if (found == 3) {
-				float closest[3];
-				closest_on_tri_to_point_v3(closest, loc, sloc[0], sloc[1], sloc[2]);
-				
-				float w[4];
-				interp_weights_face_v3(w, sloc[0], sloc[1], sloc[2], NULL, closest);
-				copy_v3_v3(fiber->control_weight, w);
-				/* float precisions issues can cause slightly negative weights */
-				CLAMP3(fiber->control_weight, 0.0f, 1.0f);
-			}
-			else if (found == 2) {
-				fiber->control_weight[1] = line_point_factor_v3(loc, sloc[0], sloc[1]);
-				fiber->control_weight[0] = 1.0f - fiber->control_weight[1];
-				/* float precisions issues can cause slightly negative weights */
-				CLAMP2(fiber->control_weight, 0.0f, 1.0f);
-			}
-			else if (found == 1) {
-				fiber->control_weight[0] = 1.0f;
-			}
-			
-			sort_fiber_weights(fiber);
+			strand_find_closest(fiber, loc, tree, strandloc);
 			verify_fiber_weights(fiber);
+			
+			strand_calc_root_distance(fiber, loc, nor, tang, strandloc);
 		}
 	}
 	
diff --git a/source/blender/editors/space_view3d/drawstrands.c b/source/blender/editors/space_view3d/drawstrands.c
index 6e6a00f..6b0f227 100644
--- a/source/blender/editors/space_view3d/drawstrands.c
+++ b/source/blender/editors/space_view3d/drawstrands.c
@@ -79,6 +79,25 @@ static GPUStrands_ShaderModel get_shader_model(int smd_shader_model)
 	return 0;
 }
 
+static int get_effects(int smd_effects)
+{
+	GPUStrands_Effects effects = 0;
+	if (smd_effects & MOD_STRANDS_EFFECT_CLUMPING)
+		effects |= GPU_STRAND_EFFECT_CLUMPING;
+	if (smd_effects & MOD_STRANDS_EFFECT_CURL)
+		effects |= GPU_STRAND_EFFECT_CURL;
+	
+	return effects;
+}
+
+static void bind_strands_shader(GPUStrandsShader *shader, RegionView3D *rv3d,
+                                Object *ob, StrandsModifierData *smd)
+{
+	GPU_strand_shader_bind_uniforms(shader, ob->obmat, rv3d->viewmat);
+	GPU_strand_shader_bind(shader, rv3d->viewmat, rv3d->viewinv,
+	                       smd->clumping_factor, smd->clumping_shape);
+}
+
 void draw_strands(Scene *scene, View3D *UNUSED(v3d), RegionView3D *rv3d,
                   Object *ob, StrandsModifierData *smd)
 {
@@ -96,7 +115,9 @@ void draw_strands(Scene *scene, View3D *UNUSED(v3d), RegionView3D *rv3d,
 	if (smd->gpu_buffer == NULL)
 		smd->gpu_buffer = GPU_strands_buffer_create(&params);
 	GPUDrawStrands *buffer = smd->gpu_buffer;
-	GPUStrandsShader *shader = GPU_strand_shader_get(strands, get_shader_model(smd->shader_model));
+	GPUStrandsShader *shader = GPU_strand_shader_get(strands,
+	                                                 get_shader_model(smd->shader_model),
+	                                                 get_effects(smd->effects));
 	
 	if (show_controls) {
 		GPU_strands_setup_edges(buffer, &params);
@@ -108,8 +129,7 @@ void draw_strands(Scene *scene, View3D *UNUSED(v3d), RegionView3D *rv3d,
 	}
 	
 	if (show_strands) {
-		GPU_strand_shader_bind_uniforms(shader, ob->obmat, rv3d->viewmat);
-		GPU_strand_shader_bind(shader, rv3d->viewmat, rv3d->viewinv);
+		bind_strands_shader(shader, rv3d, ob, smd);
 		
 		GPU_strands_setup_fibers(buffer, &params);
 		if (buffer->fiber_points) {
@@ -460,7 +480,9 @@ void draw_strands_edit(Scene *scene, View3D *UNUSED(v3d), RegionView3D *rv3d,
 	if (smd->gpu_buffer == NULL)
 		smd->gpu_buffer = GPU_strands_buffer_create(&params);
 	GPUDrawStrands *buffer = smd->gpu_buffer;
-	GPUStrandsShader *shader = GPU_strand_shader_get(smd->strands, get_shader_model(smd->shader_model));
+	GPUStrandsShader *shader = GPU_strand_shader_get(smd->strands,
+	                                                 get_shader_model(smd->shader_model),
+	                                                 get_effects(smd->effects));
 	
 	if (show_controls) {
 		GPU_strands_setup_edges(buffer, &params);
@@ -471,8 +493,7 @@ void draw_strands_edit(Scene *scene, View3D *UNUSED(v3d), RegionView3D *rv3d,
 	}
 	
 	if (show_strands) {
-		GPU_strand_shader_bind_uniforms(shader, ob->obmat, rv3d->viewmat);
-		GPU_strand_shader_bind(shader, rv3d->viewmat, rv3d->viewinv);
+		bind_strands_shader(shader, rv3d, ob, smd);
 		
 		GPU_strands_setup_fibers(buffer, &params);
 		if (buffer->fiber_points) {
diff --git a/source/blender/gpu/GPU_strands.h b/source/blender/gpu/GPU_strands.h
index 6a19d17..e74165f 100644
--- a/source/blender/gpu/GPU_strands.h
+++ b/source/blender/gpu/GPU_strands.h
@@ -48,13 +48,21 @@ typedef enum GPUStrands_ShaderModel {
 	GPU_STRAND_SHADER_MARSCHNER,
 } GPUStrands_ShaderModel;
 
-GPUStrandsShader *GPU_strand_shader_get(struct Strands *strands, GPUStrands_ShaderModel shader_model);
+typedef enum GPUStrands_Effects {
+	GPU_STRAND_EFFECT_CLUMPING      = (1 << 0),
+	GPU_STRAND_EFFECT_CURL          = (1 << 1),
+} GPUStrands_Effects;
+
+GPUStrandsShader *GPU_strand_shader_get(struct Strands *strands,
+                                        GPUStrands_ShaderModel shader_model,
+                                        int effects);
 
 void GPU_strand_shader_free(struct GPUStrandsShader *gpu_shader);
 
 void GPU_strand_shader_bind(
         GPUStrandsShader *gpu_shader,
-        float viewmat[4][4], float viewinv[4][4]);
+        float viewmat[4][4], float viewinv[4][4],
+        float clumping_factor, float clumping_shape);
 void GPU_strand_shader_bind_uniforms(
         GPUStrandsShader *gpu_shader,
         float obmat[4][4], float viewmat[4][4]);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 0905416..0308ca8 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -2492,9 +2492,7 @@ static void strands_copy_fiber_data(GPUDrawStrandsParams *params, FiberVertex *v
 				varray->control_index[k] = fiber->control_index[k];
 				varray->control_weight[k] = fiber->control_weight[k];
 			}
-			/* TODO */
-			varray->root_distance[0] = 0.0f;
-			varray->root_distance[1] = 0.0f;
+			copy_v2_v2(varray->root_distance, fiber->root_distance);
 			++varray;
 		}
 	}
@@ -2510,9 +2508,7 @@ static void strands_copy_fiber_data(GPUDrawStrandsParams *params, FiberVertex *v
 				varray->control_index[k] = fiber->control_index[k];
 				varray->control_weight[k] = fiber->control_weight[k];
 			}
-			/* TODO */
-			va

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list