From 6a88f83d679f281d7adb3798ab4770069a63c2da Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 24 Sep 2021 07:42:36 +0200 Subject: Hair Info Length Attribute Goal is to add the length attribute to the Hair Info node, for better control over color gradients or similar along the hair. Reviewed By: #eevee_viewport, brecht Differential Revision: https://developer.blender.org/D10481 --- intern/cycles/blender/blender_curves.cpp | 18 ++++++++++++++++++ intern/cycles/kernel/kernel_types.h | 1 + intern/cycles/kernel/osl/osl_services.cpp | 1 + intern/cycles/kernel/osl/osl_services.h | 1 + intern/cycles/kernel/shaders/node_hair_info.osl | 2 ++ intern/cycles/kernel/svm/svm_geometry.h | 2 ++ intern/cycles/kernel/svm/svm_types.h | 1 + intern/cycles/render/attribute.cpp | 5 +++++ intern/cycles/render/nodes.cpp | 10 ++++++++++ 9 files changed, 41 insertions(+) (limited to 'intern') diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 6fe5ea41fff..c7851e40543 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -283,10 +283,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa return; Attribute *attr_intercept = NULL; + Attribute *attr_length = NULL; Attribute *attr_random = NULL; if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT); + if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) + attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH); if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM); @@ -336,6 +339,11 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa num_curve_keys++; } + if (attr_length != NULL) + { + attr_length->add(CData->curve_length[curve]); + } + if (attr_random != NULL) { attr_random->add(hash_uint2_to_float(num_curves, 0)); } @@ -657,11 +665,16 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair) /* Add requested attributes. */ Attribute *attr_intercept = NULL; + Attribute *attr_length = NULL; Attribute *attr_random = NULL; if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) { attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT); } + if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) + { + attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH); + } if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) { attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM); } @@ -714,6 +727,11 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair) } } + if (attr_length) + { + attr_length->add(length); + } + /* Random number per curve. */ if (attr_random != NULL) { attr_random->add(hash_uint2_to_float(b_curve.index(), 0)); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 66b7310ab65..3cc42bf7a85 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -572,6 +572,7 @@ typedef enum AttributeStandard { ATTR_STD_MOTION_VERTEX_NORMAL, ATTR_STD_PARTICLE, ATTR_STD_CURVE_INTERCEPT, + ATTR_STD_CURVE_LENGTH, ATTR_STD_CURVE_RANDOM, ATTR_STD_PTEX_FACE_ID, ATTR_STD_PTEX_UV, diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 396f42080e4..4fc46a255a8 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -107,6 +107,7 @@ ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced"); ustring OSLRenderServices::u_is_smooth("geom:is_smooth"); ustring OSLRenderServices::u_is_curve("geom:is_curve"); ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness"); +ustring OSLRenderServices::u_curve_length("geom:curve_length"); ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal"); ustring OSLRenderServices::u_curve_random("geom:curve_random"); ustring OSLRenderServices::u_path_ray_length("path:ray_length"); diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 58accb46e7d..2a5400282b3 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -294,6 +294,7 @@ class OSLRenderServices : public OSL::RendererServices { static ustring u_is_smooth; static ustring u_is_curve; static ustring u_curve_thickness; + static ustring u_curve_length; static ustring u_curve_tangent_normal; static ustring u_curve_random; static ustring u_path_ray_length; diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl index ee08ea57e68..ddc2e28b83a 100644 --- a/intern/cycles/kernel/shaders/node_hair_info.osl +++ b/intern/cycles/kernel/shaders/node_hair_info.osl @@ -18,12 +18,14 @@ shader node_hair_info(output float IsStrand = 0.0, output float Intercept = 0.0, + output float Length = 0.0, output float Thickness = 0.0, output normal TangentNormal = N, output float Random = 0) { getattribute("geom:is_curve", IsStrand); getattribute("geom:curve_intercept", Intercept); + getattribute("geom:curve_length", Length); getattribute("geom:curve_thickness", Thickness); getattribute("geom:curve_tangent_normal", TangentNormal); getattribute("geom:curve_random", Random); diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 10e9f291d0e..432529eb061 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -213,6 +213,8 @@ ccl_device_noinline void svm_node_hair_info( } case NODE_INFO_CURVE_INTERCEPT: break; /* handled as attribute */ + case NODE_INFO_CURVE_LENGTH: + break; /* handled as attribute */ case NODE_INFO_CURVE_RANDOM: break; /* handled as attribute */ case NODE_INFO_CURVE_THICKNESS: { diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index c053be96c51..313bc3235b9 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -173,6 +173,7 @@ typedef enum NodeParticleInfo { typedef enum NodeHairInfo { NODE_INFO_CURVE_IS_STRAND, NODE_INFO_CURVE_INTERCEPT, + NODE_INFO_CURVE_LENGTH, NODE_INFO_CURVE_THICKNESS, /* Fade for minimum hair width transiency. */ // NODE_INFO_CURVE_FADE, diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index ea5a5f50f2d..aaf21ad9fd2 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -342,6 +342,8 @@ const char *Attribute::standard_name(AttributeStandard std) return "particle"; case ATTR_STD_CURVE_INTERCEPT: return "curve_intercept"; + case ATTR_STD_CURVE_LENGTH: + return "curve_length"; case ATTR_STD_CURVE_RANDOM: return "curve_random"; case ATTR_STD_PTEX_FACE_ID: @@ -586,6 +588,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_LENGTH: + attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE); + break; case ATTR_STD_CURVE_RANDOM: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE); break; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 03b79d7de3e..e5071c25730 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -4368,6 +4368,7 @@ NODE_DEFINE(HairInfoNode) SOCKET_OUT_FLOAT(is_strand, "Is Strand"); SOCKET_OUT_FLOAT(intercept, "Intercept"); + SOCKET_OUT_FLOAT(size, "Length"); SOCKET_OUT_FLOAT(thickness, "Thickness"); SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal"); #if 0 /* Output for minimum hair width transparency - deactivated. */ @@ -4390,6 +4391,9 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) if (!intercept_out->links.empty()) attributes->add(ATTR_STD_CURVE_INTERCEPT); + if (!output("Length")->links.empty()) + attributes->add(ATTR_STD_CURVE_LENGTH); + if (!output("Random")->links.empty()) attributes->add(ATTR_STD_CURVE_RANDOM); } @@ -4412,6 +4416,12 @@ void HairInfoNode::compile(SVMCompiler &compiler) compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); } + out = output("Length"); + if (!out->links.empty()) { + int attr = compiler.attribute(ATTR_STD_CURVE_LENGTH); + compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); + } + out = output("Thickness"); if (!out->links.empty()) { compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out)); -- cgit v1.2.3