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.
This commit is contained in:
parent
d640ce40aa
commit
37f65e9dc4
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, "" }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue