forked from blender/blender
Move the MaterialX export code into the existing shader node files #18
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user