Merge code for circular and elliptical cross-sections

This commit is contained in:
Weizhen Huang 2023-01-20 20:11:30 +01:00
parent 46bc834a3d
commit 33ff1ce7b2
13 changed files with 222 additions and 792 deletions

View File

@ -668,11 +668,7 @@ static ShaderNode *add_node(Scene *scene,
"parametrization",
NODE_MICROFACET_HAIR_NUM,
NODE_MICROFACET_HAIR_REFLECTANCE));
microfacet_hair->set_cross_section(
(NodeMicrofacetHairCrossSectionType)get_enum(b_microfacet_hair_node.ptr,
"cross_section",
NODE_MICROFACET_HAIR_CROSS_SECTION_NUM,
NODE_MICROFACET_HAIR_CIRCULAR));
microfacet_hair->set_distribution_type(
(NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr,
"distribution_type",

File diff suppressed because it is too large Load Diff

View File

@ -1150,7 +1150,6 @@ ccl_device void osl_closure_microfacet_hair_setup(KernelGlobals kg,
bsdf->roughness = closure->roughness;
bsdf->tilt = closure->tilt;
bsdf->eta = closure->eta;
bsdf->cross_section = closure->cross_section;
bsdf->distribution_type = closure->distribution_type;
bsdf->aspect_ratio = closure->aspect_ratio;

View File

@ -252,7 +252,6 @@ OSL_CLOSURE_STRUCT_BEGIN(MicrofacetHair, microfacet_hair)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, tilt, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, eta, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, distribution_type, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, cross_section, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, aspect_ratio, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, reflection, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, transmission, NULL)

View File

@ -43,7 +43,6 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
color AbsorptionCoefficient = color(0.245531, 0.52, 1.365),
normal Normal = Ng,
string parametrization = "Direct Coloring",
string cross_section = "Circular",
string distribution_type = "GGX",
float Offset = radians(2),
float Roughness = 0.3,
@ -104,12 +103,9 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
}
int distribution_type_enum = (distribution_type == "GGX") ? 0 : 1;
int cross_section_enum = 0;
normal major_axis = 0.0;
if (cross_section == "Elliptical") {
cross_section_enum = 1;
major_axis = 1.0;
if (AspectRatio != 1.0) {
getattribute("geom:N", major_axis);
}
@ -119,7 +115,6 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
Offset,
IOR,
distribution_type_enum,
cross_section_enum,
AspectRatio,
Reflection,
Transmission,

View File

@ -66,7 +66,6 @@ closure color microfacet_hair(normal N,
float tilt,
float eta,
int distribution_type,
int cross_section,
float aspect_ratio,
float reflection,
float transmission,

View File

@ -882,7 +882,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
uint4 data_node2 = read_node(kg, &offset);
uint4 data_node3 = read_node(kg, &offset);
uint4 data_node4 = read_node(kg, &offset);
uint4 data_node5 = read_node(kg, &offset);
Spectrum weight = sd->svm_closure_weight * mix_weight;
@ -891,13 +890,16 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
float tilt = stack_load_float_default(stack, offset_ofs, data_node.z);
float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
uint melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs, temp;
svm_unpack_node_uchar4(
data_node2.x, &temp, &melanin_ofs, &melanin_redness_ofs, &absorption_coefficient_ofs);
uint aspect_ratio_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
svm_unpack_node_uchar4(data_node2.x,
&aspect_ratio_ofs,
&melanin_ofs,
&melanin_redness_ofs,
&absorption_coefficient_ofs);
uint tint_ofs, random_ofs, random_color_ofs, cross_section;
uint tint_ofs, random_ofs, random_color_ofs, attr_normal;
svm_unpack_node_uchar4(
data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &cross_section);
data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &attr_normal);
const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node3.w);
float random = 0.0f;
@ -920,22 +922,30 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
ccl_private MicrofacetHairExtra *extra = (ccl_private MicrofacetHairExtra *)
closure_alloc_extra(sd, sizeof(MicrofacetHairExtra));
if (!extra)
if (!extra) {
break;
}
bsdf->extra = extra;
bsdf->extra->R = fmaxf(0.0f, R);
bsdf->extra->TT = fmaxf(0.0f, TT);
bsdf->extra->TRT = fmaxf(0.0f, TRT);
bsdf->aspect_ratio = stack_load_float_default(stack, aspect_ratio_ofs, data_node2.y);
if (bsdf->aspect_ratio != 1.0f) {
const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, attr_normal);
const float3 major_axis = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL);
/* Align ellipse major axis with the curve normal direction. */
bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, 0.0f);
}
/* Random factors range: [-randomization/2, +randomization/2]. */
float random_roughness = param2;
float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
float roughness = param1 * factor_random_roughness;
bsdf->cross_section = clamp(
cross_section, NODE_MICROFACET_HAIR_CIRCULAR, NODE_MICROFACET_HAIR_ELLIPTIC);
bsdf->distribution_type = clamp(
distribution_type, NODE_MICROFACET_HAIR_GGX, NODE_MICROFACET_HAIR_BECKMANN);
@ -990,19 +1000,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
}
if (cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
uint aspect_ratio_ofs, temp;
svm_unpack_node_uchar4(data_node5.x, &aspect_ratio_ofs, &temp, &temp, &temp);
bsdf->aspect_ratio = stack_load_float_default(stack, aspect_ratio_ofs, data_node5.y);
const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, data_node5.z);
const float3 major_axis = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL);
/* Align ellipse major axis with the curve normal direction. */
bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, 0.0f);
}
sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
}
break;

View File

@ -408,12 +408,6 @@ typedef enum NodeMicrofacetHairDistributionType {
NODE_MICROFACET_HAIR_DISTRIBUTION_TYPE_NUM,
} NodeMicrofacetHairDistributionType;
typedef enum NodeMicrofacetHairCrossSectionType {
NODE_MICROFACET_HAIR_CIRCULAR = 0,
NODE_MICROFACET_HAIR_ELLIPTIC = 1,
NODE_MICROFACET_HAIR_CROSS_SECTION_NUM,
} NodeMicrofacetHairCrossSectionType;
typedef enum NodeCombSepColorType {
NODE_COMBSEP_COLOR_RGB,
NODE_COMBSEP_COLOR_HSV,

View File

@ -3713,12 +3713,6 @@ NODE_DEFINE(MicrofacetHairBsdfNode)
SOCKET_ENUM(
distribution_type, "Distribution Type", distribution_type_enum, NODE_MICROFACET_HAIR_GGX);
/* Hair cross-section type specified as enum. */
static NodeEnum cross_section_enum;
cross_section_enum.insert("Circular", NODE_MICROFACET_HAIR_CIRCULAR);
cross_section_enum.insert("Elliptical", NODE_MICROFACET_HAIR_ELLIPTIC);
SOCKET_ENUM(cross_section, "Cross Section", cross_section_enum, NODE_MICROFACET_HAIR_CIRCULAR);
/* Initialize sockets to their default values. */
SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
@ -3760,7 +3754,7 @@ MicrofacetHairBsdfNode::MicrofacetHairBsdfNode() : BsdfBaseNode(get_node_type())
void MicrofacetHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
/* Make sure we have the normal for elliptical cross section tracking */
if (cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
if (aspect_ratio != 1.0f) {
attributes->add(ATTR_STD_VERTEX_NORMAL);
}
@ -3828,15 +3822,18 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler &compiler)
__float_as_uint(ior));
/* data node 2 */
compiler.add_node(
compiler.encode_uchar4(0, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs),
0,
__float_as_uint(melanin),
__float_as_uint(melanin_redness));
compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(aspect_ratio_in),
melanin_ofs,
melanin_redness_ofs,
absorption_coefficient_ofs),
__float_as_uint(aspect_ratio),
__float_as_uint(melanin),
__float_as_uint(melanin_redness));
/* data node 3 */
compiler.add_node(
compiler.encode_uchar4(tint_ofs, random_in_ofs, random_color_ofs, cross_section),
compiler.encode_uchar4(
tint_ofs, random_in_ofs, random_color_ofs, compiler.attribute(ATTR_STD_VERTEX_NORMAL)),
__float_as_uint(random),
__float_as_uint(random_color),
attr_random);
@ -3849,22 +3846,12 @@ void MicrofacetHairBsdfNode::compile(SVMCompiler &compiler)
__float_as_uint(R),
__float_as_uint(TT),
__float_as_uint(TRT));
/* data node 5 */
compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(aspect_ratio_in),
SVM_STACK_INVALID,
SVM_STACK_INVALID,
SVM_STACK_INVALID),
__float_as_uint(aspect_ratio),
compiler.attribute(ATTR_STD_VERTEX_NORMAL),
0);
}
/* Prepares the input data for the OSL shader. */
void MicrofacetHairBsdfNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "parametrization");
compiler.parameter(this, "cross_section");
compiler.parameter(this, "distribution_type");
compiler.add(this, "node_microfacet_hair_bsdf");
}

View File

@ -922,8 +922,6 @@ class MicrofacetHairBsdfNode : public BsdfBaseNode {
NODE_SOCKET_API(float, random)
/* Selected coloring parametrization. */
NODE_SOCKET_API(NodeMicrofacetHairParametrization, parametrization)
/* Selected cross-section type. */
NODE_SOCKET_API(NodeMicrofacetHairCrossSectionType, cross_section)
/* Selected microfacet distribution type. */
NODE_SOCKET_API(NodeMicrofacetHairDistributionType, distribution_type)
};

View File

@ -1692,10 +1692,6 @@ enum {
#define SHD_MICROFACET_HAIR_PIGMENT_CONCENTRATION 1
#define SHD_MICROFACET_HAIR_DIRECT_ABSORPTION 2
/* microfacet hair cross-section */
#define SHD_MICROFACET_HAIR_CIRCULAR 0
#define SHD_MICROFACET_HAIR_ELLIPTIC 1
/* microfacet hair distribution */
#define SHD_MICROFACET_HAIR_GGX 0
#define SHD_MICROFACET_HAIR_BECKMANN 1

View File

@ -4666,20 +4666,6 @@ static const EnumPropertyItem node_microfacet_hair_parametrization_items[] = {
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem node_microfacet_hair_cross_section_items[] = {
{SHD_MICROFACET_HAIR_CIRCULAR,
"HAIR_MICROFACET_CIRCULAR",
0,
"Circular",
"Microfacet-based hair scattering model with circular cross section"},
{SHD_MICROFACET_HAIR_ELLIPTIC,
"HAIR_MICROFACET_CIRCULAR_ELLIPTIC",
0,
"Elliptical",
"Microfacet-based hair scattering model with elliptical cross section fiber"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem node_microfacet_hair_distribution_items[] = {
{SHD_MICROFACET_HAIR_GGX,
"HAIR_MICROFACET_GGX",
@ -4687,7 +4673,7 @@ static const EnumPropertyItem node_microfacet_hair_distribution_items[] = {
"GGX",
"Microfacet-based hair scattering model with GGX distribution"},
{SHD_MICROFACET_HAIR_BECKMANN,
"HAIR_MICROFACET_ELLIPTIC_BECKMANN",
"HAIR_MICROFACET_BECKMANN",
0,
"Beckmann",
"Microfacet-based hair scattering model with Beckmann distribution"},
@ -6228,13 +6214,6 @@ static void def_hair_microfacet(StructRNA *srna)
RNA_def_property_enum_items(prop, node_microfacet_hair_parametrization_items);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "cross_section", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "cross_section");
RNA_def_property_ui_text(
prop, "Hair Cross Section Shape", "Select the hair's cross section shape");
RNA_def_property_enum_items(prop, node_microfacet_hair_cross_section_items);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "distribution_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "distribution");
RNA_def_property_ui_text(

View File

@ -43,7 +43,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.description(
"For elliptical hair cross-section, the aspect ratio is the ratio of the minor axis to "
"the major axis. Recommended values are 0.8~1 for Asian hair, 0.65~0.9 for Caucasian "
"hair, 0.5~0.65 for African hair");
"hair, 0.5~0.65 for African hair. Set this to 1 for circular cross-section");
b.add_input<decl::Float>(N_("Roughness"))
.default_value(0.3f)
.min(0.0f)
@ -107,7 +107,6 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_buts_microfacet_hair(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "parametrization", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "cross_section", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "distribution_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
@ -117,7 +116,6 @@ static void node_shader_init_hair_microfacet(bNodeTree * /*ntree*/, bNode *node)
NodeShaderHairMicrofacet *data = MEM_cnew<NodeShaderHairMicrofacet>(__func__);
data->parametrization = SHD_MICROFACET_HAIR_REFLECTANCE;
data->cross_section = SHD_MICROFACET_HAIR_CIRCULAR;
data->distribution = SHD_MICROFACET_HAIR_GGX;
node->storage = data;
@ -154,9 +152,6 @@ static void node_shader_update_hair_microfacet(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(
ntree, sock, parametrization == SHD_MICROFACET_HAIR_PIGMENT_CONCENTRATION);
}
else if (STREQ(sock->name, "Aspect Ratio")) {
nodeSetSocketAvailability(ntree, sock, data->cross_section == SHD_MICROFACET_HAIR_ELLIPTIC);
}
}
}