forked from blender/blender
Export to MatX various Texture nodes #5
@ -156,6 +156,9 @@ if(WITH_MATERIALX)
|
|||||||
materialx/nodes/node_parser.cc
|
materialx/nodes/node_parser.cc
|
||||||
materialx/nodes/output_material.cc
|
materialx/nodes/output_material.cc
|
||||||
materialx/nodes/tex_image.cc
|
materialx/nodes/tex_image.cc
|
||||||
|
materialx/nodes/tex_environment.cc
|
||||||
|
materialx/nodes/tex_noise.cc
|
||||||
|
materialx/nodes/tex_checker.cc
|
||||||
|
|
||||||
materialx/material.h
|
materialx/material.h
|
||||||
materialx/nodes/node_item.h
|
materialx/nodes/node_item.h
|
||||||
|
@ -68,7 +68,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
NodeItem tangent = get_input_link("Tangent");
|
NodeItem tangent = get_input_link("Tangent");
|
||||||
|
|
||||||
/* Creating standard_surface */
|
/* Creating standard_surface */
|
||||||
NodeItem res = create_node("standard_surface", "surfaceshader");
|
NodeItem res = create_node("standard_surface", "surfaceshader", false);
|
||||||
res.set_input("base", 1.0, "float");
|
res.set_input("base", 1.0, "float");
|
||||||
res.set_input("base_color", base_color.to_color3());
|
res.set_input("base_color", base_color.to_color3());
|
||||||
res.set_input("diffuse_roughness", roughness);
|
res.set_input("diffuse_roughness", roughness);
|
||||||
|
@ -16,13 +16,15 @@ NodeItem NodeItem::empty() const
|
|||||||
return NodeItem(graph_);
|
return NodeItem(graph_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeItem::set_input(const std::string &name, const NodeItem &item)
|
void NodeItem::set_input(const std::string &name,
|
||||||
|
const NodeItem &item,
|
||||||
|
const std::string &output_name)
|
||||||
{
|
{
|
||||||
if (item.value) {
|
if (item.value) {
|
||||||
set_input(name, item.value);
|
set_input(name, item.value);
|
||||||
}
|
}
|
||||||
else if (item.node) {
|
else if (item.node) {
|
||||||
set_input(name, item.node);
|
set_input(name, item.node, output_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +60,19 @@ void NodeItem::set_input(const std::string &name, const MaterialX::ValuePtr valu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeItem::set_input(const std::string &name, const MaterialX::NodePtr node)
|
void NodeItem::set_input(const std::string &name,
|
||||||
|
const MaterialX::NodePtr node,
|
||||||
|
const std::string &output_name)
|
||||||
{
|
{
|
||||||
this->node->setConnectedNode(name, node);
|
this->node->setConnectedNode(name, node);
|
||||||
|
if (output_name != "") {
|
||||||
|
this->node->setConnectedOutput("in1", node->getOutput(output_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeItem::add_output(const std::string &name, const std::string &mx_type)
|
||||||
|
{
|
||||||
|
node->addOutput(name, mx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem::operator bool() const
|
NodeItem::operator bool() const
|
||||||
@ -550,7 +562,9 @@ MaterialX::ValuePtr NodeItem::float_to_type(float v, std::string mx_type)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeItem::adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, std::string &mx_type)
|
bool NodeItem::adjust_types(MaterialX::ValuePtr &val1,
|
||||||
|
MaterialX::ValuePtr &val2,
|
||||||
|
std::string &mx_type)
|
||||||
{
|
{
|
||||||
std::string t1 = val1->getTypeString();
|
std::string t1 = val1->getTypeString();
|
||||||
std::string t2 = val2->getTypeString();
|
std::string t2 = val2->getTypeString();
|
||||||
|
@ -25,9 +25,14 @@ class NodeItem {
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void set_input(const std::string &name, const T &value, const std::string &mx_type);
|
void set_input(const std::string &name, const T &value, const std::string &mx_type);
|
||||||
void set_input(const std::string &name, const NodeItem &item);
|
void set_input(const std::string &name,
|
||||||
|
const NodeItem &item,
|
||||||
|
const std::string &output_name = "");
|
||||||
void set_input(const std::string &name, const MaterialX::ValuePtr value);
|
void set_input(const std::string &name, const MaterialX::ValuePtr value);
|
||||||
void set_input(const std::string &name, const MaterialX::NodePtr node);
|
void set_input(const std::string &name,
|
||||||
|
const MaterialX::NodePtr node,
|
||||||
|
const std::string &output_name = "");
|
||||||
|
void add_output(const std::string &name, const std::string &mx_type);
|
||||||
|
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
NodeItem operator+(const NodeItem &other) const;
|
NodeItem operator+(const NodeItem &other) const;
|
||||||
@ -79,7 +84,9 @@ class NodeItem {
|
|||||||
std::function<float(float, float)> func) const;
|
std::function<float(float, float)> func) const;
|
||||||
static MaterialX::ValuePtr float_to_type(float v, std::string mx_type);
|
static MaterialX::ValuePtr float_to_type(float v, std::string mx_type);
|
||||||
/* Functions for adjusting values to make equal types */
|
/* Functions for adjusting values to make equal types */
|
||||||
static bool adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, std::string &mx_type);
|
static bool adjust_types(MaterialX::ValuePtr &val1,
|
||||||
|
MaterialX::ValuePtr &val2,
|
||||||
|
std::string &mx_type);
|
||||||
static bool adjust_types(NodeItem &val1, NodeItem &val2, std::string &mx_type);
|
static bool adjust_types(NodeItem &val1, NodeItem &val2, std::string &mx_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,12 +18,12 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
|||||||
|
|
||||||
NodeItem NodeParser::create_node(const std::string &mx_category,
|
NodeItem NodeParser::create_node(const std::string &mx_category,
|
||||||
const std::string &mx_type,
|
const std::string &mx_type,
|
||||||
bool accessory)
|
bool noname)
|
||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
res.node = graph->addNode(mx_category,
|
res.node = graph->addNode(mx_category,
|
||||||
accessory ? MaterialX::EMPTY_STRING :
|
noname ? MaterialX::EMPTY_STRING :
|
||||||
MaterialX::createValidName(node->name),
|
MaterialX::createValidName(node->name),
|
||||||
mx_type);
|
mx_type);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
|
|||||||
|
|
||||||
/* Getting required NodeParser object */
|
/* Getting required NodeParser object */
|
||||||
std::unique_ptr<NodeParser> parser;
|
std::unique_ptr<NodeParser> parser;
|
||||||
switch (in_node->type) {
|
switch (in_node->typeinfo->type) {
|
||||||
case SH_NODE_BSDF_PRINCIPLED:
|
case SH_NODE_BSDF_PRINCIPLED:
|
||||||
parser = std::make_unique<BSDFPrincipledNodeParser>(graph, depsgraph, material, in_node);
|
parser = std::make_unique<BSDFPrincipledNodeParser>(graph, depsgraph, material, in_node);
|
||||||
break;
|
break;
|
||||||
@ -126,6 +126,15 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
|
|||||||
case SH_NODE_TEX_IMAGE:
|
case SH_NODE_TEX_IMAGE:
|
||||||
parser = std::make_unique<TexImageNodeParser>(graph, depsgraph, material, in_node);
|
parser = std::make_unique<TexImageNodeParser>(graph, depsgraph, material, in_node);
|
||||||
break;
|
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;
|
||||||
default:
|
default:
|
||||||
// TODO: warning log
|
// TODO: warning log
|
||||||
return res;
|
return res;
|
||||||
|
@ -31,7 +31,7 @@ class NodeParser {
|
|||||||
protected:
|
protected:
|
||||||
NodeItem create_node(const std::string &mx_category,
|
NodeItem create_node(const std::string &mx_category,
|
||||||
const std::string &mx_type,
|
const std::string &mx_type,
|
||||||
bool accessory = false);
|
bool noname = true);
|
||||||
NodeItem get_input_default(const std::string &name);
|
NodeItem get_input_default(const std::string &name);
|
||||||
NodeItem get_input_default(int index);
|
NodeItem get_input_default(int index);
|
||||||
NodeItem get_input_link(const std::string &name);
|
NodeItem get_input_link(const std::string &name);
|
||||||
@ -64,6 +64,9 @@ DECLARE_PARSER(InvertNodeParser)
|
|||||||
DECLARE_PARSER(MathNodeParser)
|
DECLARE_PARSER(MathNodeParser)
|
||||||
DECLARE_PARSER(MixRGBNodeParser)
|
DECLARE_PARSER(MixRGBNodeParser)
|
||||||
DECLARE_PARSER(OutputMaterialNodeParser)
|
DECLARE_PARSER(OutputMaterialNodeParser)
|
||||||
|
DECLARE_PARSER(TexCheckerNodeParser)
|
||||||
|
DECLARE_PARSER(TexEnvironmentNodeParser)
|
||||||
DECLARE_PARSER(TexImageNodeParser)
|
DECLARE_PARSER(TexImageNodeParser)
|
||||||
|
DECLARE_PARSER(TexNoiseNodeParser)
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -11,7 +11,7 @@ NodeItem OutputMaterialNodeParser::compute()
|
|||||||
NodeItem node = empty();
|
NodeItem node = empty();
|
||||||
NodeItem surface = get_input_link("Surface");
|
NodeItem surface = get_input_link("Surface");
|
||||||
if (surface) {
|
if (surface) {
|
||||||
node = create_node("surfacematerial", "material");
|
node = create_node("surfacematerial", "material", false);
|
||||||
node.set_input("surfaceshader", surface);
|
node.set_input("surfaceshader", surface);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
52
source/blender/nodes/shader/materialx/nodes/tex_checker.cc
Normal file
52
source/blender/nodes/shader/materialx/nodes/tex_checker.cc
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem TexCheckerNodeParser::compute()
|
||||||
|
{
|
||||||
|
NodeItem scale = get_input_value("Scale");
|
||||||
|
NodeItem color1 = get_input_value("Color1");
|
||||||
|
NodeItem color2 = get_input_value("Color2");
|
||||||
|
|
||||||
|
if (scale.value && scale.type() == "float") {
|
||||||
|
float v = scale.value->asA<float>();
|
||||||
|
scale = value(MaterialX::Vector2(v, v));
|
||||||
|
}
|
||||||
|
/* Modifier to follow Cycles result */
|
||||||
|
scale = scale * value(4.0f);
|
||||||
|
|
||||||
|
NodeItem texcoord = create_node("texcoord", "vector2");
|
||||||
|
NodeItem place2d = create_node("place2d", "vector2");
|
||||||
|
place2d.set_input("texcoord", texcoord * scale);
|
||||||
|
|
||||||
|
/* TODO: fix offset:
|
||||||
|
* place2d.set_input("offset", offset); */
|
||||||
|
|
||||||
|
NodeItem separate = create_node("separate2", "multioutput");
|
||||||
|
separate.set_input("in", place2d);
|
||||||
|
separate.add_output("outx", "float");
|
||||||
|
separate.add_output("outy", "float");
|
||||||
|
|
||||||
|
NodeItem modulo_x = create_node("modulo", "float");
|
||||||
|
modulo_x.set_input("in1", separate, "outx");
|
||||||
|
modulo_x.set_input("in2", value(2.0f));
|
||||||
|
|
||||||
|
NodeItem modulo_y = create_node("modulo", "float");
|
||||||
|
modulo_y.set_input("in1", separate, "outy");
|
||||||
|
modulo_y.set_input("in2", value(2.0f));
|
||||||
|
|
||||||
|
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);
|
||||||
|
res.set_input("fg", color1.to_color3());
|
||||||
|
res.set_input("bg", color2.to_color3());
|
||||||
|
res.set_input("mix", ifequal);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -0,0 +1,33 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
#include "hydra/image.h"
|
||||||
|
|
||||||
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem TexEnvironmentNodeParser::compute()
|
||||||
|
{
|
||||||
|
Image *image = (Image *)node->id;
|
||||||
|
NodeTexEnvironment *tex = static_cast<NodeTexEnvironment *>(node->storage);
|
||||||
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
|
Main *bmain = DEG_get_bmain(depsgraph);
|
||||||
|
std::string image_path;
|
||||||
|
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
|
||||||
|
* pretty general code, so could be moved from bf_usd project. */
|
||||||
|
#ifdef WITH_HYDRA
|
||||||
|
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NodeItem texcoord = create_node("texcoord", "vector2");
|
||||||
|
NodeItem res = create_node("image", "color3", false);
|
||||||
|
res.set_input("file", image_path, "filename");
|
||||||
|
res.set_input("texcoord", texcoord);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -17,14 +17,14 @@ NodeItem TexImageNodeParser::compute()
|
|||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
Main *bmain = DEG_get_bmain(depsgraph);
|
Main *bmain = DEG_get_bmain(depsgraph);
|
||||||
std::string image_path;
|
std::string image_path;
|
||||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contain
|
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
|
||||||
* pretty general code, so could be moved from bf_usd project. */
|
* pretty general code, so could be moved from bf_usd project. */
|
||||||
#ifdef WITH_HYDRA
|
#ifdef WITH_HYDRA
|
||||||
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeItem texcoord = create_node("texcoord", "vector2", true);
|
NodeItem texcoord = create_node("texcoord", "vector2");
|
||||||
NodeItem res = create_node("image", "color3");
|
NodeItem res = create_node("image", "color3", false);
|
||||||
res.set_input("file", image_path, "filename");
|
res.set_input("file", image_path, "filename");
|
||||||
res.set_input("texcoord", texcoord);
|
res.set_input("texcoord", texcoord);
|
||||||
return res;
|
return res;
|
||||||
|
28
source/blender/nodes/shader/materialx/nodes/tex_noise.cc
Normal file
28
source/blender/nodes/shader/materialx/nodes/tex_noise.cc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem TexNoiseNodeParser::compute()
|
||||||
|
{
|
||||||
|
NodeItem scale = get_input_value("Scale");
|
||||||
|
NodeItem detail = get_input_value("Detail");
|
||||||
|
NodeItem lacunarity = get_input_value("Lacunarity");
|
||||||
|
|
||||||
|
if (detail.value && detail.type() == "float") {
|
||||||
|
detail = value(int(detail.value->asA<float>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem texcoord = create_node("position", "vector3");
|
||||||
|
|
||||||
|
NodeItem res = create_node("fractal3d", "color3", false);
|
||||||
|
res.set_input("position", texcoord * scale);
|
||||||
|
res.set_input("octaves", detail);
|
||||||
|
res.set_input("lacunarity", lacunarity);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
Loading…
Reference in New Issue
Block a user