[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56072] trunk/blender: Cycles Hair: Strand Minimum Pixel Size

Stuart Broadfoot gbroadfoot at hotmail.com
Mon Apr 15 23:38:31 CEST 2013


Revision: 56072
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56072
Author:   broadstu
Date:     2013-04-15 21:38:31 +0000 (Mon, 15 Apr 2013)
Log Message:
-----------
Cycles Hair: Strand Minimum Pixel Size

Code is added to restrict the pixel size of strands in cycles. It works best with ribbon primitives and a preset for these is included. It uses distance dependent expansion of the strands and then stochastic strand removal to give a fading. To prevent a slowdown for triangle mesh objects in the BVH an extra visibility flag has been added. It is also only applied for camera rays.

The strand width settings are also changed, so that the particle size is not included in the width calculation. Instead there is a separate particle system parameter for width scaling.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/properties.py
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_curves.cpp
    trunk/blender/intern/cycles/bvh/bvh.cpp
    trunk/blender/intern/cycles/kernel/kernel_bvh.h
    trunk/blender/intern/cycles/kernel/kernel_path.h
    trunk/blender/intern/cycles/kernel/kernel_shader.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/kernel/svm/svm_geometry.h
    trunk/blender/intern/cycles/kernel/svm/svm_types.h
    trunk/blender/intern/cycles/render/camera.cpp
    trunk/blender/intern/cycles/render/camera.h
    trunk/blender/intern/cycles/render/curves.cpp
    trunk/blender/intern/cycles/render/curves.h
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/session.cpp
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_hair_info.c

Modified: trunk/blender/intern/cycles/blender/addon/properties.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/properties.py	2013-04-15 18:49:37 UTC (rev 56071)
+++ trunk/blender/intern/cycles/blender/addon/properties.py	2013-04-15 21:38:31 UTC (rev 56072)
@@ -71,6 +71,7 @@
     ('TRUE_NORMAL', "True Normal", "Use true normals with line segments(good for thin strands)"),
     ('ACCURATE_PRESET', "Accurate", "Use best line segment settings (suitable for glass materials)"),
     ('SMOOTH_CURVES', "Smooth Curves", "Use smooth cardinal curves (slowest)"),
+    ('SMOOTH_RIBBONS', "Ribbons", "Use smooth cardinal curves without thickness"),
     )
 
 enum_curve_primitives = (
@@ -745,11 +746,23 @@
                 min=0, max=100.0,
                 default=1.01,
                 )
+        cls.minimum_width = FloatProperty(
+                name="Minimal width",
+                description="Minimal pixel width for strands (0 - deactivated)",
+                min=0, max=100,
+                default=0.0,
+                )
+        cls.maximum_width = FloatProperty(
+                name="Maximal width",
+                description="Maximum extension that strand radius can be increased by",
+                min=0, max=100,
+                default=0.1,
+                )
         cls.subdivisions = IntProperty(
                 name="Subdivisions",
                 description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
                 min=0, max=24,
-                default=3,
+                default=4,
                 )
 
     @classmethod
@@ -765,15 +778,21 @@
                 description="Cycles hair settings",
                 type=cls,
                 )
+        cls.radius_scale = FloatProperty(
+                name="Radius Scaling",
+                description="Multiplier of width properties",
+                min=0.0, max=1000.0,
+                default=0.01,
+                )
         cls.root_width = FloatProperty(
-                name="Root Size Multiplier",
-                description="Multiplier of particle size for the strand's width at root",
+                name="Root Size",
+                description="Strand's width at root",
                 min=0.0, max=1000.0,
                 default=1.0,
                 )
         cls.tip_width = FloatProperty(
-                name="Tip Size Multiplier",
-                description="Multiplier of particle size for the strand's width at tip",
+                name="Tip Multiplier",
+                description="Strand's width at tip",
                 min=0.0, max=1000.0,
                 default=0.0,
                 )

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2013-04-15 18:49:37 UTC (rev 56071)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2013-04-15 21:38:31 UTC (rev 56072)
@@ -1079,6 +1079,10 @@
 
             row = layout.row()
             row.prop(ccscene, "use_parents", text="Include parents")
+        
+        row = layout.row()
+        row.prop(ccscene, "minimum_width", text="Min Pixels")
+        row.prop(ccscene, "maximum_width", text="Max Ext.")
 
 
 class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
@@ -1103,12 +1107,15 @@
 
         row = layout.row()
         row.prop(cpsys, "shape", text="Shape")
-        row.prop(cpsys, "use_closetip", text="Close tip")
 
-        layout.label(text="Width multiplier:")
+        layout.label(text="Thickness:")
         row = layout.row()
         row.prop(cpsys, "root_width", text="Root")
         row.prop(cpsys, "tip_width", text="Tip")
+        
+        row = layout.row()
+        row.prop(cpsys, "radius_scale", text="Scaling")
+        row.prop(cpsys, "use_closetip", text="Close tip")
 
 
 class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):

Modified: trunk/blender/intern/cycles/blender/blender_curves.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_curves.cpp	2013-04-15 18:49:37 UTC (rev 56071)
+++ trunk/blender/intern/cycles/blender/blender_curves.cpp	2013-04-15 21:38:31 UTC (rev 56072)
@@ -195,7 +195,7 @@
 				CData->psys_curvenum.push_back(totcurves);
 				CData->psys_shader.push_back(shader);
 
-				float radius = b_psys.settings().particle_size() * 0.5f;
+				float radius = get_float(cpsys, "radius_scale") * 0.5f;
 	
 				CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width"));
 				CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width"));
@@ -884,6 +884,8 @@
 	CurveSystemManager prev_curve_system_manager = *curve_system_manager;
 
 	curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
+	curve_system_manager->minimum_width = get_float(csscene, "minimum_width");
+	curve_system_manager->maximum_width = get_float(csscene, "maximum_width");
 
 	if(preset == CURVE_CUSTOM) {
 		/*custom properties*/
@@ -957,6 +959,12 @@
 				curve_system_manager->use_backfacing = true;
 				curve_system_manager->subdivisions = 4;
 				break;
+			case CURVE_SMOOTH_RIBBONS:
+				/*Cardinal ribbons preset*/
+				curve_system_manager->primitive = CURVE_RIBBONS;
+				curve_system_manager->use_backfacing = false;
+				curve_system_manager->subdivisions = 4;
+				break;
 		}
 		
 	}

Modified: trunk/blender/intern/cycles/bvh/bvh.cpp
===================================================================
--- trunk/blender/intern/cycles/bvh/bvh.cpp	2013-04-15 18:49:37 UTC (rev 56071)
+++ trunk/blender/intern/cycles/bvh/bvh.cpp	2013-04-15 21:38:31 UTC (rev 56072)
@@ -341,6 +341,9 @@
 			int tob = pack.prim_object[i];
 			Object *ob = objects[tob];
 			pack.prim_visibility[i] = ob->visibility;
+
+			if(pack.prim_segment[i] != ~0)
+				pack.prim_visibility[i] |= PATH_RAY_CURVE;
 		}
 		else {
 			memset(&pack.tri_woop[i * nsize], 0, sizeof(float4)*3);
@@ -651,6 +654,8 @@
 					float mr = max(mesh->curve_keys[k0].radius,mesh->curve_keys[k1].radius);
 					bbox.grow(lower, mr);
 					bbox.grow(upper, mr);
+
+					visibility |= PATH_RAY_CURVE;
 				}
 				else {
 					/* triangles */

Modified: trunk/blender/intern/cycles/kernel/kernel_bvh.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_bvh.h	2013-04-15 18:49:37 UTC (rev 56071)
+++ trunk/blender/intern/cycles/kernel/kernel_bvh.h	2013-04-15 21:38:31 UTC (rev 56072)
@@ -113,11 +113,22 @@
 #endif
 
 /* intersect two bounding boxes */
+#ifdef __HAIR__
 __device_inline void bvh_node_intersect(KernelGlobals *kg,
 	bool *traverseChild0, bool *traverseChild1,
 	bool *closestChild1, int *nodeAddr0, int *nodeAddr1,
+	float3 P, float3 idir, float t, uint visibility, int nodeAddr, float difl = 0.0f, float extmax = 0.0f)
+{
+	float hdiff = 1.0f + difl;
+	float ldiff = 1.0f - difl;
+#else
+__device_inline void bvh_node_intersect(KernelGlobals *kg,
+	bool *traverseChild0, bool *traverseChild1,
+	bool *closestChild1, int *nodeAddr0, int *nodeAddr1,
 	float3 P, float3 idir, float t, uint visibility, int nodeAddr)
 {
+#endif
+
 	/* fetch node data */
 	float4 n0xy = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+0);
 	float4 n1xy = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+1);
@@ -144,6 +155,19 @@
 	NO_EXTENDED_PRECISION float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f);
 	NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
 
+#ifdef __HAIR__
+	if(difl != 0.0f) {
+		if(__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
+			c0min = max(ldiff * c0min, c0min - extmax);
+			c0max = min(hdiff * c0max, c0max + extmax);
+		}
+		if(__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
+			c1min = max(ldiff * c1min, c1min - extmax);
+			c1max = min(hdiff * c1max, c1max + extmax);
+		}
+	}
+#endif
+
 	/* decide which nodes to traverse next */
 #ifdef __VISIBILITY_FLAG__
 	/* this visibility test gives a 5% performance hit, how to solve? */
@@ -257,8 +281,9 @@
 }
 
 __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
-	float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
+	float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state = NULL, float difl = 0.0f, float extmax = 0.0f)
 {
+	float epsilon = 0.0f;
 	int depth = kernel_data.curve_kernel_data.subdivisions;
 
 	/* curve Intersection check */
@@ -316,23 +341,31 @@
 
 	float r_curr = max(r_st, r_en);
 
+	if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
+		epsilon = 2 * r_curr;
+
 	/*find bounds - this is slow for cubic curves*/
 	float upper,lower;
+
+	float zextrem[4];
+	curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
+	if(lower - r_curr > isect->t || upper + r_curr < epsilon)
+		return;
+
+	/*minimum width extension*/
+	float mw_extension = min(difl * fabsf(upper), extmax);
+	float r_ext = mw_extension + r_curr;
+
 	float xextrem[4];
 	curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
-	if(lower > r_curr || upper < -r_curr)
+	if(lower > r_ext || upper < -r_ext)
 		return;
 
 	float yextrem[4];
 	curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
-	if(lower > r_curr || upper < -r_curr)
+	if(lower > r_ext || upper < -r_ext)
 		return;
 
-	float zextrem[4];
-	curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
-	if(lower - r_curr > isect->t || upper + r_curr < 0.0f)
-		return;
-
 	/*setup recurrent loop*/
 	int level = 1 << depth;
 	int tree = 0;
@@ -381,7 +414,11 @@
 		float r2 = r_st + (r_en - r_st) * i_en;
 		r_curr = max(r1, r2);
 
-		if (bminz - r_curr > isect->t || bmaxz + r_curr < 0.0f|| bminx > r_curr || bmaxx < -r_curr || bminy > r_curr || bmaxy < -r_curr) {
+		mw_extension = min(difl * fabsf(bmaxz), extmax);
+		float r_ext = mw_extension + r_curr;
+		float coverage = 1.0f;
+
+		if (bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list