[Bf-blender-cvs] [37f65e9dc4b] master: Cycles: Implement index output for hair node

Sergey Sharybin noreply at git.blender.org
Tue Feb 13 14:22:04 CET 2018


Commit: 37f65e9dc4bcfa5225a114feabac753e342bb201
Author: Sergey Sharybin
Date:   Tue Feb 13 14:20:47 2018 +0100
Branches: master
https://developer.blender.org/rB37f65e9dc4bcfa5225a114feabac753e342bb201

Cycles: Implement index output for hair node

This is like the only way to add variety to hair which is created
using simple children. Used here for the hair.

Maybe not ideal, but the time will show.

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

M	intern/cycles/blender/blender_curves.cpp
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/shaders/node_hair_info.osl
M	intern/cycles/kernel/svm/svm_geometry.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/nodes.cpp
M	source/blender/nodes/shader/nodes/node_shader_hair_info.c

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

diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 42b985305ea..c8eb879e5cb 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -565,9 +565,12 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa
 		return;
 
 	Attribute *attr_intercept = NULL;
+	Attribute *attr_index = NULL;
 
 	if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
 		attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+	if(mesh->need_attribute(scene, ATTR_STD_CURVE_INDEX))
+		attr_index = mesh->curve_attributes.add(ATTR_STD_CURVE_INDEX);
 
 	/* compute and reserve size of arrays */
 	for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
@@ -612,12 +615,25 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa
 				num_curve_keys++;
 			}
 
+			if(attr_index != NULL) {
+				attr_index->add(num_curves);
+			}
+
 			mesh->add_curve(num_keys, CData->psys_shader[sys]);
 			num_keys += num_curve_keys;
 			num_curves++;
 		}
 	}
 
+	if(attr_index != NULL) {
+		/* Normalize index to 0..1 range. */
+		float *curve_index = attr_index->data_float();
+		const float norm_factor = 1.0f / (float)num_curves;
+		for(int i = 0; i < num_curves; ++i) {
+			curve_index[i] *= norm_factor;
+		}
+	}
+
 	/* check allocation */
 	if((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) {
 		VLOG(1) << "Allocation failed, clearing data";
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index cd3b450932f..0bb5873e75c 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -772,6 +772,7 @@ typedef enum AttributeStandard {
 	ATTR_STD_MOTION_VERTEX_NORMAL,
 	ATTR_STD_PARTICLE,
 	ATTR_STD_CURVE_INTERCEPT,
+	ATTR_STD_CURVE_INDEX,
 	ATTR_STD_PTEX_FACE_ID,
 	ATTR_STD_PTEX_UV,
 	ATTR_STD_VOLUME_DENSITY,
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
index 965d2a3c7f7..79995bdbfc3 100644
--- a/intern/cycles/kernel/shaders/node_hair_info.osl
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -20,11 +20,13 @@ shader node_hair_info(
 	output float IsStrand = 0.0,
 	output float Intercept = 0.0,
 	output float Thickness = 0.0,
-	output normal TangentNormal = N)
+	output normal TangentNormal = N,
+	output float Index = 0)
 {
 	getattribute("geom:is_curve", IsStrand);
 	getattribute("geom:curve_intercept", Intercept);
 	getattribute("geom:curve_thickness", Thickness);
 	getattribute("geom:curve_tangent_normal", TangentNormal);
+	getattribute("geom:curve_index", Index);
 }
 
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 9af4a0182d9..6c88d150b60 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -180,6 +180,8 @@ ccl_device void svm_node_hair_info(KernelGlobals *kg,
 		}
 		case NODE_INFO_CURVE_INTERCEPT:
 			break; /* handled as attribute */
+		case NODE_INFO_CURVE_INDEX:
+			break; /* handled as attribute */
 		case NODE_INFO_CURVE_THICKNESS: {
 			data = curve_thickness(kg, sd);
 			stack_store_float(stack, out_offset, data);
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index c0ce0f52cd0..b3a2cf6e9ae 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -176,7 +176,8 @@ typedef enum NodeHairInfo {
 	NODE_INFO_CURVE_THICKNESS,
 	/*fade for minimum hair width transpency*/
 	/*NODE_INFO_CURVE_FADE,*/
-	NODE_INFO_CURVE_TANGENT_NORMAL
+	NODE_INFO_CURVE_TANGENT_NORMAL,
+	NODE_INFO_CURVE_INDEX,
 } NodeHairInfo;
 
 typedef enum NodeLightPath {
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 95e69df6885..2d1100c9d88 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -267,6 +267,8 @@ const char *Attribute::standard_name(AttributeStandard std)
 			return "particle";
 		case ATTR_STD_CURVE_INTERCEPT:
 			return "curve_intercept";
+		case ATTR_STD_CURVE_INDEX:
+			return "curve_index";
 		case ATTR_STD_PTEX_FACE_ID:
 			return "ptex_face_id";
 		case ATTR_STD_PTEX_UV:
@@ -451,6 +453,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
 			case ATTR_STD_CURVE_INTERCEPT:
 				attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
 				break;
+			case ATTR_STD_CURVE_INDEX:
+				attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE);
+				break;
 			case ATTR_STD_GENERATED_TRANSFORM:
 				attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
 				break;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index cb884ba9231..d2a03ceb76a 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -3572,6 +3572,7 @@ NODE_DEFINE(HairInfoNode)
 #if 0 /*output for minimum hair width transparency - deactivated */
 	SOCKET_OUT_FLOAT(fade, "Fade");
 #endif
+	SOCKET_OUT_FLOAT(index, "Index");
 
 	return type;
 }
@@ -3588,6 +3589,9 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
 
 		if(!intercept_out->links.empty())
 			attributes->add(ATTR_STD_CURVE_INTERCEPT);
+
+		if(!output("Index")->links.empty())
+			attributes->add(ATTR_STD_CURVE_INDEX);
 	}
 
 	ShaderNode::attributes(shader, attributes);
@@ -3623,6 +3627,11 @@ void HairInfoNode::compile(SVMCompiler& compiler)
 		compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
 	}*/
 
+	out = output("Index");
+	if(!out->links.empty()) {
+		int attr = compiler.attribute(ATTR_STD_CURVE_INDEX);
+		compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
+	}
 }
 
 void HairInfoNode::compile(OSLCompiler& compiler)
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
index 63adba750cf..5fe74976c08 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hair_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
@@ -33,6 +33,7 @@ static bNodeSocketTemplate outputs[] = {
 	{	SOCK_FLOAT,  0, N_("Thickness"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 	{	SOCK_VECTOR, 0, N_("Tangent Normal"),	0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 	/*{	SOCK_FLOAT,  0, N_("Fade"),				0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},*/
+	{	SOCK_FLOAT,  0, "Index" },
 	{	-1, 0, ""	}
 };



More information about the Bf-blender-cvs mailing list