MaterialX: split standard_surface into basic nodes #26

Merged
Bogdan Nagirniak merged 11 commits from matx-principlebsdf-split into matx-export-material 2023-09-21 10:58:14 +02:00
Showing only changes of commit 7a2d2ae8e6 - Show all commits

View File

@ -289,99 +289,60 @@ static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
/* NOTE: commented inputs aren't used for node creation. */
auto bsdf_inputs = [&]() { auto bsdf_inputs = [&]() {
NodeItem base_color = get_input_value("Base Color", NodeItem::Type::Color3);
NodeItem subsurface = get_input_value("Subsurface", NodeItem::Type::Float);
NodeItem subsurface_radius = get_input_value("Subsurface Radius", NodeItem::Type::Vector3);
NodeItem subsurface_scale = get_input_value("Subsurface Scale", NodeItem::Type::Float);
NodeItem metallic = get_input_value("Metallic", NodeItem::Type::Float);
NodeItem specular = get_input_value("Specular", NodeItem::Type::Float);
// NodeItem specular_tint = get_input_value("Specular Tint");
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
/* TODO: use Specular Tint input */
NodeItem anisotropic = get_input_value("Anisotropic", NodeItem::Type::Float);
NodeItem anisotropic_rotation = get_input_value("Anisotropic Rotation", NodeItem::Type::Float);
// anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0)
NodeItem sheen = get_input_value("Sheen", NodeItem::Type::Float);
// sheen_tint = get_input_value("Sheen Tint");
NodeItem coat = get_input_value("Coat", NodeItem::Type::Float);
NodeItem coat_roughness = get_input_value("Coat Roughness", NodeItem::Type::Float);
NodeItem ior = get_input_value("IOR", NodeItem::Type::Float);
NodeItem transmission = get_input_value("Transmission", NodeItem::Type::Float);
NodeItem alpha = get_input_value("Alpha", NodeItem::Type::Float);
// transparency = 1.0 - alpha
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem coat_normal = get_input_link("Coat Normal", NodeItem::Type::Vector3);
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
subsurface_radius = subsurface_radius * subsurface_scale;
return std::map<std::string, NodeItem>{ return std::map<std::string, NodeItem>{
{"base", val(1.0f)}, {"base_color", get_input_value("Base Color", NodeItem::Type::Color3)},
{"base_color", base_color}, {"subsurface", get_input_value("Subsurface", NodeItem::Type::Float)},
{"diffuse_roughness", roughness}, {"subsurface_scale", get_input_value("Subsurface Scale", NodeItem::Type::Float)},
{"normal", normal}, {"subsurface_radius", get_input_value("Subsurface Radius", NodeItem::Type::Vector3)},
{"tangent", tangent}, //{"subsurface_ior", get_input_value("Subsurface IOR", NodeItem::Type::Vector3)},
{"metalness", metallic}, {"subsurface_anisotropy", get_input_value("Subsurface Anisotropy", NodeItem::Type::Float)},
{"specular", specular}, {"metallic", get_input_value("Metallic", NodeItem::Type::Float)},
{"specular_color", base_color}, {"specular", get_input_value("Specular", NodeItem::Type::Float)},
{"specular_roughness", roughness}, {"specular_tint", get_input_value("Specular Tint", NodeItem::Type::Color3)},
{"specular_IOR", ior}, {"roughness", get_input_value("Roughness", NodeItem::Type::Float)},
{"specular_anisotropy", anisotropic}, {"anisotropic", get_input_value("Anisotropic", NodeItem::Type::Float)},
{"specular_rotation", anisotropic_rotation}, {"anisotropic_rotation", get_input_value("Anisotropic Rotation", NodeItem::Type::Float)},
{"transmission", transmission}, {"sheen", get_input_value("Sheen", NodeItem::Type::Float)},
{"transmission_color", base_color}, {"sheen_roughness", get_input_value("Sheen Roughness", NodeItem::Type::Float)},
{"transmission_extra_roughness", roughness}, {"sheen_tint", get_input_value("Sheen Tint", NodeItem::Type::Color3)},
{"subsurface", subsurface}, {"coat", get_input_value("Coat", NodeItem::Type::Float)},
{"subsurface_color", base_color}, {"coat_roughness", get_input_value("Coat Roughness", NodeItem::Type::Float)},
{"subsurface_radius", subsurface_radius}, {"coat_ior", get_input_value("Coat IOR", NodeItem::Type::Float)},
{"subsurface_anisotropy", anisotropic}, {"coat_tint", get_input_value("Coat Tint", NodeItem::Type::Color3)},
{"sheen", sheen}, {"ior", get_input_value("IOR", NodeItem::Type::Float)},
{"sheen_color", base_color}, {"transmission", get_input_value("Transmission", NodeItem::Type::Float)},
{"sheen_roughness", roughness}, //{"alpha", get_input_value("Alpha", NodeItem::Type::Float)},
{"coat", coat}, {"normal", get_input_link("Normal", NodeItem::Type::Vector3)},
{"coat_color", base_color}, {"coat_normal", get_input_link("Coat Normal", NodeItem::Type::Vector3)},
{"coat_roughness", coat_roughness}, {"tangent", get_input_link("Tangent", NodeItem::Type::Vector3)},
{"coat_IOR", ior},
{"coat_anisotropy", anisotropic},
{"coat_rotation", anisotropic_rotation},
{"coat_normal", coat_normal},
}; };
}; };
auto edf_inputs = [&]() { auto edf_inputs = [&]() {
NodeItem emission = get_input_value("Emission", NodeItem::Type::Color3); return std::map<std::string, NodeItem>{
NodeItem emission_strength = 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)}};
return std::map<std::string, NodeItem>{{"emission", emission_strength},
{"emission_color", emission}};
}; };
NodeItem res = empty(); NodeItem res = empty();
if (to_type_ == NodeItem::Type::BSDF) { if (to_type_ == NodeItem::Type::BSDF) {
auto inputs = bsdf_inputs(); auto inputs = bsdf_inputs();
NodeItem roughness = inputs.find("diffuse_roughness")->second; NodeItem roughness = inputs.find("roughness")->second;
NodeItem anisotropy = inputs.find("specular_anisotropy")->second; NodeItem anisotropy = inputs.find("anisotropic")->second;
NodeItem rotation = inputs.find("specular_rotation")->second; NodeItem rotation = inputs.find("anisotropic_rotation")->second;
NodeItem base_color = inputs.find("base_color")->second; NodeItem base_color = inputs.find("base_color")->second;
NodeItem specular = inputs.find("specular")->second; NodeItem specular = inputs.find("specular")->second;
NodeItem coat = inputs.find("coat")->second; NodeItem coat = inputs.find("coat")->second;
DagerD marked this conversation as resolved Outdated

Rewrite create_node() with inputs parameter inside function.

Rewrite `create_node()` with `inputs` parameter inside function.
NodeItem ior = inputs.find("specular_IOR")->second; NodeItem ior = inputs.find("ior")->second;
NodeItem normal = inputs.find("normal")->second; NodeItem normal = inputs.find("normal")->second;
NodeItem tangent = inputs.find("tangent")->second; NodeItem tangent = inputs.find("tangent")->second;
NodeItem coat_normal = inputs.find("coat_normal")->second;
NodeItem n_main_tangent = empty(); NodeItem n_main_tangent = empty();
if (tangent) { if (tangent && normal) {
NodeItem n_tangent_rotate = create_node( NodeItem n_tangent_rotate = create_node(
"rotate3d", "rotate3d",
NodeItem::Type::Vector3, NodeItem::Type::Vector3,
@ -397,22 +358,22 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_coat_roughness_vector = create_node( NodeItem n_coat_roughness_vector = create_node(
"roughness_anisotropy", "roughness_anisotropy",
NodeItem::Type::Vector2, NodeItem::Type::Vector2,
{{"roughness", roughness}, {"anisotropy", anisotropy}}); {{"roughness", inputs.find("coat_roughness")->second}, {"anisotropy", anisotropy}});
NodeItem n_coat_bsdf = create_node("dielectric_bsdf", NodeItem n_coat_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"weight", coat}, {{"weight", coat},
{"tint", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}, {"tint", inputs.find("coat_tint")->second},
{"ior", ior}, {"ior", inputs.find("coat_ior")->second},
{"scatter_mode", val(std::string("R"))}, {"scatter_mode", val(std::string("R"))},
{"roughness", n_coat_roughness_vector}, {"roughness", n_coat_roughness_vector},
{"normal", normal}}); {"normal", coat_normal}});
if (tangent) { if (tangent && coat_normal) {
NodeItem n_coat_tangent_rotate = create_node( NodeItem n_coat_tangent_rotate = create_node(
"rotate3d", "rotate3d",
NodeItem::Type::Vector3, NodeItem::Type::Vector3,
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", normal}}); {{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}});
NodeItem n_coat_tangent_rotate_normalize = create_node( NodeItem n_coat_tangent_rotate_normalize = create_node(
"normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}}); "normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}});
@ -434,7 +395,8 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3); NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3); NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3);
NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * roughness; NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) *
inputs.find("coat_roughness")->second;
NodeItem n_coat_affected_roughness = create_node( NodeItem n_coat_affected_roughness = create_node(
"mix", "mix",
NodeItem::Type::Float, NodeItem::Type::Float,
@ -456,7 +418,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_specular_bsdf = create_node("dielectric_bsdf", NodeItem n_specular_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"weight", specular}, {{"weight", specular},
{"tint", base_color}, {"tint", inputs.find("specular_tint")->second},
{"ior", ior}, {"ior", ior},
{"scatter_mode", val(std::string("R"))}, {"scatter_mode", val(std::string("R"))},
{"roughness", n_main_roughness}, {"roughness", n_main_roughness},
@ -490,12 +452,14 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"color", n_coat_affected_subsurface_color}, {"normal", normal}}); {{"color", n_coat_affected_subsurface_color}, {"normal", normal}});
NodeItem n_subsurface_bsdf = create_node("subsurface_bsdf", NodeItem n_subsurface_bsdf = create_node(
NodeItem::Type::BSDF, "subsurface_bsdf",
{{"color", n_coat_affected_subsurface_color}, NodeItem::Type::BSDF,
{"radius", inputs.find("subsurface_radius")->second}, {{"color", n_coat_affected_subsurface_color},
{"anisotropy", anisotropy}, {"radius",
{"normal", normal}}); inputs.find("subsurface_radius")->second * inputs.find("subsurface_scale")->second},
{"anisotropy", inputs.find("subsurface_anisotropy")->second},
{"normal", normal}});
NodeItem n_selected_subsurface_bsdf = create_node( NodeItem n_selected_subsurface_bsdf = create_node(
"mix", "mix",
@ -505,8 +469,8 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_sheen_bsdf = create_node("sheen_bsdf", NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"weight", inputs.find("sheen")->second}, {{"weight", inputs.find("sheen")->second},
{"color", base_color}, {"color", inputs.find("sheen_tint")->second},
{"roughness", roughness}, {"roughness", inputs.find("sheen_roughness")->second},
{"normal", normal}}); {"normal", normal}});
NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf", NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
@ -538,7 +502,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
{{"fg", n_metal_bsdf}, {{"fg", n_metal_bsdf},
{"bg", n_specular_layer}, {"bg", n_specular_layer},
{"mix", inputs.find("metalness")->second}}); {"mix", inputs.find("metallic")->second}});
NodeItem n_thin_film_layer = create_node( NodeItem n_thin_film_layer = create_node(
"layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}}); "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
@ -546,16 +510,15 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_opacity_luminance = create_node( NodeItem n_opacity_luminance = create_node(
"luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}}); "luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}});
NodeItem n_coat_attenuation = create_node( NodeItem n_coat_attenuation = create_node("mix",
"mix", NodeItem::Type::Color3,
NodeItem::Type::Color3, {{"fg", inputs.find("coat_tint")->second},
{{"fg", base_color}, {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}, {"mix", coat}}); {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
{"mix", coat}});
res = create_node("layer", res = create_node("layer",
NodeItem::Type::BSDF, NodeItem::Type::BSDF,
DagerD marked this conversation as resolved Outdated

This node is created in MaterialOutput.
Should be:

if (to_type_ == NodeItem::Type::BSDF) {
<calculate and return only BSDF part>
....
return n_coat_layer; // probably n_coat_layer * n_opacity_luminance
}
else if (to_type_ == NodeItem::Type::EDF) {
<calculate and return only EDF part>
...
return n_emission_edf; // probably n_emission_edf * n_opacity_luminance
}
else if (to_type_ == NodeItem::Type::SurfaceShader) {
<previous implementation>
}
This node is created in MaterialOutput. Should be: ``` if (to_type_ == NodeItem::Type::BSDF) { <calculate and return only BSDF part> .... return n_coat_layer; // probably n_coat_layer * n_opacity_luminance } else if (to_type_ == NodeItem::Type::EDF) { <calculate and return only EDF part> ... return n_emission_edf; // probably n_emission_edf * n_opacity_luminance } else if (to_type_ == NodeItem::Type::SurfaceShader) { <previous implementation> } ```
{{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}}); {{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}});
return res;
} }
else if (to_type_ == NodeItem::Type::EDF) { else if (to_type_ == NodeItem::Type::EDF) {
auto inputs = edf_inputs(); auto inputs = edf_inputs();
@ -569,45 +532,49 @@ NODE_SHADER_MATERIALX_BEGIN
auto b_inputs = bsdf_inputs(); auto b_inputs = bsdf_inputs();
auto e_inputs = edf_inputs(); auto e_inputs = edf_inputs();
NodeItem roughness = b_inputs.find("diffuse_roughness")->second; NodeItem roughness = b_inputs.find("roughness")->second;
NodeItem base_color = b_inputs.find("base_color")->second; NodeItem base_color = b_inputs.find("base_color")->second;
NodeItem anisotropic = b_inputs.find("specular_anisotropy")->second; NodeItem anisotropic = b_inputs.find("anisotropic")->second;
NodeItem ior = b_inputs.find("specular_IOR")->second; NodeItem rotation = b_inputs.find("anisotropic_rotation")->second;
NodeItem rotation = b_inputs.find("specular_rotation")->second;
res = create_node("standard_surface", res = create_node(
NodeItem::Type::SurfaceShader, "standard_surface",
{{"base", val(1.0f)}, NodeItem::Type::SurfaceShader,
{"base_color", base_color}, {{"base", val(1.0f)},
{"diffuse_roughness", roughness}, {"base_color", base_color},
{"metalness", b_inputs.find("metalness")->second}, {"diffuse_roughness", roughness},
{"specular", b_inputs.find("specular")->second}, {"metalness", b_inputs.find("metallic")->second},
{"specular_color", base_color}, {"specular", b_inputs.find("specular")->second},
{"specular_roughness", roughness}, {"specular_color", b_inputs.find("specular_tint")->second},
{"specular_IOR", ior}, {"specular_roughness", roughness},
{"specular_anisotropy", anisotropic}, {"specular_IOR", b_inputs.find("ior")->second},
{"specular_rotation", rotation}, {"specular_anisotropy", anisotropic},
{"transmission", b_inputs.find("transmission")->second}, {"specular_rotation", rotation},
{"transmission_color", base_color}, {"transmission", b_inputs.find("transmission")->second},
{"transmission_extra_roughness", roughness}, {"transmission_color", base_color},
{"subsurface", b_inputs.find("subsurface")->second}, {"transmission_extra_roughness", roughness},
{"subsurface_color", base_color}, {"subsurface", b_inputs.find("subsurface")->second},
{"subsurface_radius", b_inputs.find("subsurface_radius")->second}, {"subsurface_color", base_color},
{"subsurface_anisotropy", anisotropic}, {"subsurface_radius",
{"sheen", b_inputs.find("sheen")->second}, b_inputs.find("subsurface_radius")->second * b_inputs.find("subsurface_scale")->second},
{"sheen_color", base_color}, {"subsurface_anisotropy", b_inputs.find("subsurface_anisotropy")->second},
{"sheen_roughness", roughness}, {"sheen", b_inputs.find("sheen")->second},
{"coat", b_inputs.find("coat")->second}, {"sheen_color", b_inputs.find("sheen_tint")->second},
{"coat_color", base_color}, {"sheen_roughness", b_inputs.find("sheen_roughness")->second},
{"coat_roughness", b_inputs.find("coat_roughness")->second}, {"coat", b_inputs.find("coat")->second},
{"coat_IOR", ior}, {"coat_color", b_inputs.find("coat_tint")->second},
{"coat_anisotropy", anisotropic}, {"coat_roughness", b_inputs.find("coat_roughness")->second},
{"coat_rotation", rotation}, {"coat_IOR", b_inputs.find("coat_ior")->second},
{"coat_normal", b_inputs.find("coat_normal")->second}, {"coat_anisotropy", anisotropic},
{"emission", e_inputs.find("emission")->second}, {"coat_rotation", rotation},
{"emission_color", e_inputs.find("emission_color")->second}, {"coat_normal", b_inputs.find("coat_normal")->second},
{"normal", b_inputs.find("normal")->second}, {"emission", e_inputs.find("emission")->second},
{"tangent", b_inputs.find("tangent")->second}}); {"emission_color", e_inputs.find("emission_color")->second},
{"normal", b_inputs.find("normal")->second},
{"tangent", b_inputs.find("tangent")->second}});
}
else {
BLI_assert_unreachable();
} }
return res; return res;