forked from blender/blender
matx-code-improvements #8
@ -162,6 +162,7 @@ if(WITH_MATERIALX)
|
||||
materialx/material.h
|
||||
materialx/nodes/node_item.h
|
||||
materialx/nodes/node_parser.h
|
||||
materialx/nodes/output_material.h
|
||||
)
|
||||
list(APPEND LIB
|
||||
MaterialXCore
|
||||
|
@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "material.h"
|
||||
#include "nodes/node_parser.h"
|
||||
#include "nodes/output_material.h"
|
||||
|
||||
#include <MaterialXFormat/XmlIo.h>
|
||||
|
||||
@ -45,6 +45,7 @@ static void create_standard_surface(MaterialX::GraphElement *graph, Material *ma
|
||||
|
||||
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material)
|
||||
{
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name);
|
||||
MaterialX::DocumentPtr doc = MaterialX::createDocument();
|
||||
if (material->use_nodes) {
|
||||
export_nodegraph(doc.get(), depsgraph, material);
|
||||
@ -52,8 +53,11 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
||||
else {
|
||||
create_standard_surface(doc.get(), material);
|
||||
}
|
||||
std::string str = MaterialX::writeToXmlString(doc);
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Material: %s\n%s", material->id.name, str.c_str());
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER,
|
||||
2,
|
||||
"Material: %s\n%s",
|
||||
material->id.name,
|
||||
MaterialX::writeToXmlString(doc).c_str());
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
||||
NodeItem tangent = get_input_link("Tangent");
|
||||
|
||||
/* Creating standard_surface */
|
||||
NodeItem res = create_node("standard_surface", "surfaceshader", false);
|
||||
NodeItem res = create_node("standard_surface", "surfaceshader");
|
||||
res.set_input("base", 1.0, "float");
|
||||
res.set_input("base_color", base_color.to_color3());
|
||||
res.set_input("diffuse_roughness", roughness);
|
||||
@ -90,7 +90,9 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
||||
res.set_input("specular_IOR", ior);
|
||||
if (anisotropic) {
|
||||
res.set_input("specular_anisotropy", anisotropic);
|
||||
res.set_input("specular_rotation", anisotropic_rotation);
|
||||
if (anisotropic_rotation) {
|
||||
res.set_input("specular_rotation", anisotropic_rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,20 +12,16 @@ namespace blender::nodes::materialx {
|
||||
NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node)
|
||||
: graph(graph), depsgraph(depsgraph), material(material), node(node)
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out)
|
||||
: graph(graph), depsgraph(depsgraph), material(material), node(node), socket_out(socket_out)
|
||||
{
|
||||
}
|
||||
|
||||
NodeItem NodeParser::create_node(const std::string &mx_category,
|
||||
const std::string &mx_type,
|
||||
bool noname)
|
||||
NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type)
|
||||
{
|
||||
NodeItem res = empty();
|
||||
res.node = graph->addNode(mx_category,
|
||||
noname ? MaterialX::EMPTY_STRING :
|
||||
MaterialX::createValidName(node->name),
|
||||
mx_type);
|
||||
res.node = graph->addNode(mx_category, MaterialX::EMPTY_STRING, mx_type);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -98,50 +94,43 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
|
||||
return res;
|
||||
}
|
||||
|
||||
const bNode *in_node = link->fromnode;
|
||||
const bNode *from_node = link->fromnode;
|
||||
|
||||
/* Passing NODE_REROUTE nodes */
|
||||
while (in_node->type == NODE_REROUTE) {
|
||||
link = in_node->input_socket(0).link;
|
||||
while (from_node->type == NODE_REROUTE) {
|
||||
link = from_node->input_socket(0).link;
|
||||
if (!(link && link->is_used())) {
|
||||
return res;
|
||||
}
|
||||
in_node = link->fromnode;
|
||||
from_node = link->fromnode;
|
||||
}
|
||||
|
||||
/* Getting required NodeParser object */
|
||||
#define CASE_NODE_TYPE(type, T) \
|
||||
case type: \
|
||||
parser = std::make_unique<T>(graph, depsgraph, material, from_node, link->fromsock); \
|
||||
break;
|
||||
|
||||
std::unique_ptr<NodeParser> parser;
|
||||
switch (in_node->typeinfo->type) {
|
||||
case SH_NODE_BSDF_PRINCIPLED:
|
||||
parser = std::make_unique<BSDFPrincipledNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_INVERT:
|
||||
parser = std::make_unique<InvertNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_MATH:
|
||||
parser = std::make_unique<MathNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_MIX_RGB_LEGACY:
|
||||
parser = std::make_unique<MixRGBNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_TEX_IMAGE:
|
||||
parser = std::make_unique<TexImageNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_TEX_ENVIRONMENT:
|
||||
parser = std::make_unique<TexEnvironmentNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_TEX_NOISE:
|
||||
parser = std::make_unique<TexNoiseNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
case SH_NODE_TEX_CHECKER:
|
||||
parser = std::make_unique<TexCheckerNodeParser>(graph, depsgraph, material, in_node);
|
||||
break;
|
||||
switch (from_node->typeinfo->type) {
|
||||
CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_INVERT, InvertNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_MATH, MathNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_MIX_RGB_LEGACY, MixRGBNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_TEX_CHECKER, TexCheckerNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_TEX_ENVIRONMENT, TexEnvironmentNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_TEX_IMAGE, TexImageNodeParser)
|
||||
CASE_NODE_TYPE(SH_NODE_TEX_NOISE, TexNoiseNodeParser)
|
||||
|
||||
default:
|
||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported node: %s (%d)", in_node->name, in_node->type);
|
||||
CLOG_WARN(LOG_MATERIALX_SHADER,
|
||||
"Unsupported node: %s [%d]",
|
||||
from_node->name,
|
||||
from_node->typeinfo->type);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = parser->compute();
|
||||
res = parser->compute_full();
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -154,4 +143,14 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket)
|
||||
return res;
|
||||
}
|
||||
|
||||
NodeItem NodeParser::compute_full()
|
||||
{
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Node: %s [%d]", node->name, node->typeinfo->type);
|
||||
NodeItem res = compute();
|
||||
if (res.node) {
|
||||
res.node->setName(MaterialX::createValidName(std::string(node->name) + "." + socket_out->name));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::materialx
|
||||
|
@ -18,20 +18,19 @@ class NodeParser {
|
||||
const Depsgraph *depsgraph;
|
||||
const Material *material;
|
||||
const bNode *node;
|
||||
const bNodeSocket *socket_out;
|
||||
|
||||
public:
|
||||
NodeParser(MaterialX::GraphElement *graph,
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node);
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out);
|
||||
virtual ~NodeParser() = default;
|
||||
|
||||
virtual NodeItem compute() = 0;
|
||||
|
||||
protected:
|
||||
NodeItem create_node(const std::string &mx_category,
|
||||
const std::string &mx_type,
|
||||
bool noname = true);
|
||||
NodeItem create_node(const std::string &mx_category, const std::string &mx_type);
|
||||
NodeItem get_input_default(const std::string &name);
|
||||
NodeItem get_input_default(int index);
|
||||
NodeItem get_input_link(const std::string &name);
|
||||
@ -45,6 +44,7 @@ class NodeParser {
|
||||
NodeItem get_input_default(const bNodeSocket &socket);
|
||||
NodeItem get_input_link(const bNodeSocket &socket);
|
||||
NodeItem get_input_value(const bNodeSocket &socket);
|
||||
NodeItem compute_full();
|
||||
};
|
||||
|
||||
template<class T> NodeItem NodeParser::value(const T &data) const
|
||||
@ -63,7 +63,6 @@ DECLARE_PARSER(BSDFPrincipledNodeParser)
|
||||
DECLARE_PARSER(InvertNodeParser)
|
||||
DECLARE_PARSER(MathNodeParser)
|
||||
DECLARE_PARSER(MixRGBNodeParser)
|
||||
DECLARE_PARSER(OutputMaterialNodeParser)
|
||||
DECLARE_PARSER(TexCheckerNodeParser)
|
||||
DECLARE_PARSER(TexEnvironmentNodeParser)
|
||||
DECLARE_PARSER(TexImageNodeParser)
|
||||
|
@ -2,19 +2,31 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "node_parser.h"
|
||||
#include "output_material.h"
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node)
|
||||
: NodeParser(graph, depsgraph, material, node, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NodeItem OutputMaterialNodeParser::compute()
|
||||
{
|
||||
NodeItem node = empty();
|
||||
NodeItem surface = get_input_link("Surface");
|
||||
if (surface) {
|
||||
node = create_node("surfacematerial", "material", false);
|
||||
node = create_node("surfacematerial", "material");
|
||||
node.set_input("surfaceshader", surface);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
NodeItem OutputMaterialNodeParser::compute_default()
|
||||
{
|
||||
return empty();
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::materialx
|
||||
|
@ -0,0 +1,22 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_parser.h"
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
class OutputMaterialNodeParser : public NodeParser {
|
||||
public:
|
||||
OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node);
|
||||
|
||||
NodeItem compute() override;
|
||||
NodeItem compute_default();
|
||||
};
|
||||
|
||||
} // namespace blender::nodes::materialx
|
@ -42,7 +42,7 @@ NodeItem TexCheckerNodeParser::compute()
|
||||
NodeItem ifequal =
|
||||
(modulo_x.floor() + modulo_y.floor()).if_else("==", value(1.0f), value(0.0f), value(1.0f));
|
||||
|
||||
NodeItem res = create_node("mix", "color3", false);
|
||||
NodeItem res = create_node("mix", "color3");
|
||||
res.set_input("fg", color1.to_color3());
|
||||
res.set_input("bg", color2.to_color3());
|
||||
res.set_input("mix", ifequal);
|
||||
|
@ -24,7 +24,7 @@ NodeItem TexEnvironmentNodeParser::compute()
|
||||
#endif
|
||||
|
||||
NodeItem texcoord = create_node("texcoord", "vector2");
|
||||
NodeItem res = create_node("image", "color3", false);
|
||||
NodeItem res = create_node("image", "color3");
|
||||
res.set_input("file", image_path, "filename");
|
||||
res.set_input("texcoord", texcoord);
|
||||
return res;
|
||||
|
@ -24,7 +24,7 @@ NodeItem TexImageNodeParser::compute()
|
||||
#endif
|
||||
|
||||
NodeItem texcoord = create_node("texcoord", "vector2");
|
||||
NodeItem res = create_node("image", "color3", false);
|
||||
NodeItem res = create_node("image", "color3");
|
||||
res.set_input("file", image_path, "filename");
|
||||
res.set_input("texcoord", texcoord);
|
||||
return res;
|
||||
|
@ -18,7 +18,7 @@ NodeItem TexNoiseNodeParser::compute()
|
||||
|
||||
NodeItem texcoord = create_node("position", "vector3");
|
||||
|
||||
NodeItem res = create_node("fractal3d", "color3", false);
|
||||
NodeItem res = create_node("fractal3d", "color3");
|
||||
res.set_input("position", texcoord * scale);
|
||||
res.set_input("octaves", detail);
|
||||
res.set_input("lacunarity", lacunarity);
|
||||
|
Loading…
Reference in New Issue
Block a user