Implement export of Shader BSDF nodes #13

Merged
Bogdan Nagirniak merged 13 commits from BogdanNagirniak/blender:matx-shader-bsdf-nodes into matx-export-material 2023-09-07 11:22:44 +02:00
7 changed files with 57 additions and 43 deletions
Showing only changes of commit a4086cd79a - Show all commits

View File

@ -50,9 +50,9 @@ NodeItem BSDFPrincipledNodeParser::compute_surface()
NodeItem alpha = get_input_value("Alpha", NodeItem::Type::Float); NodeItem alpha = get_input_value("Alpha", NodeItem::Type::Float);
// transparency = 1.0 - alpha // transparency = 1.0 - alpha
NodeItem normal = get_input_link("Normal"); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem clearcoat_normal = get_input_link("Clearcoat Normal"); NodeItem clearcoat_normal = get_input_link("Clearcoat Normal", NodeItem::Type::Vector3);
NodeItem tangent = get_input_link("Tangent"); NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
/* Creating standard_surface */ /* Creating standard_surface */
NodeItem res = create_node("standard_surface", "surfaceshader"); NodeItem res = create_node("standard_surface", "surfaceshader");

View File

@ -14,7 +14,7 @@ NodeItem MathNodeParser::compute()
NodeItem res = empty(); NodeItem res = empty();
/* Single operand operations */ /* Single operand operations */
NodeItem x = get_input_value(0, NodeItem::Type::Empty); NodeItem x = get_input_value(0, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_MATH_SINE: case NODE_MATH_SINE:
res = x.sin(); res = x.sin();
@ -82,7 +82,7 @@ NodeItem MathNodeParser::compute()
default: { default: {
/* 2-operand operations */ /* 2-operand operations */
NodeItem y = get_input_value(1, NodeItem::Type::Empty); NodeItem y = get_input_value(1, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_MATH_ADD: case NODE_MATH_ADD:
res = x + y; res = x + y;
@ -132,7 +132,7 @@ NodeItem MathNodeParser::compute()
default: { default: {
/* 3-operand operations */ /* 3-operand operations */
NodeItem z = get_input_value(2, NodeItem::Type::Empty); NodeItem z = get_input_value(2, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_MATH_WRAP: case NODE_MATH_WRAP:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op); CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);

View File

@ -328,7 +328,7 @@ NodeItem NodeItem::extract(const int index) const
NodeItem NodeItem::convert(Type to_type) const NodeItem NodeItem::convert(Type to_type) const
{ {
Type from_type = type(); Type from_type = type();
if (from_type == to_type) { if (from_type == Type::Empty || from_type == to_type || to_type == Type::Any) {
return *this; return *this;
} }
if (!is_arithmetic(from_type) || !is_arithmetic(to_type)) { if (!is_arithmetic(from_type) || !is_arithmetic(to_type)) {

View File

@ -46,34 +46,34 @@ NodeItem NodeParser::create_node(const std::string &mx_category, const std::stri
return res; return res;
} }
NodeItem NodeParser::get_input_default(const std::string &name) NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)
{ {
return get_input_default(node_->input_by_identifier(name)); return get_input_default(node_->input_by_identifier(name), to_type);
} }
NodeItem NodeParser::get_input_default(int index) NodeItem NodeParser::get_input_default(int index, NodeItem::Type to_type)
{ {
return get_input_default(node_->input_socket(index)); return get_input_default(node_->input_socket(index), to_type);
} }
NodeItem NodeParser::get_input_link(const std::string &name) NodeItem NodeParser::get_input_link(const std::string &name, NodeItem::Type to_type)
{ {
return get_input_link(node_->input_by_identifier(name)); return get_input_link(node_->input_by_identifier(name), to_type);
} }
NodeItem NodeParser::get_input_link(int index) NodeItem NodeParser::get_input_link(int index, NodeItem::Type to_type)
{ {
return get_input_link(node_->input_socket(index)); return get_input_link(node_->input_socket(index), to_type);
} }
NodeItem NodeParser::get_input_value(const std::string &name, const NodeItem::Type type) NodeItem NodeParser::get_input_value(const std::string &name, NodeItem::Type to_type)
{ {
return get_input_value(node_->input_by_identifier(name), type); return get_input_value(node_->input_by_identifier(name), to_type);
} }
NodeItem NodeParser::get_input_value(int index, const NodeItem::Type type) NodeItem NodeParser::get_input_value(int index, NodeItem::Type to_type)
{ {
return get_input_value(node_->input_socket(index), type); return get_input_value(node_->input_socket(index), to_type);
} }
NodeItem NodeParser::empty() const NodeItem NodeParser::empty() const
@ -81,7 +81,7 @@ NodeItem NodeParser::empty() const
return NodeItem(graph_); return NodeItem(graph_);
} }
NodeItem NodeParser::get_input_default(const bNodeSocket &socket) NodeItem NodeParser::get_input_default(const bNodeSocket &socket, NodeItem::Type to_type)
{ {
NodeItem res = empty(); NodeItem res = empty();
switch (socket.type) { switch (socket.type) {
@ -106,10 +106,10 @@ NodeItem NodeParser::get_input_default(const bNodeSocket &socket)
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported socket type: %d", socket.type); CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported socket type: %d", socket.type);
} }
} }
return res; return res.convert(to_type);
} }
NodeItem NodeParser::get_input_link(const bNodeSocket &socket) NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to_type)
{ {
NodeItem res = empty(); NodeItem res = empty();
@ -170,16 +170,16 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
/* Computing */ /* Computing */
res = parser->compute_full(); res = parser->compute_full();
return res; return res.convert(to_type);
} }
NodeItem NodeParser::get_input_value(const bNodeSocket &socket, const NodeItem::Type type) NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type to_type)
{ {
NodeItem res = get_input_link(socket); NodeItem res = get_input_link(socket, to_type);
if (!res) { if (!res) {
res = get_input_default(socket); res = get_input_default(socket, to_type);
} }
return type == NodeItem::Type::Empty ? res : res.convert(type); return res;
} }
ShaderNodeParser::ShaderNodeParser(MaterialX::GraphElement *graph, ShaderNodeParser::ShaderNodeParser(MaterialX::GraphElement *graph,
@ -207,6 +207,21 @@ NodeItem ShaderNodeParser::compute()
return empty(); return empty();
} }
NodeItem ShaderNodeParser::compute_full()
{
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] - %s",
node_->name,
node_->typeinfo->type,
NodeItem::type(shader_type_).c_str());
NodeItem res = compute();
if (res.node) {
res.node->setName(node_name());
}
return res;
}
std::string ShaderNodeParser::node_name() std::string ShaderNodeParser::node_name()
{ {
std::string name = NodeParser::node_name(); std::string name = NodeParser::node_name();

View File

@ -31,24 +31,22 @@ class NodeParser {
virtual NodeItem compute() = 0; virtual NodeItem compute() = 0;
protected: protected:
NodeItem compute_full(); virtual NodeItem compute_full();
virtual std::string node_name(); virtual std::string node_name();
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);
NodeItem get_input_default(const std::string &name); NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_default(int index); NodeItem get_input_default(int index, NodeItem::Type to_type);
NodeItem get_input_link(const std::string &name); NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_link(int index); NodeItem get_input_link(int index, NodeItem::Type to_type);
NodeItem get_input_value(const std::string &name, NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
const NodeItem::Type type); NodeItem get_input_value(int index, NodeItem::Type to_type);
NodeItem get_input_value(int index, const NodeItem::Type type);
NodeItem empty() const; NodeItem empty() const;
template<class T> NodeItem value(const T &data) const; template<class T> NodeItem value(const T &data) const;
private: private:
NodeItem get_input_default(const bNodeSocket &socket); NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_link(const bNodeSocket &socket); NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_value(const bNodeSocket &socket, NodeItem get_input_value(const bNodeSocket &socket, NodeItem::Type to_type);
const NodeItem::Type type);
}; };
class ShaderNodeParser : public NodeParser { class ShaderNodeParser : public NodeParser {
@ -69,6 +67,7 @@ class ShaderNodeParser : public NodeParser {
virtual NodeItem compute_surface() = 0; virtual NodeItem compute_surface() = 0;
protected: protected:
NodeItem compute_full() override;
std::string node_name() override; std::string node_name() override;
NodeItem get_input_shader(const std::string &name, NodeItem::Type shader_type); NodeItem get_input_shader(const std::string &name, NodeItem::Type shader_type);
NodeItem get_input_shader(int index, NodeItem::Type shader_type); NodeItem get_input_shader(int index, NodeItem::Type shader_type);

View File

@ -8,7 +8,7 @@ namespace blender::nodes::materialx {
NodeItem TexCheckerNodeParser::compute() NodeItem TexCheckerNodeParser::compute()
{ {
NodeItem vector = get_input_link("Vector"); NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
NodeItem color1 = get_input_value("Color1", NodeItem::Type::Color3); NodeItem color1 = get_input_value("Color1", NodeItem::Type::Color3);
NodeItem color2 = get_input_value("Color2", NodeItem::Type::Color3); NodeItem color2 = get_input_value("Color2", NodeItem::Type::Color3);
NodeItem scale = get_input_value("Scale", NodeItem::Type::Float); NodeItem scale = get_input_value("Scale", NodeItem::Type::Float);

View File

@ -14,7 +14,7 @@ NodeItem VectorMathNodeParser::compute()
NodeItem res = empty(); NodeItem res = empty();
/* Single operand operations */ /* Single operand operations */
NodeItem x = get_input_value(0, NodeItem::Type::Empty); NodeItem x = get_input_value(0, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_VECTOR_MATH_SINE: case NODE_VECTOR_MATH_SINE:
res = x.sin(); res = x.sin();
@ -46,7 +46,7 @@ NodeItem VectorMathNodeParser::compute()
default: { default: {
/* 2-operand operations */ /* 2-operand operations */
NodeItem y = get_input_value(1, NodeItem::Type::Empty); NodeItem y = get_input_value(1, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_VECTOR_MATH_ADD: case NODE_VECTOR_MATH_ADD:
res = x + y; res = x + y;
@ -93,7 +93,7 @@ NodeItem VectorMathNodeParser::compute()
default: { default: {
/* 3-operand operations */ /* 3-operand operations */
NodeItem z = get_input_value(2, NodeItem::Type::Empty); NodeItem z = get_input_value(2, NodeItem::Type::Any);
switch (op) { switch (op) {
case NODE_VECTOR_MATH_MULTIPLY_ADD: case NODE_VECTOR_MATH_MULTIPLY_ADD:
res = x * y + z; res = x * y + z;