Move the MaterialX export code into the existing shader node files #18

Merged
Bogdan Nagirniak merged 14 commits from BogdanNagirniak/blender:matx-move-code into matx-export-material 2023-09-12 13:55:27 +02:00
4 changed files with 118 additions and 30 deletions
Showing only changes of commit 5a7005c2a4 - Show all commits

View File

@ -164,6 +164,11 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
from_node = link->fromnode;
}
if (from_node->typeinfo->materialx_fn) {
NodeParserData data = {graph_, depsgraph_, material_, to_type, empty()};
from_node->typeinfo->materialx_fn(&data, const_cast<bNode *>(from_node), link->fromsock);
return data.result;
}
/* Creating required NodeParser object */
std::unique_ptr<NodeParser> parser;
@ -239,14 +244,14 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type t
return res;
}
NodeItem NodeParser::get_input_shader(const std::string &name, NodeItem::Type shader_type)
NodeItem NodeParser::get_input_shader(const std::string &name, NodeItem::Type to_type)
{
return get_input_link(node_->input_by_identifier(name), shader_type);
return get_input_link(node_->input_by_identifier(name), to_type);
}
NodeItem NodeParser::get_input_shader(int index, NodeItem::Type shader_type)
NodeItem NodeParser::get_input_shader(int index, NodeItem::Type to_type)
{
return get_input_link(node_->input_socket(index), shader_type);
return get_input_link(node_->input_socket(index), to_type);
}
} // namespace blender::nodes::materialx

View File

@ -27,7 +27,7 @@ class NodeParser {
const Material *material,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type shader_type);
NodeItem::Type to_type);
virtual ~NodeParser() = default;
virtual NodeItem compute() = 0;
@ -42,8 +42,8 @@ class NodeParser {
NodeItem get_input_link(int index, NodeItem::Type to_type);
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_value(int index, NodeItem::Type to_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(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_shader(int index, NodeItem::Type to_type);
NodeItem empty() const;
template<class T> NodeItem val(const T &data) const;
NodeItem texcoord_node();
@ -107,39 +107,33 @@ DECLARE_NODE_PARSER(EmissionNodeParser)
DECLARE_NODE_PARSER(MixShaderNodeParser)
DECLARE_NODE_PARSER(SubsurfaceScatteringNodeParser)
struct NodeParserData {
MaterialX::GraphElement *graph;
const Depsgraph *depsgraph;
const Material *material;
NodeItem::Type shader_type;
NodeItem::Type to_type;
NodeItem result;
};
template<class T>
void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *out)
{
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data);
T parser(d->graph, d->depsgraph, d->material, node, out, d->shader_type);
d->result = parser.compute_full();
}
#define NODE_SHADER_MATERIALX_BEGIN \
class MaterialXNodeParser : public materialx::NodeParser { \
public: \
using materialx::NodeParser::NodeParser; \
materialx::NodeItem compute() override \
class MaterialXNodeParser : public materialx::NodeParser { \
public: \
using materialx::NodeParser::NodeParser; \
materialx::NodeItem compute() override; \
}; \
\
materialx::NodeItem MaterialXNodeParser::compute() \
{ \
using NodeItem = materialx::NodeItem;
#define NODE_SHADER_MATERIALX_END \
} \
}; \
\
void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *out) \
{ \
materialx::node_shader_materialx<MaterialXNodeParser>(data, node, out); \
}
void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *out) \
{ \
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
d->result = MaterialXNodeParser(d->graph, d->depsgraph, d->material, node, out, d->to_type) \
.compute_full(); \
}
} // namespace blender::nodes::materialx

View File

@ -4,8 +4,8 @@
#include "BLI_string.h"
#include "node_shader_util.hh"
#include "../materialx/nodes/node_parser.h"
#include "node_shader_util.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
@ -256,7 +256,94 @@ static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
NODE_SHADER_MATERIALX_BEGIN
{
return empty();
if (to_type_ != NodeItem::Type::SurfaceShader) {
/* TODO: implement for BSDF and EDF */
return empty();
}
NodeItem base_color = get_input_value("Base Color", NodeItem::Type::Color3);
NodeItem subsurface = get_input_value("Subsurface", NodeItem::Type::Float);
NodeItem subsurface_radius = get_input_value("Subsurface Radius", NodeItem::Type::Color3);
NodeItem subsurface_color = get_input_value("Subsurface Color", NodeItem::Type::Color3);
NodeItem metallic = get_input_value("Metallic", NodeItem::Type::Float);
NodeItem specular = get_input_value("Specular", NodeItem::Type::Float);
// NodeItem specular_tint = get_input_value("Specular Tint");
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
/* TODO: use Specular Tint input */
NodeItem anisotropic = get_input_value("Anisotropic", NodeItem::Type::Float);
NodeItem anisotropic_rotation = get_input_value("Anisotropic Rotation", NodeItem::Type::Float);
// anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0)
NodeItem sheen = get_input_value("Sheen", NodeItem::Type::Float);
// sheen_tint = get_input_value("Sheen Tint");
NodeItem clearcoat = get_input_value("Clearcoat", NodeItem::Type::Float);
NodeItem clearcoat_roughness = get_input_value("Clearcoat Roughness", NodeItem::Type::Float);
NodeItem ior = get_input_value("IOR", NodeItem::Type::Float);
NodeItem transmission = get_input_value("Transmission", NodeItem::Type::Float);
NodeItem emission = get_input_value("Emission", NodeItem::Type::Color3);
NodeItem emission_strength = get_input_value("Emission Strength", NodeItem::Type::Float);
NodeItem alpha = get_input_value("Alpha", NodeItem::Type::Float);
// transparency = 1.0 - alpha
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem clearcoat_normal = get_input_link("Clearcoat Normal", NodeItem::Type::Vector3);
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
/* Creating standard_surface */
NodeItem res = create_node("standard_surface", NodeItem::Type::SurfaceShader);
res.set_input("base", val(1.0f));
res.set_input("base_color", base_color);
res.set_input("diffuse_roughness", roughness);
if (normal) {
res.set_input("normal", normal);
}
if (tangent) {
res.set_input("tangent", tangent);
}
res.set_input("metalness", metallic);
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);
res.set_input("transmission", transmission);
res.set_input("transmission_color", base_color);
res.set_input("transmission_extra_roughness", roughness);
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);
res.set_input("sheen", sheen);
res.set_input("sheen_color", base_color);
res.set_input("sheen_roughness", roughness);
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);
if (clearcoat_normal) {
res.set_input("coat_normal", clearcoat_normal);
}
res.set_input("emission", emission_strength);
res.set_input("emission_color", emission);
return res;
}
NODE_SHADER_MATERIALX_END

View File

@ -2,8 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_shader_util.hh"
#include "../materialx/nodes/node_parser.h"
#include "node_shader_util.hh"
#include "BKE_scene.h"
@ -45,6 +45,7 @@ static int node_shader_gpu_output_material(GPUMaterial *mat,
}
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem surface = empty();
if (node_) {
NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF);
@ -69,6 +70,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
res.set_input("surfaceshader", surface);
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_output_material_cc