Add basic supported nodes #1

Merged
Bogdan Nagirniak merged 5 commits from add-basic-nodes into matx-export-material 2023-08-24 10:23:00 +02:00
11 changed files with 356 additions and 9 deletions

View File

@ -21,6 +21,12 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
if(WITH_HYDRA)
list(APPEND INC
../../io/usd
)
add_definitions(-DWITH_HYDRA)
endif()
set(SRC
nodes/node_shader_add_shader.cc
@ -138,8 +144,16 @@ if(WITH_MATERIALX)
list(APPEND LIB MaterialXCore)
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()

View File

@ -3,11 +3,23 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "material.h"
#include "nodes/material_output.h"
#include <MaterialXCore/Node.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(
@ -17,16 +29,17 @@ 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());
->setNodeName(standard_surface->getName());
}
MaterialX::DocumentPtr export_to_materialx(Material* material) {
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material)
{
MaterialX::DocumentPtr doc = MaterialX::createDocument();
if (material->use_nodes) {
;
export_nodegraph(doc, depsgraph, material);
}
else {
create_standard_surface(doc, material);
@ -34,5 +47,4 @@ MaterialX::DocumentPtr export_to_materialx(Material* material) {
return doc;
}
} // namespace blender::materialx
} // namespace blender::nodes::materialx

View File

@ -6,11 +6,11 @@
#include <MaterialXCore/Document.h>
#include "DEG_depsgraph.h"
#include "DNA_material_types.h"
namespace blender::nodes::materialx {
MaterialX::DocumentPtr export_to_materialx(Material *material);
} // namespace blender::materialx
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material);
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,43 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node.h"
#include "image.h"
#include "hydra/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()
{
Image *image = (Image *)node->id;
NodeTexImage *tex = static_cast<NodeTexImage *>(node->storage);
Scene *scene = DEG_get_input_scene(depsgraph);
Main *bmain = DEG_get_bmain(depsgraph);
std::string image_path;
#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;
}
} // namespace blender::nodes::materialx

View 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

View File

@ -0,0 +1,35 @@
/* 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, depsgraph, material, inode);
surface_node.convert();
matx_node->addInput("surfaceshader", "surfaceshader")->setNodeName(inode->name);
}
}
return matx_node;
}
} // namespace blender::nodes::materialx

View File

@ -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

View File

@ -0,0 +1,17 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node.h"
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)
{
}
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,33 @@
/* 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;
};
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,126 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "principled_bsdf.h"
#include <BKE_node_runtime.hh>
namespace blender::nodes::materialx {
const MaterialX::Color3 MaterialXPrincipledBSDFNode::default_white_color_{1.0, 1.0, 1.0};
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()
{
#pragma region get inputs
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("base_color", "color3")
->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2]));
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

View File

@ -0,0 +1,23 @@
/* 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 {
protected:
static const MaterialX::Color3 default_white_color_;
public:
MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc,
const Depsgraph *depsgraph,
const Material *material,
const bNode *node);
MaterialX::NodePtr convert() override;
};
} // namespace blender::nodes::materialx