From 3808bcb2124301884334621a3be402f6c68a00d2 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 18 Aug 2023 11:04:45 +0300 Subject: [PATCH 01/11] Export to file. Apply to object. --- source/blender/io/usd/CMakeLists.txt | 5 +++ source/blender/io/usd/hydra/material.cc | 34 +++++++++++++------ .../nodes/shader/materialx/material.cc | 13 +++++-- .../blender/nodes/shader/materialx/material.h | 2 ++ 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 5880da289a19..21f70027c97e 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -205,6 +205,11 @@ if(WITH_OPENVDB) ) endif() +if(WITH_MATERIALX) + list(APPEND LIB MaterialXCore) + list(APPEND LIB MaterialXFormat) +endif() + blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # RNA_prototypes.h diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index fa2c698146b5..0b7c31c50b23 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "MEM_guardedalloc.h" #include "BKE_lib_id.h" @@ -30,6 +33,7 @@ #include "intern/usd_exporter_context.h" #include "intern/usd_writer_material.h" +#include "shader/materialx/material.h" namespace blender::io::hydra { @@ -68,24 +72,32 @@ void MaterialData::init() image_cache_file_path()}; /* Create USD material. */ - pxr::UsdShadeMaterial usd_material = usd::create_usd_material( - export_context, material_path, (Material *)id, "st"); + //pxr::UsdShadeMaterial usd_material = usd::create_usd_material(export_context, material_path, (Material *)id, "st"); /* Convert USD material to Hydra material network map, adapted for render delegate. */ - const pxr::HdRenderDelegate *render_delegate = - scene_delegate_->GetRenderIndex().GetRenderDelegate(); + const pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate(); const pxr::TfTokenVector contextVector = render_delegate->GetMaterialRenderContexts(); pxr::TfTokenVector shaderSourceTypes = render_delegate->GetShaderSourceTypes(); pxr::HdMaterialNetworkMap network_map; - if (pxr::UsdShadeShader surface = usd_material.ComputeSurfaceSource(contextVector)) { - pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(surface.GetPrim(), - pxr::HdMaterialTerminalTokens->surface, - shaderSourceTypes, - contextVector, - &network_map, - time); + MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx((Material *)id); + pxr::UsdMtlxRead(doc, stage); + + if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) { + if (pxr::UsdPrimSiblingRange children = materials.GetChildren()) { + if (auto usd_material = pxr::UsdShadeMaterial(*children.begin())) { + if (pxr::UsdShadeShader mtlx_surface = usd_material.ComputeSurfaceSource(contextVector)) + { + UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(), + pxr::HdMaterialTerminalTokens->surface, + shaderSourceTypes, + contextVector, + &network_map, + time); + } + } + } } material_network_map_ = pxr::VtValue(network_map); diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 9f8c497743ba..450dd1173931 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -5,6 +5,7 @@ #include "material.h" #include +#include namespace blender::nodes::materialx { @@ -17,20 +18,28 @@ static void create_standard_surface(MaterialX::DocumentPtr doc, Material *materi standard_surface->addInput("base", "float")->setValue(1.0); standard_surface->addInput("base_color", "color3") - ->setValue(MaterialX::Color3(material->r, material->g, material->a)); + ->setValue(MaterialX::Color3(material->r, material->g, material->b)); surfacematerial->addInput(standard_surface->getType(), standard_surface->getType()) ->setNodeName(standard_surface->getName()); } +static void export_nodegraph(MaterialX::DocumentPtr doc, Material *material) +{ + ; +} + MaterialX::DocumentPtr export_to_materialx(Material* material) { MaterialX::DocumentPtr doc = MaterialX::createDocument(); if (material->use_nodes) { - ; + export_nodegraph(doc, material); } else { create_standard_surface(doc, material); } + MaterialX::writeToXmlFile( + doc, + MaterialX::FilePath("c:/Users/Vasyl_Pidhirskyi/Work/AMD/blender-git/tmp/material.mtlx")); return doc; } diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index d0706153b679..7297f02897bb 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -11,6 +11,8 @@ namespace blender::nodes::materialx { MaterialX::DocumentPtr export_to_materialx(Material *material); +static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material); +static void export_nodegraph(MaterialX::DocumentPtr doc, Material *material); } // namespace blender::materialx -- 2.30.2 From e671a68d49abf30a7051e1a6f1fad7d8be4ee015 Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Fri, 18 Aug 2023 11:36:03 +0300 Subject: [PATCH 02/11] Moved dependency MaterialXFormat to source/blender/nodes/shader/CMakeLists.txt. --- source/blender/io/usd/CMakeLists.txt | 1 - source/blender/nodes/shader/CMakeLists.txt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 21f70027c97e..43bf9a5723ec 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -207,7 +207,6 @@ endif() if(WITH_MATERIALX) list(APPEND LIB MaterialXCore) - list(APPEND LIB MaterialXFormat) endif() blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index c05bb53c9e17..8819dba1743b 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -136,6 +136,7 @@ set(LIB if(WITH_MATERIALX) list(APPEND LIB MaterialXCore) + list(APPEND LIB MaterialXFormat) list(APPEND SRC materialx/material.cc -- 2.30.2 From 497b02df4bf2f9c52c54ddd1675944cd7e084a8f Mon Sep 17 00:00:00 2001 From: Vasyl-Pidhirskyi Date: Tue, 22 Aug 2023 16:13:40 +0300 Subject: [PATCH 03/11] Initial implementation of parsing system. --- source/blender/io/usd/hydra/material.cc | 2 +- source/blender/nodes/shader/CMakeLists.txt | 8 ++ .../nodes/shader/materialx/material.cc | 23 +-- .../blender/nodes/shader/materialx/material.h | 8 +- .../nodes/shader/materialx/nodes/image.cc | 41 ++++++ .../nodes/shader/materialx/nodes/image.h | 24 ++++ .../shader/materialx/nodes/material_output.cc | 38 +++++ .../shader/materialx/nodes/material_output.h | 20 +++ .../nodes/shader/materialx/nodes/node.cc | 71 +++++++++ .../nodes/shader/materialx/nodes/node.h | 38 +++++ .../shader/materialx/nodes/principled_bsdf.cc | 136 ++++++++++++++++++ .../shader/materialx/nodes/principled_bsdf.h | 20 +++ 12 files changed, 416 insertions(+), 13 deletions(-) create mode 100644 source/blender/nodes/shader/materialx/nodes/image.cc create mode 100644 source/blender/nodes/shader/materialx/nodes/image.h create mode 100644 source/blender/nodes/shader/materialx/nodes/material_output.cc create mode 100644 source/blender/nodes/shader/materialx/nodes/material_output.h create mode 100644 source/blender/nodes/shader/materialx/nodes/node.cc create mode 100644 source/blender/nodes/shader/materialx/nodes/node.h create mode 100644 source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc create mode 100644 source/blender/nodes/shader/materialx/nodes/principled_bsdf.h diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index 0b7c31c50b23..75a1c2162bf3 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -81,7 +81,7 @@ void MaterialData::init() pxr::HdMaterialNetworkMap network_map; - MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx((Material *)id); + MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(scene_delegate_->depsgraph, (Material *)id); pxr::UsdMtlxRead(doc, stage); if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) { diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index 8819dba1743b..9c1d3a8c7ace 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -139,8 +139,16 @@ if(WITH_MATERIALX) list(APPEND LIB MaterialXFormat) list(APPEND SRC materialx/material.cc + materialx/nodes/node.cc + materialx/nodes/material_output.cc + materialx/nodes/principled_bsdf.cc + materialx/nodes/image.cc materialx/material.h + materialx/nodes/node.h + materialx/nodes/material_output.h + materialx/nodes/principled_bsdf.h + materialx/nodes/image.h ) endif() diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 450dd1173931..1690a6950dd8 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -3,12 +3,24 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "material.h" +#include "nodes/material_output.h" #include #include +#include "NOD_shader.h" + namespace blender::nodes::materialx { +static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, Material *material) +{ + material->nodetree->ensure_topology_cache(); + + bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); + MaterialXMaterialOutputNode material_node(doc, depsgraph, material, output_node); + material_node.convert(); +} + static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material) { MaterialX::NodePtr surfacematerial = doc->addNode( @@ -24,15 +36,11 @@ static void create_standard_surface(MaterialX::DocumentPtr doc, Material *materi ->setNodeName(standard_surface->getName()); } -static void export_nodegraph(MaterialX::DocumentPtr doc, Material *material) +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material) { - ; -} - -MaterialX::DocumentPtr export_to_materialx(Material* material) { MaterialX::DocumentPtr doc = MaterialX::createDocument(); if (material->use_nodes) { - export_nodegraph(doc, material); + export_nodegraph(doc, depsgraph, material); } else { create_standard_surface(doc, material); @@ -43,5 +51,4 @@ MaterialX::DocumentPtr export_to_materialx(Material* material) { return doc; } -} // namespace blender::materialx - +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index 7297f02897bb..799450a8fda7 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -6,13 +6,13 @@ #include +#include "DEG_depsgraph.h" #include "DNA_material_types.h" namespace blender::nodes::materialx { -MaterialX::DocumentPtr export_to_materialx(Material *material); +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material); static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material); -static void export_nodegraph(MaterialX::DocumentPtr doc, Material *material); - -} // namespace blender::materialx +static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, Material *material); +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/image.cc b/source/blender/nodes/shader/materialx/nodes/image.cc new file mode 100644 index 000000000000..e782bdd337fc --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/image.cc @@ -0,0 +1,41 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "node.h" +#include "image.h" + +#include "DEG_depsgraph_query.h" + +namespace blender::nodes::materialx { + +const MaterialX::Color3 MaterialXTexImageNode::texture_error_color_{1.0, 0.0, 1.0}; + +MaterialXTexImageNode::MaterialXTexImageNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : MaterialXNode(doc, depsgraph, material, node) +{ + matx_node = doc->addNode("image", MaterialX::createValidName(node->name), "color3"); +} + +MaterialX::NodePtr MaterialXTexImageNode::convert() +{ + const Image *image = (Image *)node->id; + const NodeTexImage *tex = static_cast(node->storage); + Scene *scene = DEG_get_input_scene(depsgraph); + Main *bmain = DEG_get_bmain(depsgraph); + std::string image_path = "C:/Users/Vasyl_Pidhirskyi/Desktop/Untitled.png"; +#ifdef WITH_HYDRA + image_path = cache_or_get_image_file(bmain, scene, image, &tex->iuser); +#endif + MaterialX::NodePtr uv_node = doc->addNode("texcoord", MaterialX::EMPTY_STRING, "vector2"); + + matx_node->addInput("file", "filename")->setValue(image_path); + matx_node->addInput("texcoord", "vector2")->setNodeName(uv_node->getName()); + + return matx_node; +} + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/image.h b/source/blender/nodes/shader/materialx/nodes/image.h new file mode 100644 index 000000000000..fc83f8b3e4a7 --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/image.h @@ -0,0 +1,24 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "node.h" + +namespace blender::nodes::materialx { + +class MaterialXTexImageNode : public MaterialXNode { + protected: + /* Following Cycles color for wrong Texture nodes. */ + static const MaterialX::Color3 texture_error_color_; + + public: + MaterialXTexImageNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + MaterialX::NodePtr convert() override; +}; + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/material_output.cc b/source/blender/nodes/shader/materialx/nodes/material_output.cc new file mode 100644 index 000000000000..1128b7fd7127 --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/material_output.cc @@ -0,0 +1,38 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "material_output.h" +#include "principled_bsdf.h" + +namespace blender::nodes::materialx { + +MaterialXMaterialOutputNode::MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : MaterialXNode(doc, depsgraph, material, node) +{ + matx_node = doc->addNode("surfacematerial", MaterialX::createValidName(node->name), "material"); +} + +MaterialX::NodePtr MaterialXMaterialOutputNode::convert() +{ + //LISTBASE_FOREACH (const bNodeSocket *, sock, &node->inputs) { + // if (!sock->link) { + // continue; + // } + // if (STREQ(sock->name, "Surface")) { + // const bNode *inode = sock->link->fromnode; + // MaterialXPrincipledBSDFNode surface_node(doc, material, inode); + // surface_node.convert(); + // matx_node->addInput("surfaceshader", "surfaceshader")->setNodeName(inode->name); + // } + //} + const char *matx_socket = "surfaceshader"; + const bNodeSocket sock = node->input_by_identifier("Surface"); + get_input_link_node(&sock, matx_node, matx_socket); + return matx_node; +} + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/material_output.h b/source/blender/nodes/shader/materialx/nodes/material_output.h new file mode 100644 index 000000000000..8ffda3d00d94 --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/material_output.h @@ -0,0 +1,20 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "node.h" + +namespace blender::nodes::materialx { + +class MaterialXMaterialOutputNode : public MaterialXNode { + public: + MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + MaterialX::NodePtr convert() override; +}; + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node.cc b/source/blender/nodes/shader/materialx/nodes/node.cc new file mode 100644 index 000000000000..54d3838f3f3f --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/node.cc @@ -0,0 +1,71 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "node.h" +#include "principled_bsdf.h" +#include "image.h" +#include + +namespace blender::nodes::materialx { + +MaterialXNode::MaterialXNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : depsgraph(depsgraph), material(material), node(node), doc(doc) +{ +} + +void MaterialXNode::get_input_link_node(const bNodeSocket *sock, MaterialX::NodePtr matx_node_to, const char *input) +{ + const bNode *inode = sock->link->fromnode; + if (inode->type == SH_NODE_BSDF_PRINCIPLED) { + MaterialXPrincipledBSDFNode maxt_node(doc, depsgraph, material, inode); + maxt_node.convert(); + } + else if (inode->type == SH_NODE_TEX_IMAGE) { + MaterialXTexImageNode maxt_node(doc, depsgraph, material, inode); + maxt_node.convert(); + } + else { + return; + } + const bNodeSocket *sock_from = sock->link->fromsock; + matx_node_to->addInput(input, get_mx_type(sock))->setNodeName(MaterialX::createValidName(inode->name)); +}; + +std::string MaterialXNode::get_mx_type(const bNodeSocket *sock) +{ + std::string mx_sock_type; + switch (sock->type) { + case (SOCK_FLOAT): { + mx_sock_type = "float"; + break; + } + case (SOCK_VECTOR): { + mx_sock_type = "vector3"; + break; + } + case (SOCK_RGBA): { + mx_sock_type = "color3"; + break; + } + case (SOCK_BOOLEAN): { + mx_sock_type = "boolean"; + break; + } + case (SOCK_INT): { + mx_sock_type = "integer"; + break; + } + case (SOCK_SHADER): { + mx_sock_type = "surfaceshader"; + break; + } + } + return mx_sock_type; + }; + + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node.h b/source/blender/nodes/shader/materialx/nodes/node.h new file mode 100644 index 000000000000..c29e78abde32 --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/node.h @@ -0,0 +1,38 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include + +#include "DEG_depsgraph.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" + +namespace blender::nodes::materialx { + +class MaterialXNode { + public: + const Depsgraph *depsgraph = nullptr; + const Material *material = nullptr; + const bNode *node = nullptr; + MaterialX::NodePtr matx_node; + MaterialX::DocumentPtr doc; + + public: + MaterialXNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + virtual ~MaterialXNode() = default; + + virtual MaterialX::NodePtr convert() = 0; + + void get_input_link_node(const bNodeSocket *sock, + MaterialX::NodePtr matx_node_from, + const char *input); + std::string get_mx_type(const bNodeSocket *sock); +}; + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc b/source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc new file mode 100644 index 000000000000..b9ed8d05a72b --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc @@ -0,0 +1,136 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "principled_bsdf.h" + +#include +#include "shader/materialx/nodes/node.h" + +namespace blender::nodes::materialx { + +MaterialXPrincipledBSDFNode::MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : MaterialXNode(doc, depsgraph, material, node) +{ + matx_node = doc->addNode( + "standard_surface", MaterialX::createValidName(node->name), "surfaceshader"); +} + +MaterialX::NodePtr MaterialXPrincipledBSDFNode::convert() +{ + MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); +#pragma region get inputs + const bNodeSocket base_color_socket = node->input_by_identifier("Base Color"); + const char *matx_input = "base_color"; + if (base_color_socket.link) { + get_input_link_node(&base_color_socket, matx_node, matx_input); + } + else { + const float *base_color = base_color_socket.default_value_typed()->value; + matx_node->addInput("base_color", "color3")->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); + } + + + + const float *base_color = + node->input_by_identifier("Base Color").default_value_typed()->value; + const float subsurface = + node->input_by_identifier("Subsurface").default_value_typed()->value; + + const float *subsurface_radius = node->input_by_identifier("Subsurface Radius") + .default_value_typed() + ->value; + const float *subsurface_color = node->input_by_identifier("Subsurface Color") + .default_value_typed() + ->value; + const float metallic = + node->input_by_identifier("Metallic").default_value_typed()->value; + const float specular = + node->input_by_identifier("Specular").default_value_typed()->value; + const float roughness = + node->input_by_identifier("Roughness").default_value_typed()->value; + const float anisotropic = + node->input_by_identifier("Anisotropic").default_value_typed()->value; + const float anisotropic_rot = node->input_by_identifier("Anisotropic Rotation") + .default_value_typed() + ->value; + const float sheen = + node->input_by_identifier("Sheen").default_value_typed()->value; + const float clearcoat = + node->input_by_identifier("Clearcoat").default_value_typed()->value; + const float clearcoat_roughness = node->input_by_identifier("Clearcoat Roughness") + .default_value_typed() + ->value; + const float IOR = + node->input_by_identifier("IOR").default_value_typed()->value; + const float transmission = node->input_by_identifier("Transmission") + .default_value_typed() + ->value; + const float *emission = + node->input_by_identifier("Emission").default_value_typed()->value; + const float emission_str = node->input_by_identifier("Emission Strength") + .default_value_typed() + ->value; + const float *normal = + node->input_by_identifier("Normal").default_value_typed()->value; + const float *clearcoat_normal = node->input_by_identifier("Clearcoat Normal") + .default_value_typed() + ->value; + const float *tangent = + node->input_by_identifier("Tangent").default_value_typed()->value; +#pragma endregion get inputs + +#pragma region set inputs + matx_node->addInput("base", "float")->setValue(1.0); + matx_node->addInput("diffuse_roughness", "float")->setValue(roughness); + matx_node->addInput("normal", "vector3") + ->setValue(MaterialX::Vector3(normal[0], normal[1], normal[2])); + matx_node->addInput("tangent", "vector3") + ->setValue(MaterialX::Vector3(tangent[0], tangent[1], tangent[2])); + + matx_node->addInput("metalness", "float")->setValue(metallic); + + matx_node->addInput("specular", "float")->setValue(specular); + matx_node->addInput("specular_color", "color3")->setValue(default_white_color); + matx_node->addInput("specular_roughness", "float")->setValue(roughness); + matx_node->addInput("specular_IOR", "float")->setValue(IOR); + matx_node->addInput("specular_anisotropy", "float")->setValue(anisotropic); + matx_node->addInput("specular_rotation", "float")->setValue(anisotropic_rot); + + matx_node->addInput("transmission", "float")->setValue(transmission); + matx_node->addInput("transmission_color", "color3")->setValue(default_white_color); + matx_node->addInput("transmission_extra_roughness", "float")->setValue(roughness); + + matx_node->addInput("subsurface", "float")->setValue(subsurface); + matx_node->addInput("subsurface_color", "color3") + ->setValue(MaterialX::Color3(subsurface_color[0], subsurface_color[1], subsurface_color[2])); + matx_node->addInput("subsurface_radius", "color3") + ->setValue( + MaterialX::Color3(subsurface_radius[0], subsurface_radius[1], subsurface_radius[2])); + matx_node->addInput("subsurface_anisotropy", "float")->setValue(anisotropic); + + matx_node->addInput("sheen", "float")->setValue(sheen); + matx_node->addInput("sheen_color", "color3")->setValue(default_white_color); + matx_node->addInput("sheen_roughness", "float")->setValue(roughness); + + matx_node->addInput("coat", "float")->setValue(clearcoat); + matx_node->addInput("coat_color", "color3")->setValue(default_white_color); + matx_node->addInput("coat_roughness", "float")->setValue(clearcoat_roughness); + matx_node->addInput("coat_IOR", "float")->setValue(IOR); + matx_node->addInput("coat_anisotropy", "float")->setValue(anisotropic); + matx_node->addInput("coat_rotation", "float")->setValue(anisotropic_rot); + matx_node->addInput("coat_normal", "vector3") + ->setValue( + MaterialX::Vector3(clearcoat_normal[0], clearcoat_normal[1], clearcoat_normal[2])); + + matx_node->addInput("emission", "float")->setValue(emission_str); + matx_node->addInput("emission_color", "color3") + ->setValue(MaterialX::Color3(emission[0], emission[1], emission[2])); +#pragma endregion set inputs + return matx_node; +} + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.h b/source/blender/nodes/shader/materialx/nodes/principled_bsdf.h new file mode 100644 index 000000000000..ba7d08a5db71 --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/principled_bsdf.h @@ -0,0 +1,20 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "node.h" + +namespace blender::nodes::materialx { + +class MaterialXPrincipledBSDFNode : public MaterialXNode { + public: + MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + MaterialX::NodePtr convert() override; +}; + +} // namespace blender::nodes::materialx -- 2.30.2 From 3f1b272170fb1b067078da83bc65c434ec7adbe2 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 24 Aug 2023 17:09:20 +0300 Subject: [PATCH 04/11] Fixed path to mtlx file --- .../blender/nodes/shader/materialx/material.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 2f8df47b837d..60d3fb8eb299 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -8,7 +8,10 @@ #include #include -#include "NOD_shader.h" +#include "BLI_fileops.h" +#include "BLI_path_util.h" + +#include "BKE_appdir.h" #include "NOD_shader.h" @@ -47,9 +50,14 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater else { create_standard_surface(doc, material); } - MaterialX::writeToXmlFile( - doc, - MaterialX::FilePath("c:/Users/Vasyl_Pidhirskyi/Work/AMD/blender-git/tmp/material.mtlx")); + + char dir_path[FILE_MAX], file_path[FILE_MAX], file_name[32]; + BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra", "materialx"); + BLI_dir_create_recursive(dir_path); + SNPRINTF(file_name, "mat_%p.mtlx", material); + BLI_path_join(file_path, sizeof(file_path), dir_path, file_name); + MaterialX::writeToXmlFile(doc, MaterialX::FilePath(file_path)); + return doc; } -- 2.30.2 From d559b3b710289b376c3b1f5f9d004015ce647c2c Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 25 Aug 2023 15:16:39 +0300 Subject: [PATCH 05/11] Added usage of use_materialx in HydraSceneDelegate and MaterialData --- .../io/usd/hydra/hydra_scene_delegate.h | 2 + source/blender/io/usd/hydra/material.cc | 40 ++++++++++--------- .../nodes/shader/materialx/material.cc | 8 ---- source/blender/render/hydra/engine.cc | 1 + 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.h b/source/blender/io/usd/hydra/hydra_scene_delegate.h index 157db1e9ab74..424fd7aba799 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.h +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.h @@ -52,7 +52,9 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { const View3D *view3d = nullptr; Main *bmain = nullptr; Scene *scene = nullptr; + ShadingSettings shading_settings; + bool use_materialx = true; private: ObjectDataMap objects_; diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index 75a1c2162bf3..dd73c61e3d4b 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -70,9 +70,21 @@ void MaterialData::init() time, export_params, image_cache_file_path()}; - /* Create USD material. */ - //pxr::UsdShadeMaterial usd_material = usd::create_usd_material(export_context, material_path, (Material *)id, "st"); + pxr::UsdShadeMaterial usd_material; + if (scene_delegate_->use_materialx) { + MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(scene_delegate_->depsgraph, (Material *)id); + pxr::UsdMtlxRead(doc, stage); + if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) { + pxr::UsdPrimSiblingRange children = materials.GetChildren(); + if (!children.empty()) { + usd_material = pxr::UsdShadeMaterial(*children.begin()); + } + } + } + else { + usd_material = usd::create_usd_material(export_context, material_path, (Material *)id, "st"); + } /* Convert USD material to Hydra material network map, adapted for render delegate. */ const pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate(); @@ -81,23 +93,13 @@ void MaterialData::init() pxr::HdMaterialNetworkMap network_map; - MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(scene_delegate_->depsgraph, (Material *)id); - pxr::UsdMtlxRead(doc, stage); - - if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) { - if (pxr::UsdPrimSiblingRange children = materials.GetChildren()) { - if (auto usd_material = pxr::UsdShadeMaterial(*children.begin())) { - if (pxr::UsdShadeShader mtlx_surface = usd_material.ComputeSurfaceSource(contextVector)) - { - UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(), - pxr::HdMaterialTerminalTokens->surface, - shaderSourceTypes, - contextVector, - &network_map, - time); - } - } - } + if (pxr::UsdShadeShader mtlx_surface = usd_material.ComputeSurfaceSource(contextVector)) { + pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(), + pxr::HdMaterialTerminalTokens->surface, + shaderSourceTypes, + contextVector, + &network_map, + time); } material_network_map_ = pxr::VtValue(network_map); diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 60d3fb8eb299..9ebc5a537366 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -50,14 +50,6 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater else { create_standard_surface(doc, material); } - - char dir_path[FILE_MAX], file_path[FILE_MAX], file_name[32]; - BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra", "materialx"); - BLI_dir_create_recursive(dir_path); - SNPRINTF(file_name, "mat_%p.mtlx", material); - BLI_path_join(file_path, sizeof(file_path), dir_path, file_name); - MaterialX::writeToXmlFile(doc, MaterialX::FilePath(file_path)); - return doc; } diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 82f3c3172d84..5bf5dc653fbc 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -89,6 +89,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context) pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"); hydra_scene_delegate_ = std::make_unique(render_index_.get(), scene_path); + hydra_scene_delegate_->use_materialx = bl_engine_->type->flag & RE_USE_MATERIALX; } hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr); } -- 2.30.2 From 185950bbb89400a97d6aee4f59c00a08aa22315d Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 25 Aug 2023 16:07:45 +0300 Subject: [PATCH 06/11] Renamings --- source/blender/io/usd/hydra/material.cc | 6 ++++-- source/blender/nodes/shader/CMakeLists.txt | 16 ++++++++-------- .../nodes/shader/materialx/material.cc | 8 +------- ...{principled_bsdf.cc => bsdf_principled.cc} | 12 +++++------- .../{principled_bsdf.h => bsdf_principled.h} | 4 ++-- .../nodes/{node.cc => node_parser.cc} | 16 ++++++++++------ .../materialx/nodes/{node.h => node_parser.h} | 6 +++--- ...{material_output.cc => output_material.cc} | 19 +++---------------- .../{material_output.h => output_material.h} | 4 ++-- .../nodes/{image.cc => tex_image.cc} | 6 +++--- .../materialx/nodes/{image.h => tex_image.h} | 4 ++-- 11 files changed, 43 insertions(+), 58 deletions(-) rename source/blender/nodes/shader/materialx/nodes/{principled_bsdf.cc => bsdf_principled.cc} (95%) rename source/blender/nodes/shader/materialx/nodes/{principled_bsdf.h => bsdf_principled.h} (85%) rename source/blender/nodes/shader/materialx/nodes/{node.cc => node_parser.cc} (79%) rename source/blender/nodes/shader/materialx/nodes/{node.h => node_parser.h} (89%) rename source/blender/nodes/shader/materialx/nodes/{material_output.cc => output_material.cc} (58%) rename source/blender/nodes/shader/materialx/nodes/{material_output.h => output_material.h} (85%) rename source/blender/nodes/shader/materialx/nodes/{image.cc => tex_image.cc} (93%) rename source/blender/nodes/shader/materialx/nodes/{image.h => tex_image.h} (88%) diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index dd73c61e3d4b..8478cf0d55b9 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -73,7 +73,8 @@ void MaterialData::init() /* Create USD material. */ pxr::UsdShadeMaterial usd_material; if (scene_delegate_->use_materialx) { - MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(scene_delegate_->depsgraph, (Material *)id); + MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx( + scene_delegate_->depsgraph, (Material *)id); pxr::UsdMtlxRead(doc, stage); if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) { pxr::UsdPrimSiblingRange children = materials.GetChildren(); @@ -87,7 +88,8 @@ void MaterialData::init() } /* Convert USD material to Hydra material network map, adapted for render delegate. */ - const pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate(); + const pxr::HdRenderDelegate *render_delegate = + scene_delegate_->GetRenderIndex().GetRenderDelegate(); const pxr::TfTokenVector contextVector = render_delegate->GetMaterialRenderContexts(); pxr::TfTokenVector shaderSourceTypes = render_delegate->GetShaderSourceTypes(); diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index a166091d16d2..1888021af16c 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -148,16 +148,16 @@ if(WITH_MATERIALX) list(APPEND LIB MaterialXFormat) list(APPEND SRC materialx/material.cc - materialx/nodes/node.cc - materialx/nodes/material_output.cc - materialx/nodes/principled_bsdf.cc - materialx/nodes/image.cc + materialx/nodes/bsdf_principled.cc + materialx/nodes/node_parser.cc + materialx/nodes/output_material.cc + materialx/nodes/tex_image.cc materialx/material.h - materialx/nodes/node.h - materialx/nodes/material_output.h - materialx/nodes/principled_bsdf.h - materialx/nodes/image.h + materialx/nodes/bsdf_principled.h + materialx/nodes/node_parser.h + materialx/nodes/output_material.h + materialx/nodes/tex_image.h ) endif() diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 9ebc5a537366..3bf72b6ecf15 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -3,15 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "material.h" -#include "nodes/material_output.h" +#include "nodes/output_material.h" #include -#include - -#include "BLI_fileops.h" -#include "BLI_path_util.h" - -#include "BKE_appdir.h" #include "NOD_shader.h" diff --git a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc similarity index 95% rename from source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc rename to source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc index b9ed8d05a72b..db8f4b5361c1 100644 --- a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc @@ -2,10 +2,9 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "principled_bsdf.h" +#include "bsdf_principled.h" #include -#include "shader/materialx/nodes/node.h" namespace blender::nodes::materialx { @@ -13,7 +12,7 @@ MaterialXPrincipledBSDFNode::MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr const Depsgraph *depsgraph, const Material *material, const bNode *node) - : MaterialXNode(doc, depsgraph, material, node) + : NodeParser(doc, depsgraph, material, node) { matx_node = doc->addNode( "standard_surface", MaterialX::createValidName(node->name), "surfaceshader"); @@ -23,18 +22,17 @@ MaterialX::NodePtr MaterialXPrincipledBSDFNode::convert() { MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); #pragma region get inputs - const bNodeSocket base_color_socket = node->input_by_identifier("Base Color"); + const bNodeSocket base_color_socket = node->input_by_identifier("Base Color"); const char *matx_input = "base_color"; if (base_color_socket.link) { get_input_link_node(&base_color_socket, matx_node, matx_input); } else { const float *base_color = base_color_socket.default_value_typed()->value; - matx_node->addInput("base_color", "color3")->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); + matx_node->addInput("base_color", "color3") + ->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); } - - const float *base_color = node->input_by_identifier("Base Color").default_value_typed()->value; const float subsurface = diff --git a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.h b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h similarity index 85% rename from source/blender/nodes/shader/materialx/nodes/principled_bsdf.h rename to source/blender/nodes/shader/materialx/nodes/bsdf_principled.h index ba7d08a5db71..959c1e281427 100644 --- a/source/blender/nodes/shader/materialx/nodes/principled_bsdf.h +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h @@ -4,11 +4,11 @@ #pragma once -#include "node.h" +#include "node_parser.h" namespace blender::nodes::materialx { -class MaterialXPrincipledBSDFNode : public MaterialXNode { +class MaterialXPrincipledBSDFNode : public NodeParser { public: MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc, const Depsgraph *depsgraph, diff --git a/source/blender/nodes/shader/materialx/nodes/node.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc similarity index 79% rename from source/blender/nodes/shader/materialx/nodes/node.cc rename to source/blender/nodes/shader/materialx/nodes/node_parser.cc index 54d3838f3f3f..8c59bea6594c 100644 --- a/source/blender/nodes/shader/materialx/nodes/node.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -2,14 +2,16 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "node.h" -#include "principled_bsdf.h" -#include "image.h" +#include "node_parser.h" + +#include "bsdf_principled.h" +#include "tex_image.h" + #include namespace blender::nodes::materialx { -MaterialXNode::MaterialXNode(MaterialX::DocumentPtr doc, +NodeParser::NodeParser(MaterialX::DocumentPtr doc, const Depsgraph *depsgraph, const Material *material, const bNode *node) @@ -17,7 +19,9 @@ MaterialXNode::MaterialXNode(MaterialX::DocumentPtr doc, { } -void MaterialXNode::get_input_link_node(const bNodeSocket *sock, MaterialX::NodePtr matx_node_to, const char *input) +void NodeParser::get_input_link_node(const bNodeSocket *sock, + MaterialX::NodePtr matx_node_to, + const char *input) { const bNode *inode = sock->link->fromnode; if (inode->type == SH_NODE_BSDF_PRINCIPLED) { @@ -35,7 +39,7 @@ void MaterialXNode::get_input_link_node(const bNodeSocket *sock, MaterialX::Node matx_node_to->addInput(input, get_mx_type(sock))->setNodeName(MaterialX::createValidName(inode->name)); }; -std::string MaterialXNode::get_mx_type(const bNodeSocket *sock) +std::string NodeParser::get_mx_type(const bNodeSocket *sock) { std::string mx_sock_type; switch (sock->type) { diff --git a/source/blender/nodes/shader/materialx/nodes/node.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h similarity index 89% rename from source/blender/nodes/shader/materialx/nodes/node.h rename to source/blender/nodes/shader/materialx/nodes/node_parser.h index c29e78abde32..515cb6255cb4 100644 --- a/source/blender/nodes/shader/materialx/nodes/node.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -12,7 +12,7 @@ namespace blender::nodes::materialx { -class MaterialXNode { +class NodeParser { public: const Depsgraph *depsgraph = nullptr; const Material *material = nullptr; @@ -21,11 +21,11 @@ class MaterialXNode { MaterialX::DocumentPtr doc; public: - MaterialXNode(MaterialX::DocumentPtr doc, + NodeParser(MaterialX::DocumentPtr doc, const Depsgraph *depsgraph, const Material *material, const bNode *node); - virtual ~MaterialXNode() = default; + virtual ~NodeParser() = default; virtual MaterialX::NodePtr convert() = 0; diff --git a/source/blender/nodes/shader/materialx/nodes/material_output.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc similarity index 58% rename from source/blender/nodes/shader/materialx/nodes/material_output.cc rename to source/blender/nodes/shader/materialx/nodes/output_material.cc index 1128b7fd7127..1bc2ccb6988a 100644 --- a/source/blender/nodes/shader/materialx/nodes/material_output.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -2,8 +2,7 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "material_output.h" -#include "principled_bsdf.h" +#include "output_material.h" namespace blender::nodes::materialx { @@ -11,25 +10,13 @@ MaterialXMaterialOutputNode::MaterialXMaterialOutputNode(MaterialX::DocumentPtr const Depsgraph *depsgraph, const Material *material, const bNode *node) - : MaterialXNode(doc, depsgraph, material, node) + : NodeParser(doc, depsgraph, material, node) { matx_node = doc->addNode("surfacematerial", MaterialX::createValidName(node->name), "material"); } MaterialX::NodePtr MaterialXMaterialOutputNode::convert() -{ - //LISTBASE_FOREACH (const bNodeSocket *, sock, &node->inputs) { - // if (!sock->link) { - // continue; - // } - // if (STREQ(sock->name, "Surface")) { - // const bNode *inode = sock->link->fromnode; - // MaterialXPrincipledBSDFNode surface_node(doc, material, inode); - // surface_node.convert(); - // matx_node->addInput("surfaceshader", "surfaceshader")->setNodeName(inode->name); - // } - //} - const char *matx_socket = "surfaceshader"; +{ const char *matx_socket = "surfaceshader"; const bNodeSocket sock = node->input_by_identifier("Surface"); get_input_link_node(&sock, matx_node, matx_socket); return matx_node; diff --git a/source/blender/nodes/shader/materialx/nodes/material_output.h b/source/blender/nodes/shader/materialx/nodes/output_material.h similarity index 85% rename from source/blender/nodes/shader/materialx/nodes/material_output.h rename to source/blender/nodes/shader/materialx/nodes/output_material.h index 8ffda3d00d94..3fa9a7d77327 100644 --- a/source/blender/nodes/shader/materialx/nodes/material_output.h +++ b/source/blender/nodes/shader/materialx/nodes/output_material.h @@ -4,11 +4,11 @@ #pragma once -#include "node.h" +#include "node_parser.h" namespace blender::nodes::materialx { -class MaterialXMaterialOutputNode : public MaterialXNode { +class MaterialXMaterialOutputNode : public NodeParser { public: MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc, const Depsgraph *depsgraph, diff --git a/source/blender/nodes/shader/materialx/nodes/image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc similarity index 93% rename from source/blender/nodes/shader/materialx/nodes/image.cc rename to source/blender/nodes/shader/materialx/nodes/tex_image.cc index f7f192ace407..8eb780764a16 100644 --- a/source/blender/nodes/shader/materialx/nodes/image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -2,8 +2,8 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "node.h" -#include "image.h" +#include "tex_image.h" +#include "node_parser.h" #include "hydra/image.h" @@ -17,7 +17,7 @@ MaterialXTexImageNode::MaterialXTexImageNode(MaterialX::DocumentPtr doc, const Depsgraph *depsgraph, const Material *material, const bNode *node) - : MaterialXNode(doc, depsgraph, material, node) + : NodeParser(doc, depsgraph, material, node) { matx_node = doc->addNode("image", MaterialX::createValidName(node->name), "color3"); } diff --git a/source/blender/nodes/shader/materialx/nodes/image.h b/source/blender/nodes/shader/materialx/nodes/tex_image.h similarity index 88% rename from source/blender/nodes/shader/materialx/nodes/image.h rename to source/blender/nodes/shader/materialx/nodes/tex_image.h index fc83f8b3e4a7..1e6f5f008bf8 100644 --- a/source/blender/nodes/shader/materialx/nodes/image.h +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.h @@ -4,11 +4,11 @@ #pragma once -#include "node.h" +#include "node_parser.h" namespace blender::nodes::materialx { -class MaterialXTexImageNode : public MaterialXNode { +class MaterialXTexImageNode : public NodeParser { protected: /* Following Cycles color for wrong Texture nodes. */ static const MaterialX::Color3 texture_error_color_; -- 2.30.2 From b9323f22989842ee52b4434d669e7db2be0db06b Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 26 Aug 2023 01:02:55 +0300 Subject: [PATCH 07/11] Implementing NodeItem and NodeParser --- .../nodes/shader/materialx/material.cc | 4 +- .../shader/materialx/nodes/bsdf_principled.cc | 12 +- .../shader/materialx/nodes/bsdf_principled.h | 9 +- .../shader/materialx/nodes/node_parser.cc | 151 +++++++++++++++--- .../shader/materialx/nodes/node_parser.h | 55 +++++-- .../shader/materialx/nodes/output_material.cc | 13 +- .../shader/materialx/nodes/output_material.h | 12 +- .../nodes/shader/materialx/nodes/tex_image.cc | 12 +- .../nodes/shader/materialx/nodes/tex_image.h | 12 +- 9 files changed, 203 insertions(+), 77 deletions(-) diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 3bf72b6ecf15..7dc601570950 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -16,8 +16,8 @@ static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, M material->nodetree->ensure_topology_cache(); bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); - MaterialXMaterialOutputNode material_node(doc, depsgraph, material, output_node); - material_node.convert(); + OutputMaterialNodeParser material_node(doc, depsgraph, material, output_node); + material_node.compute(); } static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material) diff --git a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc index db8f4b5361c1..cfe44e8551ca 100644 --- a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc @@ -8,18 +8,10 @@ namespace blender::nodes::materialx { -MaterialXPrincipledBSDFNode::MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) - : NodeParser(doc, depsgraph, material, node) +NodeItem BSDFPrincipledNodeParser::compute() { - matx_node = doc->addNode( - "standard_surface", MaterialX::createValidName(node->name), "surfaceshader"); -} + NodeItem node = create_node("standard_surface", "surfaceshader"); -MaterialX::NodePtr MaterialXPrincipledBSDFNode::convert() -{ MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); #pragma region get inputs const bNodeSocket base_color_socket = node->input_by_identifier("Base Color"); diff --git a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h index 959c1e281427..b4cace6d8216 100644 --- a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.h @@ -8,13 +8,10 @@ namespace blender::nodes::materialx { -class MaterialXPrincipledBSDFNode : public NodeParser { +class BSDFPrincipledNodeParser : public NodeParser { public: - MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); - MaterialX::NodePtr convert() override; + using NodeParser::NodeParser; + NodeItem compute() override; }; } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 8c59bea6594c..3ec65e1c57a9 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -11,33 +11,141 @@ namespace blender::nodes::materialx { -NodeParser::NodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) - : depsgraph(depsgraph), material(material), node(node), doc(doc) +NodeItem::NodeItem(MaterialX::GraphElement *graph) + : graph_(graph) { } -void NodeParser::get_input_link_node(const bNodeSocket *sock, - MaterialX::NodePtr matx_node_to, - const char *input) +void NodeItem::set_input(const std::string &name, const NodeItem &item) { - const bNode *inode = sock->link->fromnode; - if (inode->type == SH_NODE_BSDF_PRINCIPLED) { - MaterialXPrincipledBSDFNode maxt_node(doc, depsgraph, material, inode); - maxt_node.convert(); - } - else if (inode->type == SH_NODE_TEX_IMAGE) { - MaterialXTexImageNode maxt_node(doc, depsgraph, material, inode); - maxt_node.convert(); + if (item.value) { + set_input(name, item.value); } else { - return; + set_input(name, item.node); } - const bNodeSocket *sock_from = sock->link->fromsock; - matx_node_to->addInput(input, get_mx_type(sock))->setNodeName(MaterialX::createValidName(inode->name)); -}; +} + +void NodeItem::set_input(const std::string &name, const MaterialX::ValuePtr value) +{ + if (value->isA()) { + set_input(name, value->asA(), "float"); + } + else if (value->isA()) { + set_input(name, value->asA(), "vector3"); + } + else if (value->isA()) { + set_input(name, value->asA(), "vector4"); + } + else if (value->isA()) { + set_input(name, value->asA(), "color3"); + } + else if (value->isA()) { + set_input(name, value->asA(), "color4"); + } + else { + BLI_assert_unreachable(); + } +} + +void NodeItem::set_input(const std::string &name, const MaterialX::NodePtr node) +{ + node->setConnectedNode(name, node); +} + +NodeItem::operator bool() const +{ + return !value && !node; +} + +NodeParser::NodeParser(MaterialX::GraphElement *graph, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : graph(graph), depsgraph(depsgraph), material(material), node(node) +{ +} + +NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type) +{ + NodeItem item(graph); + item.node = graph->addNode(mx_category, MaterialX::createValidName(node->name), mx_type); + return item; +} + +NodeItem NodeParser::get_input_default(const std::string &name) +{ + const bNodeSocket &socket = node->input_by_identifier(name); + NodeItem item(graph); + switch (socket.type) { + case SOCK_FLOAT: { + float v = socket.default_value_typed()->value; + item.value = MaterialX::Value::createValue(v); + } break; + case SOCK_VECTOR: { + const float *v = socket.default_value_typed()->value; + item.value = MaterialX::Value::createValue( + MaterialX::Vector3(v[0], v[1], v[2])); + } break; + case SOCK_RGBA: { + const float *v = socket.default_value_typed()->value; + item.value = MaterialX::Value::createValue( + MaterialX::Color4(v[0], v[1], v[2], v[3])); + } break; + default: { + // TODO log warn + } + } + return item; +} + + +NodeItem NodeParser::get_input_link(const std::string &name) +{ + NodeItem item(graph); + + const bNodeLink *link = node->input_by_identifier(name).link; + if (!link->is_used()) { + return item; + } + + const bNode *in_node = link->fromnode; + + /* Passing NODE_REROUTE nodes */ + while (in_node->type == NODE_REROUTE) { + link = in_node->input_socket(0).link; + if (!link->is_used()) { + return item; + } + in_node = link->fromnode; + } + + /* Getting required NodeParser object */ + std::unique_ptr parser; + switch (in_node->type) { + case SH_NODE_BSDF_PRINCIPLED: + parser = std::make_unique(graph, depsgraph, material, in_node); + break; + case SH_NODE_TEX_IMAGE: + parser = std::make_unique(graph, depsgraph, material, in_node); + break; + default: + // TODO: warning log + return item; + } + + item = parser->compute(); + return item; +} + +NodeItem NodeParser::get_input_value(const std::string &name) +{ + NodeItem item = get_input_link(name); + if (!item) { + item = get_input_value(name); + } + return item; +} std::string NodeParser::get_mx_type(const bNodeSocket *sock) { @@ -69,7 +177,6 @@ std::string NodeParser::get_mx_type(const bNodeSocket *sock) } } return mx_sock_type; - }; - +} } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 515cb6255cb4..68ffe1555257 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -12,26 +12,55 @@ namespace blender::nodes::materialx { +class NodeItem { + public: + MaterialX::ValuePtr value; + MaterialX::NodePtr node; + + private: + MaterialX::GraphElement *graph_; + + public: + NodeItem(MaterialX::GraphElement *graph); + ~NodeItem() = default; + + template + void set_input(const std::string &name, const T &value, const std::string &mx_type); + void set_input(const std::string &name, const NodeItem &item); + void set_input(const std::string &name, const MaterialX::ValuePtr value); + void set_input(const std::string &name, const MaterialX::NodePtr node); + + operator bool() const; +}; + +template +void NodeItem::set_input(const std::string &name, const T &value, const std::string &mx_type) +{ + node->setInputValue(name, value, mx_type); +} + class NodeParser { public: - const Depsgraph *depsgraph = nullptr; - const Material *material = nullptr; - const bNode *node = nullptr; - MaterialX::NodePtr matx_node; - MaterialX::DocumentPtr doc; + MaterialX::GraphElement *graph; + const Depsgraph *depsgraph; + const Material *material; + const bNode *node; public: - NodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); + NodeParser(MaterialX::GraphElement *graph, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); virtual ~NodeParser() = default; - virtual MaterialX::NodePtr convert() = 0; + virtual NodeItem compute() = 0; + + protected: + NodeItem create_node(const std::string &mx_category, const std::string &mx_type); + NodeItem get_input_default(const std::string &name); + NodeItem get_input_link(const std::string &name); + NodeItem get_input_value(const std::string &name); - void get_input_link_node(const bNodeSocket *sock, - MaterialX::NodePtr matx_node_from, - const char *input); std::string get_mx_type(const bNodeSocket *sock); }; diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index 1bc2ccb6988a..e84dd8928e4a 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -6,17 +6,18 @@ namespace blender::nodes::materialx { -MaterialXMaterialOutputNode::MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) +OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) : NodeParser(doc, depsgraph, material, node) { matx_node = doc->addNode("surfacematerial", MaterialX::createValidName(node->name), "material"); } -MaterialX::NodePtr MaterialXMaterialOutputNode::convert() -{ const char *matx_socket = "surfaceshader"; +MaterialX::NodePtr OutputMaterialNodeParser::compute() +{ + const char *matx_socket = "surfaceshader"; const bNodeSocket sock = node->input_by_identifier("Surface"); get_input_link_node(&sock, matx_node, matx_socket); return matx_node; diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.h b/source/blender/nodes/shader/materialx/nodes/output_material.h index 3fa9a7d77327..468a61d67373 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.h +++ b/source/blender/nodes/shader/materialx/nodes/output_material.h @@ -8,13 +8,13 @@ namespace blender::nodes::materialx { -class MaterialXMaterialOutputNode : public NodeParser { +class OutputMaterialNodeParser : public NodeParser { public: - MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); - MaterialX::NodePtr convert() override; + OutputMaterialNodeParser(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + MaterialX::NodePtr compute() override; }; } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc index 8eb780764a16..5b64b4016b7b 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -11,18 +11,18 @@ namespace blender::nodes::materialx { -const MaterialX::Color3 MaterialXTexImageNode::texture_error_color_{1.0, 0.0, 1.0}; +const MaterialX::Color3 TexImageNodeParser::texture_error_color_{1.0, 0.0, 1.0}; -MaterialXTexImageNode::MaterialXTexImageNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) +TexImageNodeParser::TexImageNodeParser(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) : NodeParser(doc, depsgraph, material, node) { matx_node = doc->addNode("image", MaterialX::createValidName(node->name), "color3"); } -MaterialX::NodePtr MaterialXTexImageNode::convert() +MaterialX::NodePtr TexImageNodeParser::compute() { Image *image = (Image *)node->id; NodeTexImage *tex = static_cast(node->storage); diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.h b/source/blender/nodes/shader/materialx/nodes/tex_image.h index 1e6f5f008bf8..4370594b2694 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.h +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.h @@ -8,17 +8,17 @@ namespace blender::nodes::materialx { -class MaterialXTexImageNode : public NodeParser { +class TexImageNodeParser : public NodeParser { protected: /* Following Cycles color for wrong Texture nodes. */ static const MaterialX::Color3 texture_error_color_; public: - MaterialXTexImageNode(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); - MaterialX::NodePtr convert() override; + TexImageNodeParser(MaterialX::DocumentPtr doc, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + MaterialX::NodePtr compute() override; }; } // namespace blender::nodes::materialx -- 2.30.2 From 8777144f9655f1420fd7e96db6830ce6e91032b3 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 26 Aug 2023 02:19:55 +0300 Subject: [PATCH 08/11] Implementing NodeParser nodes --- .../nodes/shader/materialx/material.cc | 20 +- .../blender/nodes/shader/materialx/material.h | 2 - .../shader/materialx/nodes/bsdf_principled.cc | 327 ++++++++++++------ .../shader/materialx/nodes/node_parser.cc | 55 +-- .../shader/materialx/nodes/node_parser.h | 5 +- .../shader/materialx/nodes/output_material.cc | 22 +- .../shader/materialx/nodes/output_material.h | 7 +- .../nodes/shader/materialx/nodes/tex_image.cc | 22 +- .../nodes/shader/materialx/nodes/tex_image.h | 11 +- 9 files changed, 293 insertions(+), 178 deletions(-) diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 7dc601570950..3c37aa50371d 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -11,26 +11,28 @@ namespace blender::nodes::materialx { -static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, Material *material) +static void export_nodegraph(MaterialX::GraphElement *graph, + Depsgraph *depsgraph, + Material *material) { material->nodetree->ensure_topology_cache(); bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); - OutputMaterialNodeParser material_node(doc, depsgraph, material, output_node); - material_node.compute(); + OutputMaterialNodeParser parser(graph, depsgraph, material, output_node); + parser.compute(); } -static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material) +static void create_standard_surface(MaterialX::GraphElement *graph, Material *material) { - MaterialX::NodePtr surfacematerial = doc->addNode( - "surfacematerial", MaterialX::EMPTY_STRING, "material"); - MaterialX::NodePtr standard_surface = doc->addNode( + MaterialX::NodePtr standard_surface = graph->addNode( "standard_surface", MaterialX::EMPTY_STRING, "surfaceshader"); standard_surface->addInput("base", "float")->setValue(1.0); standard_surface->addInput("base_color", "color3") ->setValue(MaterialX::Color3(material->r, material->g, material->b)); + MaterialX::NodePtr surfacematerial = graph->addNode( + "surfacematerial", MaterialX::EMPTY_STRING, "material"); surfacematerial->addInput(standard_surface->getType(), standard_surface->getType()) ->setNodeName(standard_surface->getName()); } @@ -39,10 +41,10 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater { MaterialX::DocumentPtr doc = MaterialX::createDocument(); if (material->use_nodes) { - export_nodegraph(doc, depsgraph, material); + export_nodegraph(doc.get(), depsgraph, material); } else { - create_standard_surface(doc, material); + create_standard_surface(doc.get(), material); } return doc; } diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index 799450a8fda7..1784c42349b7 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -12,7 +12,5 @@ namespace blender::nodes::materialx { MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material); -static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material); -static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, Material *material); } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc index cfe44e8551ca..e49b0cb156bd 100644 --- a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc @@ -10,117 +10,246 @@ namespace blender::nodes::materialx { NodeItem BSDFPrincipledNodeParser::compute() { - NodeItem node = create_node("standard_surface", "surfaceshader"); + auto enabled = [](NodeItem &val) -> bool + { + if (val.node) { + return true; + } + if (!val.value) { + return false; + } + if (val.value->isA()) { + return val.value->asA() != 0.0f; + } + return true; + }; - MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); -#pragma region get inputs - const bNodeSocket base_color_socket = node->input_by_identifier("Base Color"); - const char *matx_input = "base_color"; - if (base_color_socket.link) { - get_input_link_node(&base_color_socket, matx_node, matx_input); - } - else { - const float *base_color = base_color_socket.default_value_typed()->value; - matx_node->addInput("base_color", "color3") - ->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); + /* Getting required inputs + * Note: if some inputs are not needed they won't be taken */ + NodeItem base_color = get_input_value("Base Color"); + + NodeItem subsurface = get_input_value("Subsurface"); + NodeItem subsurface_radius = empty_value(); + NodeItem subsurface_color = empty_value(); + if (enabled(subsurface)) { + subsurface_radius = get_input_value("Subsurface Radius"); + subsurface_color = get_input_value("Subsurface Color"); } - const float *base_color = - node->input_by_identifier("Base Color").default_value_typed()->value; - const float subsurface = - node->input_by_identifier("Subsurface").default_value_typed()->value; + NodeItem metallic = get_input_value("Metallic"); + NodeItem specular = get_input_value("Specular"); + // NodeItem specular_tint = get_input_value("Specular Tint"); + NodeItem roughness = get_input_value("Roughness"); - const float *subsurface_radius = node->input_by_identifier("Subsurface Radius") - .default_value_typed() - ->value; - const float *subsurface_color = node->input_by_identifier("Subsurface Color") - .default_value_typed() - ->value; - const float metallic = - node->input_by_identifier("Metallic").default_value_typed()->value; - const float specular = - node->input_by_identifier("Specular").default_value_typed()->value; - const float roughness = - node->input_by_identifier("Roughness").default_value_typed()->value; - const float anisotropic = - node->input_by_identifier("Anisotropic").default_value_typed()->value; - const float anisotropic_rot = node->input_by_identifier("Anisotropic Rotation") - .default_value_typed() - ->value; - const float sheen = - node->input_by_identifier("Sheen").default_value_typed()->value; - const float clearcoat = - node->input_by_identifier("Clearcoat").default_value_typed()->value; - const float clearcoat_roughness = node->input_by_identifier("Clearcoat Roughness") - .default_value_typed() - ->value; - const float IOR = - node->input_by_identifier("IOR").default_value_typed()->value; - const float transmission = node->input_by_identifier("Transmission") - .default_value_typed() - ->value; - const float *emission = - node->input_by_identifier("Emission").default_value_typed()->value; - const float emission_str = node->input_by_identifier("Emission Strength") - .default_value_typed() - ->value; - const float *normal = - node->input_by_identifier("Normal").default_value_typed()->value; - const float *clearcoat_normal = node->input_by_identifier("Clearcoat Normal") - .default_value_typed() - ->value; - const float *tangent = - node->input_by_identifier("Tangent").default_value_typed()->value; -#pragma endregion get inputs + NodeItem anisotropic = empty_value(); + NodeItem anisotropic_rotation = empty_value(); + if (enabled(metallic)) { + /* TODO: use Specular Tint input */ + anisotropic = get_input_value("Anisotropic"); + if (enabled(anisotropic)) { + anisotropic_rotation = get_input_value("Anisotropic Rotation"); + // anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0) + } + } -#pragma region set inputs - matx_node->addInput("base", "float")->setValue(1.0); - matx_node->addInput("diffuse_roughness", "float")->setValue(roughness); - matx_node->addInput("normal", "vector3") - ->setValue(MaterialX::Vector3(normal[0], normal[1], normal[2])); - matx_node->addInput("tangent", "vector3") - ->setValue(MaterialX::Vector3(tangent[0], tangent[1], tangent[2])); + NodeItem sheen = get_input_value("Sheen"); + // sheen_tint = empty_value(); + // if enabled(sheen): + // sheen_tint = get_input_value("Sheen Tint"); - matx_node->addInput("metalness", "float")->setValue(metallic); + NodeItem clearcoat = get_input_value("Clearcoat"); + NodeItem clearcoat_roughness = empty_value(); + if (enabled(clearcoat)) { + clearcoat_roughness = get_input_value("Clearcoat Roughness"); + } - matx_node->addInput("specular", "float")->setValue(specular); - matx_node->addInput("specular_color", "color3")->setValue(default_white_color); - matx_node->addInput("specular_roughness", "float")->setValue(roughness); - matx_node->addInput("specular_IOR", "float")->setValue(IOR); - matx_node->addInput("specular_anisotropy", "float")->setValue(anisotropic); - matx_node->addInput("specular_rotation", "float")->setValue(anisotropic_rot); + NodeItem ior = get_input_value("IOR"); - matx_node->addInput("transmission", "float")->setValue(transmission); - matx_node->addInput("transmission_color", "color3")->setValue(default_white_color); - matx_node->addInput("transmission_extra_roughness", "float")->setValue(roughness); + NodeItem transmission = get_input_value("Transmission"); + NodeItem transmission_roughness = empty_value(); + if (enabled(transmission)) { + transmission_roughness = get_input_value("Transmission Roughness"); + } - matx_node->addInput("subsurface", "float")->setValue(subsurface); - matx_node->addInput("subsurface_color", "color3") - ->setValue(MaterialX::Color3(subsurface_color[0], subsurface_color[1], subsurface_color[2])); - matx_node->addInput("subsurface_radius", "color3") - ->setValue( - MaterialX::Color3(subsurface_radius[0], subsurface_radius[1], subsurface_radius[2])); - matx_node->addInput("subsurface_anisotropy", "float")->setValue(anisotropic); + NodeItem emission = get_input_value("Emission"); + NodeItem emission_strength = get_input_value("Emission Strength"); - matx_node->addInput("sheen", "float")->setValue(sheen); - matx_node->addInput("sheen_color", "color3")->setValue(default_white_color); - matx_node->addInput("sheen_roughness", "float")->setValue(roughness); + NodeItem alpha = get_input_value("Alpha"); + // transparency = 1.0 - alpha - matx_node->addInput("coat", "float")->setValue(clearcoat); - matx_node->addInput("coat_color", "color3")->setValue(default_white_color); - matx_node->addInput("coat_roughness", "float")->setValue(clearcoat_roughness); - matx_node->addInput("coat_IOR", "float")->setValue(IOR); - matx_node->addInput("coat_anisotropy", "float")->setValue(anisotropic); - matx_node->addInput("coat_rotation", "float")->setValue(anisotropic_rot); - matx_node->addInput("coat_normal", "vector3") - ->setValue( - MaterialX::Vector3(clearcoat_normal[0], clearcoat_normal[1], clearcoat_normal[2])); + NodeItem normal = get_input_link("Normal"); + NodeItem clearcoat_normal = get_input_link("Clearcoat Normal"); + NodeItem tangent = get_input_link("Tangent"); - matx_node->addInput("emission", "float")->setValue(emission_str); - matx_node->addInput("emission_color", "color3") - ->setValue(MaterialX::Color3(emission[0], emission[1], emission[2])); -#pragma endregion set inputs - return matx_node; + /* Creating standard_surface */ + NodeItem res = create_node("standard_surface", "surfaceshader"); + res.set_input("base", 1.0, "float"); + res.set_input("base_color", base_color); + res.set_input("diffuse_roughness", roughness); + res.set_input("normal", normal); + res.set_input("tangent", tangent); + + if (enabled(metallic)) { + res.set_input("metalness", metallic); + } + + if (enabled(specular)) { + res.set_input("specular", specular); + res.set_input("specular_color", base_color); + res.set_input("specular_roughness", roughness); + res.set_input("specular_IOR", ior); + res.set_input("specular_anisotropy", anisotropic); + res.set_input("specular_rotation", anisotropic_rotation); + } + + if (enabled(transmission)) { + res.set_input("transmission", transmission); + res.set_input("transmission_color", base_color); + res.set_input("transmission_extra_roughness", transmission_roughness); + } + + if (enabled(subsurface)) { + res.set_input("subsurface", subsurface); + res.set_input("subsurface_color", subsurface_color); + res.set_input("subsurface_radius", subsurface_radius); + res.set_input("subsurface_anisotropy", anisotropic); + } + + if (enabled(sheen)) { + res.set_input("sheen", sheen); + res.set_input("sheen_color", base_color); + res.set_input("sheen_roughness", roughness); + } + + if (enabled(clearcoat)) { + res.set_input("coat", clearcoat); + res.set_input("coat_color", base_color); + res.set_input("coat_roughness", clearcoat_roughness); + res.set_input("coat_IOR", ior); + res.set_input("coat_anisotropy", anisotropic); + res.set_input("coat_rotation", anisotropic_rotation); + res.set_input("coat_normal", clearcoat_normal); + } + + if (enabled(emission)) { + res.set_input("emission", emission_strength); + res.set_input("emission_color", emission); + } + + return res; + + + +// +// MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); +//#pragma region get inputs +// const bNodeSocket base_color_socket = res->input_by_identifier("Base Color"); +// const char *matx_input = "base_color"; +// if (base_color_socket.link) { +// get_input_link_node(&base_color_socket, matx_node, matx_input); +// } +// else { +// const float *base_color = base_color_socket.default_value_typed()->value; +// matx_node->addInput("base_color", "color3") +// ->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); +// } +// +// const float *base_color = +// res->input_by_identifier("Base Color").default_value_typed()->value; +// const float subsurface = +// res->input_by_identifier("Subsurface").default_value_typed()->value; +// +// const float *subsurface_radius = res->input_by_identifier("Subsurface Radius") +// .default_value_typed() +// ->value; +// const float *subsurface_color = res->input_by_identifier("Subsurface Color") +// .default_value_typed() +// ->value; +// const float metallic = +// res->input_by_identifier("Metallic").default_value_typed()->value; +// const float specular = +// res->input_by_identifier("Specular").default_value_typed()->value; +// const float roughness = +// res->input_by_identifier("Roughness").default_value_typed()->value; +// const float anisotropic = +// res->input_by_identifier("Anisotropic").default_value_typed()->value; +// const float anisotropic_rot = res->input_by_identifier("Anisotropic Rotation") +// .default_value_typed() +// ->value; +// const float sheen = +// res->input_by_identifier("Sheen").default_value_typed()->value; +// const float clearcoat = +// res->input_by_identifier("Clearcoat").default_value_typed()->value; +// const float clearcoat_roughness = res->input_by_identifier("Clearcoat Roughness") +// .default_value_typed() +// ->value; +// const float IOR = +// res->input_by_identifier("IOR").default_value_typed()->value; +// const float transmission = res->input_by_identifier("Transmission") +// .default_value_typed() +// ->value; +// const float *emission = +// res->input_by_identifier("Emission").default_value_typed()->value; +// const float emission_str = res->input_by_identifier("Emission Strength") +// .default_value_typed() +// ->value; +// const float *normal = +// res->input_by_identifier("Normal").default_value_typed()->value; +// const float *clearcoat_normal = res->input_by_identifier("Clearcoat Normal") +// .default_value_typed() +// ->value; +// const float *tangent = +// res->input_by_identifier("Tangent").default_value_typed()->value; +//#pragma endregion get inputs +// +//#pragma region set inputs +// matx_node->addInput("base", "float")->setValue(1.0); +// matx_node->addInput("diffuse_roughness", "float")->setValue(roughness); +// matx_node->addInput("normal", "vector3") +// ->setValue(MaterialX::Vector3(normal[0], normal[1], normal[2])); +// matx_node->addInput("tangent", "vector3") +// ->setValue(MaterialX::Vector3(tangent[0], tangent[1], tangent[2])); +// +// matx_node->addInput("metalness", "float")->setValue(metallic); +// +// matx_node->addInput("specular", "float")->setValue(specular); +// matx_node->addInput("specular_color", "color3")->setValue(default_white_color); +// matx_node->addInput("specular_roughness", "float")->setValue(roughness); +// matx_node->addInput("specular_IOR", "float")->setValue(IOR); +// matx_node->addInput("specular_anisotropy", "float")->setValue(anisotropic); +// matx_node->addInput("specular_rotation", "float")->setValue(anisotropic_rot); +// +// matx_node->addInput("transmission", "float")->setValue(transmission); +// matx_node->addInput("transmission_color", "color3")->setValue(default_white_color); +// matx_node->addInput("transmission_extra_roughness", "float")->setValue(roughness); +// +// matx_node->addInput("subsurface", "float")->setValue(subsurface); +// matx_node->addInput("subsurface_color", "color3") +// ->setValue(MaterialX::Color3(subsurface_color[0], subsurface_color[1], subsurface_color[2])); +// matx_node->addInput("subsurface_radius", "color3") +// ->setValue( +// MaterialX::Color3(subsurface_radius[0], subsurface_radius[1], subsurface_radius[2])); +// matx_node->addInput("subsurface_anisotropy", "float")->setValue(anisotropic); +// +// matx_node->addInput("sheen", "float")->setValue(sheen); +// matx_node->addInput("sheen_color", "color3")->setValue(default_white_color); +// matx_node->addInput("sheen_roughness", "float")->setValue(roughness); +// +// matx_node->addInput("coat", "float")->setValue(clearcoat); +// matx_node->addInput("coat_color", "color3")->setValue(default_white_color); +// matx_node->addInput("coat_roughness", "float")->setValue(clearcoat_roughness); +// matx_node->addInput("coat_IOR", "float")->setValue(IOR); +// matx_node->addInput("coat_anisotropy", "float")->setValue(anisotropic); +// matx_node->addInput("coat_rotation", "float")->setValue(anisotropic_rot); +// matx_node->addInput("coat_normal", "vector3") +// ->setValue( +// MaterialX::Vector3(clearcoat_normal[0], clearcoat_normal[1], clearcoat_normal[2])); +// +// matx_node->addInput("emission", "float")->setValue(emission_str); +// matx_node->addInput("emission_color", "color3") +// ->setValue(MaterialX::Color3(emission[0], emission[1], emission[2])); +//#pragma endregion set inputs +// return matx_node; } } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 3ec65e1c57a9..48722fb33f62 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -16,13 +16,13 @@ NodeItem::NodeItem(MaterialX::GraphElement *graph) { } -void NodeItem::set_input(const std::string &name, const NodeItem &item) +void NodeItem::set_input(const std::string &name, const NodeItem &res) { - if (item.value) { - set_input(name, item.value); + if (res.value) { + set_input(name, res.value); } else { - set_input(name, item.node); + set_input(name, res.node); } } @@ -66,47 +66,51 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, { } -NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type) +NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type, bool accessory) { - NodeItem item(graph); - item.node = graph->addNode(mx_category, MaterialX::createValidName(node->name), mx_type); - return item; + NodeItem res = empty_value(); + res.node = graph->addNode(mx_category, + accessory ? MaterialX::EMPTY_STRING : + MaterialX::createValidName(node->name), + mx_type); + return res; } NodeItem NodeParser::get_input_default(const std::string &name) { + NodeItem res = empty_value(); + const bNodeSocket &socket = node->input_by_identifier(name); - NodeItem item(graph); switch (socket.type) { case SOCK_FLOAT: { float v = socket.default_value_typed()->value; - item.value = MaterialX::Value::createValue(v); + res.value = MaterialX::Value::createValue(v); } break; case SOCK_VECTOR: { const float *v = socket.default_value_typed()->value; - item.value = MaterialX::Value::createValue( + res.value = MaterialX::Value::createValue( MaterialX::Vector3(v[0], v[1], v[2])); } break; case SOCK_RGBA: { const float *v = socket.default_value_typed()->value; - item.value = MaterialX::Value::createValue( + res.value = MaterialX::Value::createValue( MaterialX::Color4(v[0], v[1], v[2], v[3])); } break; default: { // TODO log warn } } - return item; + return res; } NodeItem NodeParser::get_input_link(const std::string &name) { - NodeItem item(graph); + NodeItem res = empty_value(); const bNodeLink *link = node->input_by_identifier(name).link; if (!link->is_used()) { - return item; + return res; } const bNode *in_node = link->fromnode; @@ -115,7 +119,7 @@ NodeItem NodeParser::get_input_link(const std::string &name) while (in_node->type == NODE_REROUTE) { link = in_node->input_socket(0).link; if (!link->is_used()) { - return item; + return res; } in_node = link->fromnode; } @@ -131,20 +135,25 @@ NodeItem NodeParser::get_input_link(const std::string &name) break; default: // TODO: warning log - return item; + return res; } - item = parser->compute(); - return item; + res = parser->compute(); + return res; } NodeItem NodeParser::get_input_value(const std::string &name) { - NodeItem item = get_input_link(name); - if (!item) { - item = get_input_value(name); + NodeItem res = get_input_link(name); + if (!res) { + res = get_input_value(name); } - return item; + return res; +} + +NodeItem NodeParser::empty_value() +{ + return NodeItem(graph); } std::string NodeParser::get_mx_type(const bNodeSocket *sock) diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 68ffe1555257..0e16730577f8 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -56,10 +56,13 @@ class NodeParser { virtual NodeItem compute() = 0; protected: - NodeItem create_node(const std::string &mx_category, const std::string &mx_type); + NodeItem create_node(const std::string &mx_category, + const std::string &mx_type, + bool accessory = false); NodeItem get_input_default(const std::string &name); NodeItem get_input_link(const std::string &name); NodeItem get_input_value(const std::string &name); + NodeItem empty_value(); std::string get_mx_type(const bNodeSocket *sock); }; diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index e84dd8928e4a..6b3a4584ec53 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -6,21 +6,15 @@ namespace blender::nodes::materialx { -OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) - : NodeParser(doc, depsgraph, material, node) +NodeItem OutputMaterialNodeParser::compute() { - matx_node = doc->addNode("surfacematerial", MaterialX::createValidName(node->name), "material"); -} - -MaterialX::NodePtr OutputMaterialNodeParser::compute() -{ - const char *matx_socket = "surfaceshader"; - const bNodeSocket sock = node->input_by_identifier("Surface"); - get_input_link_node(&sock, matx_node, matx_socket); - return matx_node; + NodeItem node = empty_value(); + NodeItem surface = get_input_link("Surface"); + if (surface) { + node = create_node("surfacematerial", "material"); + node.set_input("surfaceshader", surface); + } + return node; } } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.h b/source/blender/nodes/shader/materialx/nodes/output_material.h index 468a61d67373..0701c0769e8a 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.h +++ b/source/blender/nodes/shader/materialx/nodes/output_material.h @@ -10,11 +10,8 @@ namespace blender::nodes::materialx { class OutputMaterialNodeParser : public NodeParser { public: - OutputMaterialNodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); - MaterialX::NodePtr compute() override; + using NodeParser::NodeParser; + NodeItem compute() override; }; } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc index 5b64b4016b7b..ace39d0ce720 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -11,18 +11,8 @@ namespace blender::nodes::materialx { -const MaterialX::Color3 TexImageNodeParser::texture_error_color_{1.0, 0.0, 1.0}; -TexImageNodeParser::TexImageNodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node) - : NodeParser(doc, depsgraph, material, node) -{ - matx_node = doc->addNode("image", MaterialX::createValidName(node->name), "color3"); -} - -MaterialX::NodePtr TexImageNodeParser::compute() +NodeItem TexImageNodeParser::compute() { Image *image = (Image *)node->id; NodeTexImage *tex = static_cast(node->storage); @@ -34,12 +24,12 @@ MaterialX::NodePtr TexImageNodeParser::compute() #ifdef WITH_HYDRA image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser); #endif - MaterialX::NodePtr uv_node = doc->addNode("texcoord", MaterialX::EMPTY_STRING, "vector2"); - matx_node->addInput("file", "filename")->setValue(image_path); - matx_node->addInput("texcoord", "vector2")->setNodeName(uv_node->getName()); - - return matx_node; + NodeItem texcoord = create_node("texcoord", "vector2", true); + NodeItem res = create_node("image", "color3"); + res.set_input("file", image_path, "filename"); + res.set_input("texcoord", texcoord); + return res; } } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.h b/source/blender/nodes/shader/materialx/nodes/tex_image.h index 4370594b2694..cc6f962ef88a 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.h +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.h @@ -9,16 +9,9 @@ namespace blender::nodes::materialx { class TexImageNodeParser : public NodeParser { - protected: - /* Following Cycles color for wrong Texture nodes. */ - static const MaterialX::Color3 texture_error_color_; - public: - TexImageNodeParser(MaterialX::DocumentPtr doc, - const Depsgraph *depsgraph, - const Material *material, - const bNode *node); - MaterialX::NodePtr compute() override; + using NodeParser::NodeParser; + NodeItem compute() override; }; } // namespace blender::nodes::materialx -- 2.30.2 From 7b314dd80a4bc27f43961ccebe765b6a61b6f3c0 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 26 Aug 2023 04:42:52 +0300 Subject: [PATCH 09/11] Fixed bugs --- .../nodes/shader/materialx/nodes/node_parser.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 48722fb33f62..30ed755a8568 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -21,7 +21,7 @@ void NodeItem::set_input(const std::string &name, const NodeItem &res) if (res.value) { set_input(name, res.value); } - else { + else if (res.node) { set_input(name, res.node); } } @@ -55,7 +55,7 @@ void NodeItem::set_input(const std::string &name, const MaterialX::NodePtr node) NodeItem::operator bool() const { - return !value && !node; + return value || node; } NodeParser::NodeParser(MaterialX::GraphElement *graph, @@ -109,7 +109,7 @@ NodeItem NodeParser::get_input_link(const std::string &name) NodeItem res = empty_value(); const bNodeLink *link = node->input_by_identifier(name).link; - if (!link->is_used()) { + if (!(link && link->is_used())) { return res; } @@ -118,7 +118,7 @@ NodeItem NodeParser::get_input_link(const std::string &name) /* Passing NODE_REROUTE nodes */ while (in_node->type == NODE_REROUTE) { link = in_node->input_socket(0).link; - if (!link->is_used()) { + if (!(link && link->is_used())) { return res; } in_node = link->fromnode; @@ -146,7 +146,7 @@ NodeItem NodeParser::get_input_value(const std::string &name) { NodeItem res = get_input_link(name); if (!res) { - res = get_input_value(name); + res = get_input_default(name); } return res; } -- 2.30.2 From 6d44247d7d852e0fb4ae1920ef974d99568b377f Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 26 Aug 2023 11:17:50 +0300 Subject: [PATCH 10/11] Export fixes. Code cleanup --- .../nodes/shader/materialx/material.cc | 3 + .../shader/materialx/nodes/bsdf_principled.cc | 134 ++---------------- .../shader/materialx/nodes/node_parser.cc | 77 +++++----- .../shader/materialx/nodes/node_parser.h | 4 +- .../nodes/shader/materialx/nodes/tex_image.cc | 1 - 5 files changed, 50 insertions(+), 169 deletions(-) diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 3c37aa50371d..8e3350199e85 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -6,6 +6,7 @@ #include "nodes/output_material.h" #include +#include #include "NOD_shader.h" @@ -46,6 +47,8 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater else { create_standard_surface(doc.get(), material); } + std::string str = MaterialX::writeToXmlString(doc); + printf("\nMaterial: %s\n%s\n", material->id.name, str.c_str()); return doc; } diff --git a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc index e49b0cb156bd..e00bbce4d598 100644 --- a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc @@ -10,8 +10,7 @@ namespace blender::nodes::materialx { NodeItem BSDFPrincipledNodeParser::compute() { - auto enabled = [](NodeItem &val) -> bool - { + auto enabled = [](NodeItem &val) -> bool { if (val.node) { return true; } @@ -21,6 +20,10 @@ NodeItem BSDFPrincipledNodeParser::compute() if (val.value->isA()) { return val.value->asA() != 0.0f; } + if (val.value->isA()) { + auto c = val.value->asA(); + return c[0] != 0.0f || c[1] != 0.0f || c[2] != 0.0f; + } return true; }; @@ -47,8 +50,8 @@ NodeItem BSDFPrincipledNodeParser::compute() /* TODO: use Specular Tint input */ anisotropic = get_input_value("Anisotropic"); if (enabled(anisotropic)) { - anisotropic_rotation = get_input_value("Anisotropic Rotation"); - // anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0) + anisotropic_rotation = get_input_value("Anisotropic Rotation"); + // anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0) } } @@ -84,7 +87,7 @@ NodeItem BSDFPrincipledNodeParser::compute() /* Creating standard_surface */ NodeItem res = create_node("standard_surface", "surfaceshader"); res.set_input("base", 1.0, "float"); - res.set_input("base_color", base_color); + res.set_input("base_color", base_color.to_color3()); res.set_input("diffuse_roughness", roughness); res.set_input("normal", normal); res.set_input("tangent", tangent); @@ -95,7 +98,7 @@ NodeItem BSDFPrincipledNodeParser::compute() if (enabled(specular)) { res.set_input("specular", specular); - res.set_input("specular_color", base_color); + res.set_input("specular_color", base_color.to_color3()); res.set_input("specular_roughness", roughness); res.set_input("specular_IOR", ior); res.set_input("specular_anisotropy", anisotropic); @@ -104,7 +107,7 @@ NodeItem BSDFPrincipledNodeParser::compute() if (enabled(transmission)) { res.set_input("transmission", transmission); - res.set_input("transmission_color", base_color); + res.set_input("transmission_color", base_color.to_color3()); res.set_input("transmission_extra_roughness", transmission_roughness); } @@ -117,13 +120,13 @@ NodeItem BSDFPrincipledNodeParser::compute() if (enabled(sheen)) { res.set_input("sheen", sheen); - res.set_input("sheen_color", base_color); + res.set_input("sheen_color", base_color.to_color3()); res.set_input("sheen_roughness", roughness); } if (enabled(clearcoat)) { res.set_input("coat", clearcoat); - res.set_input("coat_color", base_color); + res.set_input("coat_color", base_color.to_color3()); res.set_input("coat_roughness", clearcoat_roughness); res.set_input("coat_IOR", ior); res.set_input("coat_anisotropy", anisotropic); @@ -137,119 +140,6 @@ NodeItem BSDFPrincipledNodeParser::compute() } return res; - - - -// -// MaterialX::Color3 default_white_color = MaterialX::Color3(1.0, 1.0, 1.0); -//#pragma region get inputs -// const bNodeSocket base_color_socket = res->input_by_identifier("Base Color"); -// const char *matx_input = "base_color"; -// if (base_color_socket.link) { -// get_input_link_node(&base_color_socket, matx_node, matx_input); -// } -// else { -// const float *base_color = base_color_socket.default_value_typed()->value; -// matx_node->addInput("base_color", "color3") -// ->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2])); -// } -// -// const float *base_color = -// res->input_by_identifier("Base Color").default_value_typed()->value; -// const float subsurface = -// res->input_by_identifier("Subsurface").default_value_typed()->value; -// -// const float *subsurface_radius = res->input_by_identifier("Subsurface Radius") -// .default_value_typed() -// ->value; -// const float *subsurface_color = res->input_by_identifier("Subsurface Color") -// .default_value_typed() -// ->value; -// const float metallic = -// res->input_by_identifier("Metallic").default_value_typed()->value; -// const float specular = -// res->input_by_identifier("Specular").default_value_typed()->value; -// const float roughness = -// res->input_by_identifier("Roughness").default_value_typed()->value; -// const float anisotropic = -// res->input_by_identifier("Anisotropic").default_value_typed()->value; -// const float anisotropic_rot = res->input_by_identifier("Anisotropic Rotation") -// .default_value_typed() -// ->value; -// const float sheen = -// res->input_by_identifier("Sheen").default_value_typed()->value; -// const float clearcoat = -// res->input_by_identifier("Clearcoat").default_value_typed()->value; -// const float clearcoat_roughness = res->input_by_identifier("Clearcoat Roughness") -// .default_value_typed() -// ->value; -// const float IOR = -// res->input_by_identifier("IOR").default_value_typed()->value; -// const float transmission = res->input_by_identifier("Transmission") -// .default_value_typed() -// ->value; -// const float *emission = -// res->input_by_identifier("Emission").default_value_typed()->value; -// const float emission_str = res->input_by_identifier("Emission Strength") -// .default_value_typed() -// ->value; -// const float *normal = -// res->input_by_identifier("Normal").default_value_typed()->value; -// const float *clearcoat_normal = res->input_by_identifier("Clearcoat Normal") -// .default_value_typed() -// ->value; -// const float *tangent = -// res->input_by_identifier("Tangent").default_value_typed()->value; -//#pragma endregion get inputs -// -//#pragma region set inputs -// matx_node->addInput("base", "float")->setValue(1.0); -// matx_node->addInput("diffuse_roughness", "float")->setValue(roughness); -// matx_node->addInput("normal", "vector3") -// ->setValue(MaterialX::Vector3(normal[0], normal[1], normal[2])); -// matx_node->addInput("tangent", "vector3") -// ->setValue(MaterialX::Vector3(tangent[0], tangent[1], tangent[2])); -// -// matx_node->addInput("metalness", "float")->setValue(metallic); -// -// matx_node->addInput("specular", "float")->setValue(specular); -// matx_node->addInput("specular_color", "color3")->setValue(default_white_color); -// matx_node->addInput("specular_roughness", "float")->setValue(roughness); -// matx_node->addInput("specular_IOR", "float")->setValue(IOR); -// matx_node->addInput("specular_anisotropy", "float")->setValue(anisotropic); -// matx_node->addInput("specular_rotation", "float")->setValue(anisotropic_rot); -// -// matx_node->addInput("transmission", "float")->setValue(transmission); -// matx_node->addInput("transmission_color", "color3")->setValue(default_white_color); -// matx_node->addInput("transmission_extra_roughness", "float")->setValue(roughness); -// -// matx_node->addInput("subsurface", "float")->setValue(subsurface); -// matx_node->addInput("subsurface_color", "color3") -// ->setValue(MaterialX::Color3(subsurface_color[0], subsurface_color[1], subsurface_color[2])); -// matx_node->addInput("subsurface_radius", "color3") -// ->setValue( -// MaterialX::Color3(subsurface_radius[0], subsurface_radius[1], subsurface_radius[2])); -// matx_node->addInput("subsurface_anisotropy", "float")->setValue(anisotropic); -// -// matx_node->addInput("sheen", "float")->setValue(sheen); -// matx_node->addInput("sheen_color", "color3")->setValue(default_white_color); -// matx_node->addInput("sheen_roughness", "float")->setValue(roughness); -// -// matx_node->addInput("coat", "float")->setValue(clearcoat); -// matx_node->addInput("coat_color", "color3")->setValue(default_white_color); -// matx_node->addInput("coat_roughness", "float")->setValue(clearcoat_roughness); -// matx_node->addInput("coat_IOR", "float")->setValue(IOR); -// matx_node->addInput("coat_anisotropy", "float")->setValue(anisotropic); -// matx_node->addInput("coat_rotation", "float")->setValue(anisotropic_rot); -// matx_node->addInput("coat_normal", "vector3") -// ->setValue( -// MaterialX::Vector3(clearcoat_normal[0], clearcoat_normal[1], clearcoat_normal[2])); -// -// matx_node->addInput("emission", "float")->setValue(emission_str); -// matx_node->addInput("emission_color", "color3") -// ->setValue(MaterialX::Color3(emission[0], emission[1], emission[2])); -//#pragma endregion set inputs -// return matx_node; } } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 30ed755a8568..11da5c8158a7 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -11,18 +11,15 @@ namespace blender::nodes::materialx { -NodeItem::NodeItem(MaterialX::GraphElement *graph) - : graph_(graph) -{ -} +NodeItem::NodeItem(MaterialX::GraphElement *graph) : graph_(graph) {} -void NodeItem::set_input(const std::string &name, const NodeItem &res) +void NodeItem::set_input(const std::string &name, const NodeItem &item) { - if (res.value) { - set_input(name, res.value); + if (item.value) { + set_input(name, item.value); } - else if (res.node) { - set_input(name, res.node); + else if (item.node) { + set_input(name, item.node); } } @@ -50,7 +47,7 @@ void NodeItem::set_input(const std::string &name, const MaterialX::ValuePtr valu void NodeItem::set_input(const std::string &name, const MaterialX::NodePtr node) { - node->setConnectedNode(name, node); + this->node->setConnectedNode(name, node); } NodeItem::operator bool() const @@ -58,6 +55,29 @@ NodeItem::operator bool() const return value || node; } +NodeItem NodeItem::to_color3() +{ + NodeItem res(graph_); + if (value) { + if (value->isA()) { + float v = value->asA(); + res.value = MaterialX::Value::createValue(MaterialX::Color3(v, v, v)); + } + else if (value->isA()) { + res.value = value; + } + else if (value->isA()) { + auto c = value->asA(); + res.value = MaterialX::Value::createValue( + MaterialX::Color3(c[0], c[1], c[2])); + } + } + else if (node) { + res.node = node; + } + return res; +} + NodeParser::NodeParser(MaterialX::GraphElement *graph, const Depsgraph *depsgraph, const Material *material, @@ -66,7 +86,9 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, { } -NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type, bool accessory) +NodeItem NodeParser::create_node(const std::string &mx_category, + const std::string &mx_type, + bool accessory) { NodeItem res = empty_value(); res.node = graph->addNode(mx_category, @@ -103,7 +125,6 @@ NodeItem NodeParser::get_input_default(const std::string &name) return res; } - NodeItem NodeParser::get_input_link(const std::string &name) { NodeItem res = empty_value(); @@ -156,36 +177,4 @@ NodeItem NodeParser::empty_value() return NodeItem(graph); } -std::string NodeParser::get_mx_type(const bNodeSocket *sock) -{ - std::string mx_sock_type; - switch (sock->type) { - case (SOCK_FLOAT): { - mx_sock_type = "float"; - break; - } - case (SOCK_VECTOR): { - mx_sock_type = "vector3"; - break; - } - case (SOCK_RGBA): { - mx_sock_type = "color3"; - break; - } - case (SOCK_BOOLEAN): { - mx_sock_type = "boolean"; - break; - } - case (SOCK_INT): { - mx_sock_type = "integer"; - break; - } - case (SOCK_SHADER): { - mx_sock_type = "surfaceshader"; - break; - } - } - return mx_sock_type; -} - } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 0e16730577f8..5a021e8bb33f 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -31,6 +31,8 @@ class NodeItem { void set_input(const std::string &name, const MaterialX::NodePtr node); operator bool() const; + + NodeItem to_color3(); }; template @@ -63,8 +65,6 @@ class NodeParser { NodeItem get_input_link(const std::string &name); NodeItem get_input_value(const std::string &name); NodeItem empty_value(); - - std::string get_mx_type(const bNodeSocket *sock); }; } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc index ace39d0ce720..3d1a0423c9fa 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -11,7 +11,6 @@ namespace blender::nodes::materialx { - NodeItem TexImageNodeParser::compute() { Image *image = (Image *)node->id; -- 2.30.2 From 3e9fd8e94ad563d1e2b96e370d1d0ea8abc6b292 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 28 Aug 2023 13:26:32 +0300 Subject: [PATCH 11/11] rename --- source/blender/io/usd/hydra/material.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index 8478cf0d55b9..dca349b2b009 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -95,8 +95,8 @@ void MaterialData::init() pxr::HdMaterialNetworkMap network_map; - if (pxr::UsdShadeShader mtlx_surface = usd_material.ComputeSurfaceSource(contextVector)) { - pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(mtlx_surface.GetPrim(), + if (pxr::UsdShadeShader surface = usd_material.ComputeSurfaceSource(contextVector)) { + pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(surface.GetPrim(), pxr::HdMaterialTerminalTokens->surface, shaderSourceTypes, contextVector, -- 2.30.2