forked from blender/blender
Create parsing system that converts supported nodes and ignores unsupported #2
@ -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"))) {
|
||||
|
@ -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()
|
||||
|
||||
|
@ -3,12 +3,24 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "material.h"
|
||||
#include "nodes/material_output.h"
|
||||
|
||||
#include <MaterialXCore/Node.h>
|
||||
#include <MaterialXFormat/XmlIo.h>
|
||||
|
||||
#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
|
||||
|
@ -6,13 +6,13 @@
|
||||
|
||||
#include <MaterialXCore/Document.h>
|
||||
|
||||
#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
|
||||
|
41
source/blender/nodes/shader/materialx/nodes/image.cc
Normal file
41
source/blender/nodes/shader/materialx/nodes/image.cc
Normal file
@ -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<NodeTexImage *>(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";
|
||||
BogdanNagirniak marked this conversation as resolved
Outdated
|
||||
#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
|
24
source/blender/nodes/shader/materialx/nodes/image.h
Normal file
24
source/blender/nodes/shader/materialx/nodes/image.h
Normal file
@ -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
|
@ -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
|
@ -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
|
71
source/blender/nodes/shader/materialx/nodes/node.cc
Normal file
71
source/blender/nodes/shader/materialx/nodes/node.cc
Normal file
@ -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 <BKE_node_runtime.hh>
|
||||
|
||||
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
|
38
source/blender/nodes/shader/materialx/nodes/node.h
Normal file
38
source/blender/nodes/shader/materialx/nodes/node.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <MaterialXCore/Document.h>
|
||||
|
||||
#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
|
136
source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc
Normal file
136
source/blender/nodes/shader/materialx/nodes/principled_bsdf.cc
Normal file
@ -0,0 +1,136 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "principled_bsdf.h"
|
||||
|
||||
#include <BKE_node_runtime.hh>
|
||||
#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<bNodeSocketValueRGBA>()->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<bNodeSocketValueRGBA>()->value;
|
||||
const float subsurface =
|
||||
node->input_by_identifier("Subsurface").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
|
||||
const float *subsurface_radius = node->input_by_identifier("Subsurface Radius")
|
||||
.default_value_typed<bNodeSocketValueVector>()
|
||||
->value;
|
||||
const float *subsurface_color = node->input_by_identifier("Subsurface Color")
|
||||
.default_value_typed<bNodeSocketValueRGBA>()
|
||||
->value;
|
||||
const float metallic =
|
||||
node->input_by_identifier("Metallic").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float specular =
|
||||
node->input_by_identifier("Specular").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float roughness =
|
||||
node->input_by_identifier("Roughness").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float anisotropic =
|
||||
node->input_by_identifier("Anisotropic").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float anisotropic_rot = node->input_by_identifier("Anisotropic Rotation")
|
||||
.default_value_typed<bNodeSocketValueFloat>()
|
||||
->value;
|
||||
const float sheen =
|
||||
node->input_by_identifier("Sheen").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float clearcoat =
|
||||
node->input_by_identifier("Clearcoat").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float clearcoat_roughness = node->input_by_identifier("Clearcoat Roughness")
|
||||
.default_value_typed<bNodeSocketValueFloat>()
|
||||
->value;
|
||||
const float IOR =
|
||||
node->input_by_identifier("IOR").default_value_typed<bNodeSocketValueFloat>()->value;
|
||||
const float transmission = node->input_by_identifier("Transmission")
|
||||
.default_value_typed<bNodeSocketValueFloat>()
|
||||
->value;
|
||||
const float *emission =
|
||||
node->input_by_identifier("Emission").default_value_typed<bNodeSocketValueRGBA>()->value;
|
||||
const float emission_str = node->input_by_identifier("Emission Strength")
|
||||
.default_value_typed<bNodeSocketValueFloat>()
|
||||
->value;
|
||||
const float *normal =
|
||||
node->input_by_identifier("Normal").default_value_typed<bNodeSocketValueVector>()->value;
|
||||
const float *clearcoat_normal = node->input_by_identifier("Clearcoat Normal")
|
||||
.default_value_typed<bNodeSocketValueVector>()
|
||||
->value;
|
||||
const float *tangent =
|
||||
node->input_by_identifier("Tangent").default_value_typed<bNodeSocketValueVector>()->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
|
@ -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
|
Loading…
Reference in New Issue
Block a user
this needs to be removed