Code improvements + Mix node #30

Merged
Bogdan Nagirniak merged 18 commits from BogdanNagirniak/blender:matx-code-improvements into matx-export-material 2023-09-22 18:23:13 +02:00
Showing only changes of commit a901f806d7 - Show all commits

View File

@ -289,9 +289,11 @@ static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
using InputsType = std::map<std::string, NodeItem>;
/* NOTE: commented inputs aren't used for node creation. */ /* NOTE: commented inputs aren't used for node creation. */
auto bsdf_inputs = [&]() { auto bsdf_inputs = [&]() -> InputsType {
return std::map<std::string, NodeItem>{ return {
{"base_color", get_input_value("Base Color", NodeItem::Type::Color3)}, {"base_color", get_input_value("Base Color", NodeItem::Type::Color3)},
{"subsurface", get_input_value("Subsurface", NodeItem::Type::Float)}, {"subsurface", get_input_value("Subsurface", NodeItem::Type::Float)},
{"subsurface_scale", get_input_value("Subsurface Scale", NodeItem::Type::Float)}, {"subsurface_scale", get_input_value("Subsurface Scale", NodeItem::Type::Float)},
@ -320,265 +322,238 @@ NODE_SHADER_MATERIALX_BEGIN
}; };
}; };
auto edf_inputs = [&]() { auto edf_inputs = [&]() -> InputsType {
return std::map<std::string, NodeItem>{ return {
{"emission", get_input_value("Emission Strength", NodeItem::Type::Float)}, {"emission", get_input_value("Emission Strength", NodeItem::Type::Float)},
{"emission_color", get_input_value("Emission", NodeItem::Type::Color3)}}; {"emission_color", get_input_value("Emission", NodeItem::Type::Color3)},
};
}; };
NodeItem res = empty(); NodeItem res = empty();
if (to_type_ == NodeItem::Type::BSDF) {
auto in = bsdf_inputs();
NodeItem roughness = in["roughness"]; switch (to_type_) {
NodeItem anisotropy = in["anisotropic"]; case NodeItem::Type::BSDF: {
NodeItem rotation = in["anisotropic_rotation"]; auto in = bsdf_inputs();
NodeItem base_color = in["base_color"];
NodeItem specular = in["specular"];
NodeItem coat = in["coat"];
NodeItem ior = in["ior"];
NodeItem normal = in["normal"];
NodeItem tangent = in["tangent"];
NodeItem coat_normal = in["coat_normal"];
NodeItem n_main_tangent = empty(); NodeItem roughness = in["roughness"];
if (tangent && normal) { NodeItem anisotropy = in["anisotropic"];
NodeItem n_tangent_rotate = create_node( NodeItem rotation = in["anisotropic_rotation"];
"rotate3d", NodeItem base_color = in["base_color"];
NodeItem::Type::Vector3, NodeItem specular = in["specular"];
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", normal}}); NodeItem coat = in["coat"];
NodeItem ior = in["ior"];
NodeItem normal = in["normal"];
NodeItem tangent = in["tangent"];
NodeItem coat_normal = in["coat_normal"];
NodeItem n_tangent_rotate_normalize = create_node( NodeItem n_main_tangent = empty();
"normalize", NodeItem::Type::Vector3, {{"in", n_tangent_rotate}}); if (tangent && normal) {
NodeItem n_tangent_rotate = create_node(
"rotate3d",
NodeItem::Type::Vector3,
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", normal}});
n_main_tangent = anisotropy.if_else( NodeItem n_tangent_rotate_normalize = create_node(
NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent); "normalize", NodeItem::Type::Vector3, {{"in", n_tangent_rotate}});
}
NodeItem n_coat_roughness_vector = create_node( n_main_tangent = anisotropy.if_else(
"roughness_anisotropy", NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
NodeItem::Type::Vector2, }
{{"roughness", in["coat_roughness"]}, {"anisotropy", anisotropy}});
NodeItem n_coat_bsdf = create_node("dielectric_bsdf", NodeItem n_coat_roughness_vector = create_node(
NodeItem::Type::BSDF, "roughness_anisotropy",
{{"weight", coat}, NodeItem::Type::Vector2,
{"tint", in["coat_tint"]}, {{"roughness", in["coat_roughness"]}, {"anisotropy", anisotropy}});
{"ior", in["coat_ior"]},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_coat_roughness_vector},
{"normal", coat_normal}});
if (tangent && coat_normal) { NodeItem n_coat_bsdf = create_node("dielectric_bsdf",
NodeItem n_coat_tangent_rotate = create_node( NodeItem::Type::BSDF,
"rotate3d", {{"weight", coat},
NodeItem::Type::Vector3, {"tint", in["coat_tint"]},
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}}); {"ior", in["coat_ior"]},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_coat_roughness_vector},
{"normal", coat_normal}});
NodeItem n_coat_tangent_rotate_normalize = create_node( if (tangent && coat_normal) {
"normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}}); NodeItem n_coat_tangent_rotate = create_node(
"rotate3d",
NodeItem::Type::Vector3,
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}});
NodeItem n_coat_tangent = anisotropy.if_else( NodeItem n_coat_tangent_rotate_normalize = create_node(
NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent); "normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}});
n_coat_bsdf.set_input("tangent", n_coat_tangent); NodeItem n_coat_tangent = anisotropy.if_else(
} NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
NodeItem n_thin_film_bsdf = create_node( n_coat_bsdf.set_input("tangent", n_coat_tangent);
"thin_film_bsdf", NodeItem::Type::BSDF, {{"thickness", val(0.0f)}, {"ior", val(1.5f)}}); }
NodeItem n_artistic_ior = create_node( NodeItem n_thin_film_bsdf = create_node(
"artistic_ior", "thin_film_bsdf", NodeItem::Type::BSDF, {{"thickness", val(0.0f)}, {"ior", val(1.5f)}});
NodeItem::Type::Multioutput,
{{"reflectivity", base_color * val(1.0f)}, {"edge_color", base_color * specular}});
NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3); NodeItem n_artistic_ior = create_node(
NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3); "artistic_ior",
NodeItem::Type::Multioutput,
{{"reflectivity", base_color * val(1.0f)}, {"edge_color", base_color * specular}});
NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * in["coat_roughness"]; NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem n_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness, NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3);
val(1.0f));
// NodeItem n_coat_affected_roughness = create_node(
// "mix",
// NodeItem::Type::Float,
// {{"fg", val(1.0f)}, {"bg", roughness}, {"mix", n_coat_affect_roughness_multiply2}});
NodeItem n_main_roughness = create_node( NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * in["coat_roughness"];
"roughness_anisotropy", NodeItem n_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness,
NodeItem::Type::Vector2, val(1.0f));
{{"roughness", n_coat_affected_roughness}, {"anisotropy", anisotropy}});
NodeItem n_metal_bsdf = create_node("conductor_bsdf", NodeItem n_main_roughness = create_node(
NodeItem::Type::BSDF, "roughness_anisotropy",
{{"ior", n_ior_out}, NodeItem::Type::Vector2,
{"extinction", n_extinction_out}, {{"roughness", n_coat_affected_roughness}, {"anisotropy", anisotropy}});
{"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_specular_bsdf = create_node("dielectric_bsdf", NodeItem n_metal_bsdf = create_node("conductor_bsdf",
NodeItem::Type::BSDF,
{{"weight", specular},
{"tint", in["specular_tint"]},
{"ior", ior},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix(
(roughness + roughness).clamp(), val(1.0f));
// NodeItem n_coat_affected_transmission_roughness = create_node(
// "mix",
// NodeItem::Type::Float,
// {{"fg", val(1.0f)},
// {"bg", (roughness + roughness).clamp(0.0f, 1.0f)},
// {"mix", n_coat_affect_roughness_multiply2}});
NodeItem n_transmission_roughness = create_node(
"roughness_anisotropy",
NodeItem::Type::Vector2,
{{"roughness", n_coat_affected_transmission_roughness}, {"anisotropy", anisotropy}});
NodeItem n_transmission_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{{"tint", base_color},
{"ior", ior},
{"roughness", n_transmission_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_coat_gamma = coat.clamp(0.0f, 1.0f) * val(0.0f) + val(1.0f);
NodeItem n_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ n_coat_gamma;
NodeItem n_translucent_bsdf = create_node(
"translucent_bsdf",
NodeItem::Type::BSDF,
{{"color", n_coat_affected_subsurface_color}, {"normal", normal}});
NodeItem n_subsurface_bsdf = create_node(
"subsurface_bsdf",
NodeItem::Type::BSDF,
{{"color", n_coat_affected_subsurface_color},
{"radius", in["subsurface_radius"] * in["subsurface_scale"]},
{"anisotropy", in["subsurface_anisotropy"]},
{"normal", normal}});
NodeItem n_selected_subsurface_bsdf = n_subsurface_bsdf;
// NodeItem n_selected_subsurface_bsdf = create_node(
// "mix",
// NodeItem::Type::BSDF,
// {{"fg", n_translucent_bsdf}, {"bg", n_subsurface_bsdf}, {"mix", val(0.0f)}});
NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
NodeItem::Type::BSDF,
{{"weight", in["sheen"]},
{"color", in["sheen_tint"]},
{"roughness", in["sheen_roughness"]},
{"normal", normal}});
NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"color", base_color.max(val(0.0f)) ^ n_coat_gamma}, {{"ior", n_ior_out},
{"roughness", roughness}, {"extinction", n_extinction_out},
{"weight", val(1.0f)}, {"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_specular_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{{"weight", specular},
{"tint", in["specular_tint"]},
{"ior", ior},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix(
(roughness + roughness).clamp(), val(1.0f));
NodeItem n_transmission_roughness = create_node(
"roughness_anisotropy",
NodeItem::Type::Vector2,
{{"roughness", n_coat_affected_transmission_roughness}, {"anisotropy", anisotropy}});
NodeItem n_transmission_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{{"tint", base_color},
{"ior", ior},
{"roughness", n_transmission_roughness},
{"normal", normal},
{"tangent", n_main_tangent}});
NodeItem n_coat_gamma = coat.clamp(0.0f, 1.0f) * val(0.0f) + val(1.0f);
NodeItem n_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ n_coat_gamma;
NodeItem n_translucent_bsdf = create_node(
"translucent_bsdf",
NodeItem::Type::BSDF,
{{"color", n_coat_affected_subsurface_color}, {"normal", normal}});
NodeItem n_subsurface_bsdf = create_node(
"subsurface_bsdf",
NodeItem::Type::BSDF,
{{"color", n_coat_affected_subsurface_color},
{"radius", in["subsurface_radius"] * in["subsurface_scale"]},
{"anisotropy", in["subsurface_anisotropy"]},
{"normal", normal}});
NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
NodeItem::Type::BSDF,
{{"weight", in["sheen"]},
{"color", in["sheen_tint"]},
{"roughness", in["sheen_roughness"]},
{"normal", normal}}); {"normal", normal}});
NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_selected_subsurface_bsdf); NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
// NodeItem n_subsurface_mix = create_node( NodeItem::Type::BSDF,
// "mix", {{"color", base_color.max(val(0.0f)) ^ n_coat_gamma},
// NodeItem::Type::BSDF, {"roughness", roughness},
// {{"fg", n_selected_subsurface_bsdf}, {"bg", n_diffuse_bsdf}, {"mix", in["subsurface"]}}); {"weight", val(1.0f)},
{"normal", normal}});
NodeItem n_sheen_layer = create_node( NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_subsurface_bsdf);
"layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}});
NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf); NodeItem n_sheen_layer = create_node(
// NodeItem n_transmission_mix = create_node( "layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}});
// "mix",
// NodeItem::Type::BSDF,
// {{"fg", n_transmission_bsdf}, {"bg", n_sheen_layer}, {"mix", in["transmission"]}});
NodeItem n_specular_layer = create_node( NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf);
"layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}});
NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf); NodeItem n_specular_layer = create_node(
// NodeItem n_metalness_mix = create_node( "layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}});
// "mix",
// NodeItem::Type::BSDF,
// {{"fg", n_metal_bsdf}, {"bg", n_specular_layer}, {"mix", in["metallic"]}});
NodeItem n_thin_film_layer = create_node( NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf);
"layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
NodeItem n_opacity_luminance = create_node( NodeItem n_thin_film_layer = create_node(
"luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}}); "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)), NodeItem n_opacity_luminance = create_node(
in["coat_tint"]); "luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}});
// NodeItem n_coat_attenuation = create_node("mix",
// NodeItem::Type::Color3,
// {{"fg", in["coat_tint"]},
// {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
// {"mix", coat}});
res = create_node("layer", NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)),
NodeItem::Type::BSDF, in["coat_tint"]);
{{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}});
res = create_node("layer",
NodeItem::Type::BSDF,
{{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}});
break;
}
case NodeItem::Type::EDF: {
auto in = edf_inputs();
res = create_node(
"uniform_edf", NodeItem::Type::EDF, {{"color", in["emission_color"] * in["emission"]}});
break;
}
case NodeItem::Type::SurfaceShader: {
auto in = bsdf_inputs();
auto e_in = edf_inputs();
in.insert(e_in.begin(), e_in.end());
NodeItem roughness = in["roughness"];
NodeItem base_color = in["base_color"];
NodeItem anisotropic = in["anisotropic"];
NodeItem rotation = in["anisotropic_rotation"];
res = create_node("standard_surface",
NodeItem::Type::SurfaceShader,
{{"base", val(1.0f)},
{"base_color", base_color},
{"diffuse_roughness", roughness},
{"metalness", in["metallic"]},
{"specular", in["specular"]},
{"specular_color", in["specular_tint"]},
{"specular_roughness", roughness},
{"specular_IOR", in["ior"]},
{"specular_anisotropy", anisotropic},
{"specular_rotation", rotation},
{"transmission", in["transmission"]},
{"transmission_color", base_color},
{"transmission_extra_roughness", roughness},
{"subsurface", in["subsurface"]},
{"subsurface_color", base_color},
{"subsurface_radius", in["subsurface_radius"] * in["subsurface_scale"]},
{"subsurface_anisotropy", in["subsurface_anisotropy"]},
{"sheen", in["sheen"]},
{"sheen_color", in["sheen_tint"]},
{"sheen_roughness", in["sheen_roughness"]},
{"coat", in["coat"]},
{"coat_color", in["coat_tint"]},
{"coat_roughness", in["coat_roughness"]},
{"coat_IOR", in["coat_ior"]},
{"coat_anisotropy", anisotropic},
{"coat_rotation", rotation},
{"coat_normal", in["coat_normal"]},
{"emission", in["emission"]},
{"emission_color", in["emission_color"]},
{"normal", in["normal"]},
{"tangent", in["tangent"]}});
break;
}
default:
BLI_assert_unreachable();
} }
else if (to_type_ == NodeItem::Type::EDF) {
auto in = edf_inputs();
res = create_node(
"uniform_edf", NodeItem::Type::EDF, {{"color", in["emission_color"] * in["emission"]}});
}
else if (to_type_ == NodeItem::Type::SurfaceShader) {
auto in = bsdf_inputs();
auto e_in = edf_inputs();
in.insert(e_in.begin(), e_in.end());
NodeItem roughness = in["roughness"];
NodeItem base_color = in["base_color"];
NodeItem anisotropic = in["anisotropic"];
NodeItem rotation = in["anisotropic_rotation"];
res = create_node("standard_surface",
NodeItem::Type::SurfaceShader,
{{"base", val(1.0f)},
{"base_color", base_color},
{"diffuse_roughness", roughness},
{"metalness", in["metallic"]},
{"specular", in["specular"]},
{"specular_color", in["specular_tint"]},
{"specular_roughness", roughness},
{"specular_IOR", in["ior"]},
{"specular_anisotropy", anisotropic},
{"specular_rotation", rotation},
{"transmission", in["transmission"]},
{"transmission_color", base_color},
{"transmission_extra_roughness", roughness},
{"subsurface", in["subsurface"]},
{"subsurface_color", base_color},
{"subsurface_radius", in["subsurface_radius"] * in["subsurface_scale"]},
{"subsurface_anisotropy", in["subsurface_anisotropy"]},
{"sheen", in["sheen"]},
{"sheen_color", in["sheen_tint"]},
{"sheen_roughness", in["sheen_roughness"]},
{"coat", in["coat"]},
{"coat_color", in["coat_tint"]},
{"coat_roughness", in["coat_roughness"]},
{"coat_IOR", in["coat_ior"]},
{"coat_anisotropy", anisotropic},
{"coat_rotation", rotation},
{"coat_normal", in["coat_normal"]},
{"emission", in["emission"]},
{"emission_color", in["emission_color"]},
{"normal", in["normal"]},
{"tangent", in["tangent"]}});
}
else {
BLI_assert_unreachable();
}
return res; return res;
} }
#endif #endif