MaterialX: split standard_surface into basic nodes #26

Merged
Bogdan Nagirniak merged 11 commits from matx-principlebsdf-split into matx-export-material 2023-09-21 10:58:14 +02:00
32 changed files with 534 additions and 456 deletions
Showing only changes of commit 49ca0571cd - Show all commits

View File

@ -61,9 +61,7 @@ NodeItem GroupOutputNodeParser::compute()
for (auto socket_in : node_->input_sockets()) { for (auto socket_in : node_->input_sockets()) {
NodeItem value = get_input_value(socket_in->index(), NodeItem::Type::Any); NodeItem value = get_input_value(socket_in->index(), NodeItem::Type::Any);
if (value.value) { if (value.value) {
NodeItem constant = create_node("constant", value.type()); value = create_node("constant", value.type(), {{"value", value}});
constant.set_input("value", value);
value = constant;
} }
values.append(value); values.append(value);
} }
@ -100,7 +98,7 @@ NodeItem GroupOutputNodeParser::compute_full()
res = compute(); res = compute();
return res; return res;
#else #else
return NodeParser::compute_full(); return compute();
#endif #endif
} }
@ -113,9 +111,7 @@ NodeItem GroupInputNodeParser::compute()
} }
if (value.value) { if (value.value) {
NodeItem constant = create_node("constant", value.type()); value = create_node("constant", value.type(), {{"value", value}});
constant.set_input("value", value);
value = constant;
} }
return create_input("input" + std::to_string(socket_out_->index() + 1), value); return create_input("input" + std::to_string(socket_out_->index() + 1), value);
#else #else
@ -144,7 +140,7 @@ NodeItem GroupInputNodeParser::compute_full()
res = compute(); res = compute();
return res; return res;
#else #else
return NodeParser::compute_full(); return compute();
#endif #endif
} }

View File

@ -21,10 +21,12 @@ class DefaultMaterialNodeParser : public NodeParser {
NodeItem compute() override NodeItem compute() override
{ {
NodeItem surface = create_node("standard_surface", NodeItem::Type::SurfaceShader); NodeItem surface = create_node(
surface.set_input("base_color", "standard_surface",
val(MaterialX::Color3(material_->r, material_->g, material_->b))); NodeItem::Type::SurfaceShader,
surface.set_input("diffuse_roughness", val(material_->roughness)); {{"base_color", val(MaterialX::Color3(material_->r, material_->g, material_->b))},
{"diffuse_roughness", val(material_->roughness)}});
if (material_->metallic > 0.0f) { if (material_->metallic > 0.0f) {
surface.set_input("metalness", val(material_->metallic)); surface.set_input("metalness", val(material_->metallic));
} }
@ -34,20 +36,20 @@ class DefaultMaterialNodeParser : public NodeParser {
surface.set_input("specular_roughness", val(material_->roughness)); surface.set_input("specular_roughness", val(material_->roughness));
} }
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material); NodeItem res = create_node(
"surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}});
res.node->setName("Material_Default"); res.node->setName("Material_Default");
res.set_input("surfaceshader", surface);
return res; return res;
} }
NodeItem compute_error() NodeItem compute_error()
{ {
NodeItem surface = create_node("standard_surface", NodeItem::Type::SurfaceShader); NodeItem surface = create_node("standard_surface",
surface.set_input("base_color", val(MaterialX::Color3(1.0f, 0.0f, 1.0f))); NodeItem::Type::SurfaceShader,
{{"base_color", val(MaterialX::Color3(1.0f, 0.0f, 1.0f))}});
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material); NodeItem res = create_node(
"surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}});
res.node->setName("Material_Error"); res.node->setName("Material_Error");
res.set_input("surfaceshader", surface);
return res; return res;
} }
}; };

View File

@ -3,6 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later */ * SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_item.h" #include "node_item.h"
#include "node_parser.h"
#include "BLI_assert.h" #include "BLI_assert.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
@ -120,9 +121,7 @@ NodeItem NodeItem::operator+(const NodeItem &other) const
/* Special case: add BSDF/EDF shaders */ /* Special case: add BSDF/EDF shaders */
NodeItem res = empty(); NodeItem res = empty();
if (other.type() == type) { if (other.type() == type) {
res = create_node("add", type); res = create_node("add", type, {{"in1", *this}, {"in2", other}});
res.set_input("in1", *this);
res.set_input("in2", other);
} }
else { else {
BLI_assert_unreachable(); BLI_assert_unreachable();
@ -151,9 +150,7 @@ NodeItem NodeItem::operator*(const NodeItem &other) const
NodeItem res = empty(); NodeItem res = empty();
Type other_type = other.type(); Type other_type = other.type();
if (ELEM(other_type, Type::Float, Type::Color3)) { if (ELEM(other_type, Type::Float, Type::Color3)) {
res = create_node("multiply", type); res = create_node("multiply", type, {{"in1", *this}, {"in2", other}});
res.set_input("in1", *this);
res.set_input("in2", other);
} }
else { else {
BLI_assert_unreachable(); BLI_assert_unreachable();
@ -540,8 +537,7 @@ NodeItem NodeItem::convert(Type to_type) const
} }
} }
else { else {
res = create_node("convert", to_type); res = create_node("convert", to_type, {{"in", *this}});
res.set_input("in", *this);
} }
return res; return res;
} }
@ -597,11 +593,8 @@ NodeItem NodeItem::if_else(CompareOp op,
res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2; res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2;
} }
else { else {
res = create_node(category, to_type); res = create_node(
res.set_input("value1", *this); category, to_type, {{"value1", *this}, {"value2", other}, {"in1", item1}, {"in2", item2}});
res.set_input("value2", other);
res.set_input("in1", item1);
res.set_input("in2", item2);
} }
return res; return res;
@ -610,9 +603,7 @@ NodeItem NodeItem::if_else(CompareOp op,
NodeItem NodeItem::extract(const int index) const NodeItem NodeItem::extract(const int index) const
{ {
/* TODO: Add check if (value) { ... } */ /* TODO: Add check if (value) { ... } */
NodeItem res = create_node("extract", Type::Float); NodeItem res = create_node("extract", Type::Float, {{"in", *this}, {"index", val(index)}});
res.set_input("in", *this);
res.set_input("index", val(index));
return res; return res;
} }
@ -635,7 +626,7 @@ NodeItem::Type NodeItem::type() const
return Type::Empty; return Type::Empty;
} }
NodeItem NodeItem::create_node(const std::string &category, NodeItem::Type type) const NodeItem NodeItem::create_node(const std::string &category, Type type) const
{ {
std::string type_str = this->type(type); std::string type_str = this->type(type);
CLOG_INFO(LOG_MATERIALX_SHADER, 2, "<%s type=%s>", category.c_str(), type_str.c_str()); CLOG_INFO(LOG_MATERIALX_SHADER, 2, "<%s type=%s>", category.c_str(), type_str.c_str());
@ -644,6 +635,17 @@ NodeItem NodeItem::create_node(const std::string &category, NodeItem::Type type)
return res; return res;
} }
NodeItem NodeItem::create_node(const std::string &category, Type type, const Inputs &inputs) const
{
NodeItem res = create_node(category, type);
for (auto &it : inputs) {
if (it.second) {
res.set_input(it.first, it.second);
}
}
return res;
}
void NodeItem::set_input(const std::string &in_name, const NodeItem &item) void NodeItem::set_input(const std::string &in_name, const NodeItem &item)
{ {
if (item.value) { if (item.value) {
@ -821,8 +823,7 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function<float(f
type = type == Type::Color3 ? Type::Vector3 : Type::Vector4; type = type == Type::Color3 ? Type::Vector3 : Type::Vector4;
v = v.convert(type); v = v.convert(type);
} }
res = create_node(category, type); res = create_node(category, type, {{"in", v}});
res.set_input("in", v);
} }
return res; return res;
} }
@ -887,9 +888,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
} }
} }
else { else {
res = create_node(category, to_type); res = create_node(category, to_type, {{"in1", item1}, {"in2", item2}});
res.set_input("in1", item1);
res.set_input("in2", item2);
} }
return res; return res;
} }

View File

@ -4,6 +4,8 @@
#pragma once #pragma once
#include <map>
#include <MaterialXCore/Node.h> #include <MaterialXCore/Node.h>
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
@ -13,6 +15,8 @@ namespace blender::nodes::materialx {
* All work should be done via this class instead of using MaterialX API directly. */ * All work should be done via this class instead of using MaterialX API directly. */
class NodeItem { class NodeItem {
public: public:
using Inputs = std::vector<std::pair<std::string, NodeItem>>;
enum class Type { enum class Type {
Any = 0, Any = 0,
Empty, Empty,
@ -106,7 +110,8 @@ class NodeItem {
Type type() const; Type type() const;
/* Node functions */ /* Node functions */
NodeItem create_node(const std::string &category, NodeItem::Type type) const; NodeItem create_node(const std::string &category, Type type) const;
NodeItem create_node(const std::string &category, Type type, const Inputs &inputs) const;
template<class T> void set_input(const std::string &in_name, const T &value, Type in_type); template<class T> void set_input(const std::string &in_name, const T &value, Type in_type);
void set_input(const std::string &in_name, const NodeItem &item); void set_input(const std::string &in_name, const NodeItem &item);
NodeItem add_output(const std::string &out_name, Type out_type); NodeItem add_output(const std::string &out_name, Type out_type);

View File

@ -84,6 +84,13 @@ NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type typ
return empty().create_node(category, type); return empty().create_node(category, type);
} }
NodeItem NodeParser::create_node(const std::string &category,
NodeItem::Type type,
const NodeItem::Inputs &inputs)
{
return empty().create_node(category, type, inputs);
}
NodeItem NodeParser::create_input(const std::string &name, const NodeItem &item) NodeItem NodeParser::create_input(const std::string &name, const NodeItem &item)
{ {
return empty().create_input(name, item); return empty().create_input(name, item);

View File

@ -44,6 +44,9 @@ class NodeParser {
protected: protected:
std::string node_name() const; std::string node_name() const;
NodeItem create_node(const std::string &category, NodeItem::Type type); NodeItem create_node(const std::string &category, NodeItem::Type type);
NodeItem create_node(const std::string &category,
NodeItem::Type type,
const NodeItem::Inputs &inputs);
NodeItem create_input(const std::string &name, const NodeItem &item); NodeItem create_input(const std::string &name, const NodeItem &item);
NodeItem create_output(const std::string &name, const NodeItem &item); NodeItem create_output(const std::string &name, const NodeItem &item);
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type); NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);

View File

@ -45,13 +45,9 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float); NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem res = create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF); return create_node("oren_nayar_diffuse_bsdf",
res.set_input("color", color); NodeItem::Type::BSDF,
res.set_input("roughness", roughness); {{"color", color}, {"roughness", roughness}, {"normal", normal}});
if (normal) {
res.set_input("normal", normal);
}
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -54,35 +54,29 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem ior = get_input_value("IOR", NodeItem::Type::Float); NodeItem ior = get_input_value("IOR", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem dielectric = create_node("dielectric_bsdf", NodeItem::Type::BSDF); NodeItem dielectric = create_node("dielectric_bsdf",
if (normal) { NodeItem::Type::BSDF,
dielectric.set_input("normal", normal); {{"normal", normal},
} {"tint", color},
dielectric.set_input("tint", color); {"roughness", roughness},
dielectric.set_input("roughness", roughness); {"ior", ior},
dielectric.set_input("ior", ior); {"scatter_mode", val(std::string("RT"))}});
dielectric.set_input("scatter_mode", val(std::string("RT")));
NodeItem artistic_ior = create_node("artistic_ior", NodeItem::Type::Multioutput); NodeItem artistic_ior = create_node("artistic_ior",
artistic_ior.set_input("reflectivity", color); NodeItem::Type::Multioutput,
artistic_ior.set_input("edge_color", color); {{"reflectivity", color}, {"edge_color", color}});
NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3); NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3); NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3);
NodeItem conductor = create_node("conductor_bsdf", NodeItem::Type::BSDF); NodeItem conductor = create_node("conductor_bsdf",
if (normal) { NodeItem::Type::BSDF,
conductor.set_input("normal", normal); {{"normal", normal},
} {"ior", ior_out},
conductor.set_input("ior", ior_out); {"extinction", extinction_out},
conductor.set_input("extinction", extinction_out); {"roughness", roughness}});
conductor.set_input("roughness", roughness);
NodeItem res = create_node("mix", NodeItem::Type::BSDF); return create_node(
res.set_input("fg", dielectric); "mix", NodeItem::Type::BSDF, {{"fg", dielectric}, {"bg", conductor}, {"mix", val(0.5f)}});
res.set_input("bg", conductor);
res.set_input("mix", val(0.5f));
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -69,24 +69,19 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3); NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
NodeItem artistic_ior = create_node("artistic_ior", NodeItem::Type::Multioutput); NodeItem artistic_ior = create_node("artistic_ior",
artistic_ior.set_input("reflectivity", color); NodeItem::Type::Multioutput,
artistic_ior.set_input("edge_color", color); {{"reflectivity", color}, {"edge_color", color}});
NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3); NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3); NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3);
NodeItem res = create_node("conductor_bsdf", NodeItem::Type::BSDF); return create_node("conductor_bsdf",
if (normal) { NodeItem::Type::BSDF,
res.set_input("normal", normal); {{"normal", normal},
} {"tangent", tangent},
if (tangent) { {"ior", ior_out},
res.set_input("tangent", tangent); {"extinction", extinction_out},
} {"roughness", roughness}});
res.set_input("ior", ior_out);
res.set_input("extinction", extinction_out);
res.set_input("roughness", roughness);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -303,8 +303,7 @@ NODE_SHADER_MATERIALX_BEGIN
/* TODO: use Specular Tint input */ /* TODO: use Specular Tint input */
NodeItem anisotropic = get_input_value("Anisotropic", NodeItem::Type::Float); NodeItem anisotropic = get_input_value("Anisotropic", NodeItem::Type::Float);
NodeItem anisotropic_rotation = get_input_value("Anisotropic Rotation", NodeItem anisotropic_rotation = get_input_value("Anisotropic Rotation", NodeItem::Type::Float);
NodeItem::Type::Float);
// anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0) // anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0)
NodeItem sheen = get_input_value("Sheen", NodeItem::Type::Float); NodeItem sheen = get_input_value("Sheen", NodeItem::Type::Float);
@ -326,35 +325,36 @@ NODE_SHADER_MATERIALX_BEGIN
subsurface_radius = subsurface_radius * subsurface_scale; subsurface_radius = subsurface_radius * subsurface_scale;
return std::map<std::string, NodeItem> {{"base", val(1.0f)}, return std::map<std::string, NodeItem>{
{"base_color", base_color}, {"base", val(1.0f)},
{"diffuse_roughness", roughness}, {"base_color", base_color},
{"normal", normal}, {"diffuse_roughness", roughness},
{"tangent", tangent}, {"normal", normal},
{"metalness", metallic}, {"tangent", tangent},
{"specular", specular}, {"metalness", metallic},
{"specular_color", base_color}, {"specular", specular},
{"specular_roughness", roughness}, {"specular_color", base_color},
{"specular_IOR", ior}, {"specular_roughness", roughness},
{"specular_anisotropy", anisotropic}, {"specular_IOR", ior},
DagerD marked this conversation as resolved Outdated

Rewrite create_node() with inputs parameter inside function.

Rewrite `create_node()` with `inputs` parameter inside function.
{"specular_rotation", anisotropic_rotation}, {"specular_anisotropy", anisotropic},
{"transmission", transmission}, {"specular_rotation", anisotropic_rotation},
{"transmission_color", base_color}, {"transmission", transmission},
{"transmission_extra_roughness", roughness}, {"transmission_color", base_color},
{"subsurface", subsurface}, {"transmission_extra_roughness", roughness},
{"subsurface_color", base_color}, {"subsurface", subsurface},
{"subsurface_radius", subsurface_radius}, {"subsurface_color", base_color},
{"subsurface_anisotropy", anisotropic}, {"subsurface_radius", subsurface_radius},
{"sheen", sheen}, {"subsurface_anisotropy", anisotropic},
{"sheen_color", base_color}, {"sheen", sheen},
{"sheen_roughness", roughness}, {"sheen_color", base_color},
{"coat", coat}, {"sheen_roughness", roughness},
{"coat_color", base_color}, {"coat", coat},
{"coat_roughness", coat_roughness}, {"coat_color", base_color},
{"coat_IOR", ior}, {"coat_roughness", coat_roughness},
{"coat_anisotropy", anisotropic}, {"coat_IOR", ior},
{"coat_rotation", anisotropic_rotation}, {"coat_anisotropy", anisotropic},
{"coat_normal", coat_normal}, {"coat_rotation", anisotropic_rotation},
{"coat_normal", coat_normal},
}; };
}; };
@ -379,190 +379,265 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem ior = inputs.find("specular_IOR")->second; NodeItem ior = inputs.find("specular_IOR")->second;
NodeItem normal = inputs.find("normal")->second; NodeItem normal = inputs.find("normal")->second;
NodeItem tangent = inputs.find("tangent")->second; NodeItem tangent = inputs.find("tangent")->second;
NodeItem n_main_tangent = empty(); NodeItem n_main_tangent = empty();
if (tangent) { if (tangent) {
NodeItem n_tangent_rotate = create_node("rotate3d", NodeItem::Type::Vector3); NodeItem n_tangent_rotate = create_node("rotate3d",
n_tangent_rotate.set_input("in", tangent); NodeItem::Type::Vector3,
n_tangent_rotate.set_input("amount", rotation * val(360.0f)); {
n_tangent_rotate.set_input("axis", normal); {"in", tangent},
{"amount", rotation * val(360.0f)},
{"axis", normal},
});
NodeItem n_tangent_rotate_normalize = create_node("normalize", NodeItem::Type::Vector3); NodeItem n_tangent_rotate_normalize = create_node(
n_tangent_rotate_normalize.set_input("in", n_tangent_rotate); "normalize", NodeItem::Type::Vector3, {{"in", n_tangent_rotate}});
n_main_tangent = anisotropy.if_else( n_main_tangent = anisotropy.if_else(
NodeItem::CompareOp::Greater, NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
val(0.0f),
n_tangent_rotate_normalize,
tangent);
} }
NodeItem n_coat_roughness_vector = create_node("roughness_anisotropy", NodeItem n_coat_roughness_vector = create_node("roughness_anisotropy",
NodeItem::Type::Vector2); NodeItem::Type::Vector2,
n_coat_roughness_vector.set_input("roughness", roughness); {
n_coat_roughness_vector.set_input("anisotropy", anisotropy); {"roughness", roughness},
{"anisotropy", anisotropy},
});
NodeItem n_coat_bsdf = create_node("dielectric_bsdf", NodeItem::Type::BSDF); NodeItem n_coat_bsdf = create_node("dielectric_bsdf",
n_coat_bsdf.set_input("weight", coat); NodeItem::Type::BSDF,
n_coat_bsdf.set_input("tint", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))); {
n_coat_bsdf.set_input("ior", ior); {"weight", coat},
n_coat_bsdf.set_input("scatter_mode", val(std::string("R"))); {"tint", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
n_coat_bsdf.set_input("roughness", n_coat_roughness_vector); {"ior", ior},
n_coat_bsdf.set_input("normal", normal); {"scatter_mode", val(std::string("R"))},
{"roughness", n_coat_roughness_vector},
{"normal", normal},
});
if (tangent) { if (tangent) {
NodeItem n_coat_tangent_rotate = create_node("rotate3d", NodeItem::Type::Vector3); NodeItem n_coat_tangent_rotate = create_node("rotate3d",
n_coat_tangent_rotate.set_input("in", tangent); NodeItem::Type::Vector3,
n_coat_tangent_rotate.set_input("amount", rotation * val(360.0f)); {
n_coat_tangent_rotate.set_input("axis", normal); {"in", tangent},
{"amount", rotation * val(360.0f)},
{"axis", normal},
});
NodeItem n_coat_tangent_rotate_normalize = create_node("normalize",
NodeItem::Type::Vector3,
{
{"in", n_coat_tangent_rotate},
});
NodeItem n_coat_tangent_rotate_normalize = create_node("normalize", NodeItem::Type::Vector3);
n_coat_tangent_rotate_normalize.set_input("in", n_coat_tangent_rotate);
NodeItem n_coat_tangent = anisotropy.if_else( NodeItem n_coat_tangent = anisotropy.if_else(
NodeItem::CompareOp::Greater, NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
val(0.0f),
n_coat_tangent_rotate_normalize,
tangent);
n_coat_bsdf.set_input("tangent", n_coat_tangent); n_coat_bsdf.set_input("tangent", n_coat_tangent);
} }
NodeItem n_thin_film_bsdf = create_node("thin_film_bsdf", NodeItem::Type::BSDF); NodeItem n_thin_film_bsdf = create_node("thin_film_bsdf",
n_thin_film_bsdf.set_input("thickness", val(0.0f)); NodeItem::Type::BSDF,
n_thin_film_bsdf.set_input("ior", val(1.5f)); {
{"thickness", val(0.0f)},
{"ior", val(1.5f)},
});
NodeItem n_artistic_ior = create_node("artistic_ior",
NodeItem::Type::Multioutput,
{
{"reflectivity", base_color * val(1.0f)},
{"edge_color", base_color * specular},
});
NodeItem n_artistic_ior = create_node("artistic_ior", NodeItem::Type::Multioutput);
n_artistic_ior.set_input("reflectivity", base_color * val(1.0f));
n_artistic_ior.set_input(
"edge_color", base_color * specular);
NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3); NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3); NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3);
NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * roughness;
roughness; NodeItem n_coat_affected_roughness = create_node(
NodeItem n_coat_affected_roughness = create_node("mix", NodeItem::Type::Float); "mix",
n_coat_affected_roughness.set_input("fg", val(1.0f)); NodeItem::Type::Float,
n_coat_affected_roughness.set_input("bg", roughness); {
n_coat_affected_roughness.set_input("mix", n_coat_affect_roughness_multiply2); {"fg", val(1.0f)},
{"bg", roughness},
{"mix", n_coat_affect_roughness_multiply2},
});
NodeItem n_main_roughness = create_node("roughness_anisotropy", NodeItem::Type::Vector2); NodeItem n_main_roughness = create_node("roughness_anisotropy",
n_main_roughness.set_input("roughness", n_coat_affected_roughness); NodeItem::Type::Vector2,
n_main_roughness.set_input("anisotropy", anisotropy); {
{"roughness", n_coat_affected_roughness},
{"anisotropy", anisotropy},
});
NodeItem n_metal_bsdf = create_node("conductor_bsdf", NodeItem::Type::BSDF); NodeItem n_metal_bsdf = create_node("conductor_bsdf",
n_metal_bsdf.set_input("ior", n_ior_out); NodeItem::Type::BSDF,
n_metal_bsdf.set_input("extinction", n_extinction_out); {
n_metal_bsdf.set_input("roughness", n_main_roughness); {"ior", n_ior_out},
n_metal_bsdf.set_input("normal", normal); {"extinction", n_extinction_out},
n_metal_bsdf.set_input("tangent", n_main_tangent); {"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent},
});
NodeItem n_specular_bsdf = create_node("dielectric_bsdf", NodeItem::Type::BSDF); NodeItem n_specular_bsdf = create_node("dielectric_bsdf",
n_specular_bsdf.set_input("weight", specular); NodeItem::Type::BSDF,
n_specular_bsdf.set_input("tint", base_color); {
n_specular_bsdf.set_input("ior", ior); {"weight", specular},
n_specular_bsdf.set_input("scatter_mode", val(std::string("R"))); {"tint", base_color},
n_specular_bsdf.set_input("roughness", n_main_roughness); {"ior", ior},
n_specular_bsdf.set_input("normal", normal); {"scatter_mode", val(std::string("R"))},
n_specular_bsdf.set_input("tangent", n_main_tangent); {"roughness", n_main_roughness},
{"normal", normal},
NodeItem n_coat_affected_transmission_roughness = create_node("mix", NodeItem::Type::Float); {"tangent", n_main_tangent},
n_coat_affected_transmission_roughness.set_input("fg", val(1.0f)); });
n_coat_affected_transmission_roughness.set_input(
"bg",
(roughness + roughness)
.clamp(0.0f, 1.0f));
n_coat_affected_transmission_roughness.set_input("mix", n_coat_affect_roughness_multiply2);
NodeItem n_transmission_roughness = create_node("roughness_anisotropy", NodeItem n_coat_affected_transmission_roughness = create_node(
NodeItem::Type::Vector2); "mix",
n_transmission_roughness.set_input("roughness", n_coat_affected_transmission_roughness); NodeItem::Type::Float,
n_transmission_roughness.set_input("anisotropy", anisotropy); {
{"fg", val(1.0f)},
{"bg", (roughness + roughness).clamp(0.0f, 1.0f)},
{"mix", n_coat_affect_roughness_multiply2},
});
NodeItem n_transmission_roughness = create_node(
"roughness_anisotropy",
NodeItem::Type::Vector2,
{
{"roughness", n_coat_affected_transmission_roughness},
{"anisotropy", anisotropy},
});
NodeItem n_transmission_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{
{"tint", base_color},
{"ior", ior},
{"roughness", n_transmission_roughness},
{"normal", normal},
{"tangent", n_main_tangent},
});
DagerD marked this conversation as resolved Outdated

This node is created in MaterialOutput.
Should be:

if (to_type_ == NodeItem::Type::BSDF) {
<calculate and return only BSDF part>
....
return n_coat_layer; // probably n_coat_layer * n_opacity_luminance
}
else if (to_type_ == NodeItem::Type::EDF) {
<calculate and return only EDF part>
...
return n_emission_edf; // probably n_emission_edf * n_opacity_luminance
}
else if (to_type_ == NodeItem::Type::SurfaceShader) {
<previous implementation>
}
This node is created in MaterialOutput. Should be: ``` if (to_type_ == NodeItem::Type::BSDF) { <calculate and return only BSDF part> .... return n_coat_layer; // probably n_coat_layer * n_opacity_luminance } else if (to_type_ == NodeItem::Type::EDF) { <calculate and return only EDF part> ... return n_emission_edf; // probably n_emission_edf * n_opacity_luminance } else if (to_type_ == NodeItem::Type::SurfaceShader) { <previous implementation> } ```
NodeItem n_transmission_bsdf = create_node("dielectric_bsdf", NodeItem::Type::BSDF);
n_transmission_bsdf.set_input("tint", base_color);
n_transmission_bsdf.set_input("ior", ior);
n_transmission_bsdf.set_input("roughness", n_transmission_roughness);
n_transmission_bsdf.set_input("normal", normal);
n_transmission_bsdf.set_input("tangent", n_main_tangent);
NodeItem n_coat_gamma = coat.clamp(0.0f, 1.0f) * val(0.0f) + val(1.0f); NodeItem n_coat_gamma = coat.clamp(0.0f, 1.0f) * val(0.0f) + val(1.0f);
NodeItem n_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ NodeItem n_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ n_coat_gamma;
n_coat_gamma; NodeItem n_translucent_bsdf = create_node("translucent_bsdf",
NodeItem n_translucent_bsdf = create_node("translucent_bsdf", NodeItem::Type::BSDF); NodeItem::Type::BSDF,
n_translucent_bsdf.set_input("color", n_coat_affected_subsurface_color); {
n_translucent_bsdf.set_input("normal", normal); {"color", n_coat_affected_subsurface_color},
{"normal", normal},
NodeItem n_subsurface_bsdf = create_node("subsurface_bsdf", NodeItem::Type::BSDF); });
n_subsurface_bsdf.set_input("color", n_coat_affected_subsurface_color);
n_subsurface_bsdf.set_input("radius", inputs.find("subsurface_radius")->second);
n_subsurface_bsdf.set_input("anisotropy", anisotropy);
n_subsurface_bsdf.set_input("normal", normal);
NodeItem n_selected_subsurface_bsdf = create_node("mix", NodeItem::Type::BSDF);
n_selected_subsurface_bsdf.set_input("fg", n_translucent_bsdf);
n_selected_subsurface_bsdf.set_input("bg", n_subsurface_bsdf);
n_selected_subsurface_bsdf.set_input("mix", val(0.0f));
NodeItem n_sheen_bsdf = create_node("sheen_bsdf", NodeItem::Type::BSDF); NodeItem n_subsurface_bsdf = create_node(
n_sheen_bsdf.set_input("weight", inputs.find("sheen")->second); "subsurface_bsdf",
n_sheen_bsdf.set_input("color", base_color); NodeItem::Type::BSDF,
n_sheen_bsdf.set_input("roughness", roughness); {
n_sheen_bsdf.set_input("normal", normal); {"color", n_coat_affected_subsurface_color},
{"radius", inputs.find("subsurface_radius")->second},
NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF); {"anisotropy", anisotropy},
n_diffuse_bsdf.set_input("color", {"normal", normal},
base_color.max(val(0.0f)) ^ n_coat_gamma); });
n_diffuse_bsdf.set_input("roughness", roughness);
n_diffuse_bsdf.set_input("weight", val(1.0f));
n_diffuse_bsdf.set_input("normal", normal);
NodeItem n_subsurface_mix = create_node("mix", NodeItem::Type::BSDF);
n_subsurface_mix.set_input("fg", n_selected_subsurface_bsdf);
n_subsurface_mix.set_input("bg", n_diffuse_bsdf);
n_subsurface_mix.set_input("mix", inputs.find("subsurface")->second);
NodeItem n_sheen_layer = create_node("layer", NodeItem::Type::BSDF); NodeItem n_selected_subsurface_bsdf = create_node("mix",
n_sheen_layer.set_input("top", n_sheen_bsdf); NodeItem::Type::BSDF,
n_sheen_layer.set_input("base", n_subsurface_mix); {
{"fg", n_translucent_bsdf},
{"bg", n_subsurface_bsdf},
{"mix", val(0.0f)},
});
NodeItem n_transmission_mix = create_node("mix", NodeItem::Type::BSDF); NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
n_transmission_mix.set_input("fg", n_transmission_bsdf); NodeItem::Type::BSDF,
n_transmission_mix.set_input("bg", n_sheen_layer); {
n_transmission_mix.set_input("mix", inputs.find("transmission")->second); {"weight", inputs.find("sheen")->second},
{"color", base_color},
{"roughness", roughness},
{"normal", normal},
});
NodeItem n_specular_layer = create_node("layer", NodeItem::Type::BSDF); NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
n_specular_layer.set_input("top", n_specular_bsdf); NodeItem::Type::BSDF,
n_specular_layer.set_input("base", n_transmission_mix); {
{"color", base_color.max(val(0.0f)) ^ n_coat_gamma},
{"roughness", roughness},
{"weight", val(1.0f)},
{"normal", normal},
});
NodeItem n_metalness_mix = create_node("mix", NodeItem::Type::BSDF); NodeItem n_subsurface_mix = create_node("mix",
n_metalness_mix.set_input("fg", n_metal_bsdf); NodeItem::Type::BSDF,
n_metalness_mix.set_input("bg", n_specular_layer); {
n_metalness_mix.set_input("mix", inputs.find("metalness")->second); {"fg", n_selected_subsurface_bsdf},
{"bg", n_diffuse_bsdf},
{"mix", inputs.find("subsurface")->second},
});
NodeItem n_thin_film_layer = create_node("layer", NodeItem::Type::BSDF); NodeItem n_sheen_layer = create_node("layer",
n_thin_film_layer.set_input("top", n_thin_film_bsdf); NodeItem::Type::BSDF,
n_thin_film_layer.set_input("base", n_metalness_mix); {
{"top", n_sheen_bsdf},
{"base", n_subsurface_mix},
});
NodeItem n_opacity_luminance = create_node("luminance", NodeItem::Type::Color3); NodeItem n_transmission_mix = create_node("mix",
n_opacity_luminance.set_input("in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))); NodeItem::Type::BSDF,
{
{"fg", n_transmission_bsdf},
{"bg", n_sheen_layer},
{"mix", inputs.find("transmission")->second},
});
NodeItem n_coat_attenuation = create_node("mix", NodeItem::Type::Color3); NodeItem n_specular_layer = create_node("layer",
n_coat_attenuation.set_input("fg", base_color); NodeItem::Type::BSDF,
n_coat_attenuation.set_input("bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))); {
n_coat_attenuation.set_input("mix", coat); {"top", n_specular_bsdf},
{"base", n_transmission_mix},
});
res = create_node("layer", NodeItem::Type::BSDF); NodeItem n_metalness_mix = create_node("mix",
res.set_input("top", n_coat_bsdf); NodeItem::Type::BSDF,
res.set_input("base", n_thin_film_layer * n_coat_attenuation); {
{"fg", n_metal_bsdf},
{"bg", n_specular_layer},
{"mix", inputs.find("metalness")->second},
});
NodeItem n_thin_film_layer = create_node(
"layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
NodeItem n_opacity_luminance = create_node(
"luminance",
NodeItem::Type::Color3,
{
{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
});
NodeItem n_coat_attenuation = create_node("mix",
NodeItem::Type::Color3,
{
{"fg", base_color},
{"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
{"mix", coat},
});
res = create_node("layer",
NodeItem::Type::BSDF,
{
{"top", n_coat_bsdf},
{"base", n_thin_film_layer * n_coat_attenuation},
});
return res; return res;
} }
else if (to_type_ == NodeItem::Type::EDF) { else if (to_type_ == NodeItem::Type::EDF) {
auto inputs = edf_inputs(); auto inputs = edf_inputs();
res = create_node("uniform_edf", NodeItem::Type::EDF); res = create_node(
res.set_input("color", inputs.find("emission_color")->second * inputs.find("emission")->second); "uniform_edf",
NodeItem::Type::EDF,
{
{"color", inputs.find("emission_color")->second * inputs.find("emission")->second},
});
} }
else if (to_type_ == NodeItem::Type::SurfaceShader) { else if (to_type_ == NodeItem::Type::SurfaceShader) {
auto b_inputs = bsdf_inputs(); auto b_inputs = bsdf_inputs();
@ -573,47 +648,42 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem anisotropic = b_inputs.find("specular_anisotropy")->second; NodeItem anisotropic = b_inputs.find("specular_anisotropy")->second;
NodeItem ior = b_inputs.find("specular_IOR")->second; NodeItem ior = b_inputs.find("specular_IOR")->second;
NodeItem rotation = b_inputs.find("specular_rotation")->second; NodeItem rotation = b_inputs.find("specular_rotation")->second;
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);
res.set_input("metalness", b_inputs.find("metalness")->second ); res = create_node("standard_surface",
NodeItem::Type::SurfaceShader,
res.set_input("specular", b_inputs.find("specular")->second ); {
res.set_input("specular_color", base_color); {"base", val(1.0f)},
res.set_input("specular_roughness", roughness); {"base_color", base_color},
res.set_input("specular_IOR", ior); {"diffuse_roughness", roughness},
res.set_input("specular_anisotropy", anisotropic); {"metalness", b_inputs.find("metalness")->second},
res.set_input("specular_rotation", rotation); {"specular", b_inputs.find("specular")->second},
{"specular_color", base_color},
res.set_input("transmission", b_inputs.find("transmission")->second ); {"specular_roughness", roughness},
res.set_input("transmission_color", base_color); {"specular_IOR", ior},
res.set_input("transmission_extra_roughness", roughness); {"specular_anisotropy", anisotropic},
{"specular_rotation", rotation},
res.set_input("subsurface", b_inputs.find("subsurface")->second ); {"transmission", b_inputs.find("transmission")->second},
res.set_input("subsurface_color", base_color); {"transmission_color", base_color},
res.set_input("subsurface_radius", b_inputs.find("subsurface_radius")->second ); {"transmission_extra_roughness", roughness},
res.set_input("subsurface_anisotropy", anisotropic); {"subsurface", b_inputs.find("subsurface")->second},
{"subsurface_color", base_color},
res.set_input("sheen", b_inputs.find("sheen")->second ); {"subsurface_radius", b_inputs.find("subsurface_radius")->second},
res.set_input("sheen_color", base_color); {"subsurface_anisotropy", anisotropic},
res.set_input("sheen_roughness", roughness); {"sheen", b_inputs.find("sheen")->second},
{"sheen_color", base_color},
res.set_input("coat", b_inputs.find("coat")->second ); {"sheen_roughness", roughness},
res.set_input("coat_color", base_color); {"coat", b_inputs.find("coat")->second},
res.set_input("coat_roughness", b_inputs.find("coat_roughness")->second ); {"coat_color", base_color},
res.set_input("coat_IOR", ior); {"coat_roughness", b_inputs.find("coat_roughness")->second},
res.set_input("coat_anisotropy", anisotropic); {"coat_IOR", ior},
res.set_input("coat_rotation", rotation); {"coat_anisotropy", anisotropic},
res.set_input("coat_normal", b_inputs.find("coat_normal")->second ); {"coat_rotation", rotation},
{"coat_normal", b_inputs.find("coat_normal")->second},
res.set_input("emission", e_inputs.find("emission")->second); {"emission", e_inputs.find("emission")->second},
res.set_input("emission_color", e_inputs.find("emission_color")->second); {"emission_color", e_inputs.find("emission_color")->second},
{"normal", b_inputs.find("normal")->second},
res.set_input("normal", b_inputs.find("normal")->second); {"tangent", b_inputs.find("tangent")->second},
res.set_input("tangent", b_inputs.find("tangent")->second); });
} }
return res; return res;

View File

@ -52,16 +52,13 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem ior = get_input_value("IOR", NodeItem::Type::Float); NodeItem ior = get_input_value("IOR", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem res = create_node("dielectric_bsdf", NodeItem::Type::BSDF); return create_node("dielectric_bsdf",
if (normal) { NodeItem::Type::BSDF,
res.set_input("normal", normal); {{"normal", normal},
} {"tint", color},
res.set_input("tint", color); {"roughness", roughness},
res.set_input("roughness", roughness); {"ior", ior},
res.set_input("ior", ior); {"scatter_mode", val(std::string("T"))}});
res.set_input("scatter_mode", val(std::string("T")));
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -58,14 +58,10 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float); NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem res = create_node("sheen_bsdf", NodeItem::Type::BSDF); return create_node(
res.set_input("color", color); "sheen_bsdf",
res.set_input("weight", roughness); NodeItem::Type::BSDF,
res.set_input("roughness", roughness); {{"color", color}, {"weight", roughness}, {"roughness", roughness}, {"normal", normal}});
if (normal) {
res.set_input("normal", normal);
}
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -39,12 +39,8 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem color = get_input_value("Color", NodeItem::Type::Color3); NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem res = create_node("translucent_bsdf", NodeItem::Type::BSDF); return create_node(
res.set_input("color", color); "translucent_bsdf", NodeItem::Type::BSDF, {{"color", color}, {"normal", normal}});
if (normal) {
res.set_input("normal", normal);
}
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -34,9 +34,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem color = get_input_value("Color", NodeItem::Type::Color3); NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float); NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
NodeItem res = create_node("uniform_edf", NodeItem::Type::EDF); return create_node("uniform_edf", NodeItem::Type::EDF, {{"color", color * strength}});
res.set_input("color", color * strength);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -66,16 +66,13 @@ NODE_SHADER_MATERIALX_BEGIN
std::string name = socket_out_->name; std::string name = socket_out_->name;
if (name == "Position") { if (name == "Position") {
res = create_node("position", NodeItem::Type::Vector3); res = create_node("position", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
else if (name == "Normal") { else if (name == "Normal") {
res = create_node("normal", NodeItem::Type::Vector3); res = create_node("normal", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
else if (ELEM(name, "Tangent", "True Normal")) { else if (ELEM(name, "Tangent", "True Normal")) {
res = create_node("tangent", NodeItem::Type::Vector3); res = create_node("tangent", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
else { else {
res = get_output_default(name, NodeItem::Type::Any); res = get_output_default(name, NodeItem::Type::Any);

View File

@ -43,15 +43,10 @@ NODE_SHADER_MATERIALX_BEGIN
/* Modifier to follow Cycles result */ /* Modifier to follow Cycles result */
hue = hue - val(0.5f); hue = hue - val(0.5f);
NodeItem combine = create_node("combine3", NodeItem::Type::Vector3); NodeItem combine = create_node(
combine.set_input("in1", hue); "combine3", NodeItem::Type::Vector3, {{"in1", hue}, {"in2", saturation}, {"in3", value}});
combine.set_input("in2", saturation);
combine.set_input("in3", value);
NodeItem res = create_node("hsvadjust", NodeItem::Type::Color3); return create_node("hsvadjust", NodeItem::Type::Color3, {{"in", color}, {"amount", combine}});
res.set_input("in", color);
res.set_input("amount", combine);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -31,7 +31,7 @@ NODE_SHADER_MATERIALX_BEGIN
{ {
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float); NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
NodeItem color = get_input_value("Color", NodeItem::Type::Color3); NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
return fac.blend(color, fac.val(1.0f) - color); return fac.blend(color, val(1.0f) - color);
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -475,14 +475,14 @@ NODE_SHADER_MATERIALX_BEGIN
BLI_assert_unreachable(); BLI_assert_unreachable();
} }
NodeItem res = create_node("range", type); return create_node("range",
res.set_input("in", value); type,
res.set_input("inlow", from_min); {{"in", value},
res.set_input("inhigh", from_max); {"inlow", from_min},
res.set_input("outlow", to_min); {"inhigh", from_max},
res.set_input("outhigh", to_max); {"outlow", to_min},
res.set_input("doclamp", val(bool(map_range->clamp))); {"outhigh", to_max},
return res; {"doclamp", val(bool(map_range->clamp))}});
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -41,10 +41,7 @@ NODE_SHADER_MATERIALX_BEGIN
res = shader2 * fac; res = shader2 * fac;
} }
else if (shader1 && shader2) { else if (shader1 && shader2) {
res = create_node("mix", to_type_); res = create_node("mix", to_type_, {{"fg", shader2}, {"bg", shader1}, {"mix", fac}});
res.set_input("fg", shader2);
res.set_input("bg", shader1);
res.set_input("mix", fac);
} }
break; break;
} }

View File

@ -147,11 +147,9 @@ NODE_SHADER_MATERIALX_BEGIN
BLI_assert_unreachable(); BLI_assert_unreachable();
} }
NodeItem res = create_node("normalmap", NodeItem::Type::Vector3); return create_node("normalmap",
res.set_input("in", color); NodeItem::Type::Vector3,
res.set_input("scale", strength); {{"in", color}, {"scale", strength}, {"space", val(space)}});
res.set_input("space", val(space));
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -38,8 +38,7 @@ NODE_SHADER_MATERIALX_BEGIN
std::string name = socket_out_->name; std::string name = socket_out_->name;
if (name == "Location") { if (name == "Location") {
res = create_node("position", NodeItem::Type::Vector3); res = create_node("position", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
/* TODO: This node doesn't have an implementation in MaterialX. /* TODO: This node doesn't have an implementation in MaterialX.
* It's added in MaterialX 1.38.8. Uncomment this code after switching to 1.38.8. * It's added in MaterialX 1.38.8. Uncomment this code after switching to 1.38.8.

View File

@ -61,9 +61,7 @@ NODE_SHADER_MATERIALX_BEGIN
else { else {
surface = get_input_link("Surface", NodeItem::Type::SurfaceShader); surface = get_input_link("Surface", NodeItem::Type::SurfaceShader);
} }
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material); return create_node("surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}});
res.set_input("surfaceshader", surface);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -30,9 +30,7 @@ NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
NodeItem color = get_output_default("Color", NodeItem::Type::Color4); NodeItem color = get_output_default("Color", NodeItem::Type::Color4);
NodeItem res = create_node("constant", NodeItem::Type::Color4); return create_node("constant", NodeItem::Type::Color4, {{"value", color}});
res.set_input("value", color);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -31,10 +31,7 @@ NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
NodeItem color = get_input_value("Color", NodeItem::Type::Color4); NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
return create_node("luminance", NodeItem::Type::Color4, {{"in", color}});
NodeItem res = create_node("luminance", NodeItem::Type::Color4);
res.set_input("in", color);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -82,8 +82,7 @@ NODE_SHADER_MATERIALX_BEGIN
case NODE_COMBSEP_COLOR_HSV: case NODE_COMBSEP_COLOR_HSV:
case NODE_COMBSEP_COLOR_HSL: case NODE_COMBSEP_COLOR_HSL:
/* NOTE: HSL is unsupported color model, using HSV instead */ /* NOTE: HSL is unsupported color model, using HSV instead */
convert = create_node("rgbtohsv", NodeItem::Type::Color3); convert = create_node("rgbtohsv", NodeItem::Type::Color3, {{"in", color}});
convert.set_input("in", color);
break; break;
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();

View File

@ -153,11 +153,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem y = get_input_value("Y", NodeItem::Type::Float); NodeItem y = get_input_value("Y", NodeItem::Type::Float);
NodeItem z = get_input_value("Z", NodeItem::Type::Float); NodeItem z = get_input_value("Z", NodeItem::Type::Float);
NodeItem res = create_node("combine3", NodeItem::Type::Vector3); return create_node("combine3", NodeItem::Type::Vector3, {{"in1", x}, {"in2", y}, {"in3", z}});
res.set_input("in1", x);
res.set_input("in2", y);
res.set_input("in3", z);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -91,15 +91,13 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem anisotropy = get_input_value("Anisotropy", NodeItem::Type::Float); NodeItem anisotropy = get_input_value("Anisotropy", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem res = create_node("subsurface_bsdf", NodeItem::Type::BSDF); return create_node("subsurface_bsdf",
res.set_input("weight", val(1.0f)); NodeItem::Type::BSDF,
res.set_input("color", color); {{"weight", val(1.0f)},
res.set_input("radius", radius * scale); {"color", color},
res.set_input("anisotropy", anisotropy); {"radius", radius * scale},
if (normal) { {"anisotropy", anisotropy},
res.set_input("normal", normal); {"normal", normal}});
}
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -82,12 +82,10 @@ NODE_SHADER_MATERIALX_BEGIN
res = texcoord_node(); res = texcoord_node();
} }
else if (name == "Normal") { else if (name == "Normal") {
res = create_node("normal", NodeItem::Type::Vector3); res = create_node("normal", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
else if (name == "Object") { else if (name == "Object") {
res = create_node("position", NodeItem::Type::Vector3); res = create_node("position", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
res.set_input("space", val(std::string("world")));
} }
else { else {
res = get_output_default(name, NodeItem::Type::Any); res = get_output_default(name, NodeItem::Type::Any);

View File

@ -11,6 +11,10 @@
#include "IMB_colormanagement.h" #include "IMB_colormanagement.h"
#include "hydra/image.h"
#include "DEG_depsgraph_query.h"
namespace blender::nodes::node_shader_tex_environment_cc { namespace blender::nodes::node_shader_tex_environment_cc {
static void node_declare(NodeDeclarationBuilder &b) static void node_declare(NodeDeclarationBuilder &b)
@ -130,8 +134,50 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
/* TODO: Implement */ NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
return empty();
Image *image = (Image *)node_->id;
if (!image) {
return res;
}
NodeTexEnvironment *tex_env = static_cast<NodeTexEnvironment *>(node_->storage);
Scene *scene = DEG_get_input_scene(depsgraph_);
Main *bmain = DEG_get_bmain(depsgraph_);
/* 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. */
std::string image_path = io::hydra::cache_or_get_image_file(
bmain, scene, image, &tex_env->iuser);
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
if (!vector) {
vector = texcoord_node();
}
/* TODO: texcoords should be translated to spherical coordinates */
std::string filtertype;
switch (tex_env->interpolation) {
case SHD_INTERP_LINEAR:
filtertype = "linear";
break;
case SHD_INTERP_CLOSEST:
filtertype = "closest";
break;
case SHD_INTERP_CUBIC:
case SHD_INTERP_SMART:
filtertype = "cubic";
break;
default:
BLI_assert_unreachable();
}
res = create_node("image", NodeItem::Type::Color4);
res.set_input("file", image_path, NodeItem::Type::Filename);
res.set_input("texcoord", vector);
res.set_input("filtertype", val(filtertype));
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -179,64 +179,74 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f)); /* Getting node name for Color output. This name will be used for <image> node. */
std::string image_node_name = node_name();
image_node_name = image_node_name.substr(0, image_node_name.rfind('_')) + "_Color";
Image *image = (Image *)node_->id; NodeItem res = empty();
if (image) { res.node = graph_->getNode(image_node_name);
NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage); if (!res.node) {
Scene *scene = DEG_get_input_scene(depsgraph_); res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
Main *bmain = DEG_get_bmain(depsgraph_);
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains Image *image = (Image *)node_->id;
* pretty general code, so could be moved from bf_usd project. */ if (image) {
std::string image_path = io::hydra::cache_or_get_image_file( NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage);
bmain, scene, image, &tex_image->iuser); Scene *scene = DEG_get_input_scene(depsgraph_);
Main *bmain = DEG_get_bmain(depsgraph_);
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); /* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file
if (!vector) { * contains pretty general code, so could be moved from bf_usd project. */
vector = texcoord_node(); std::string image_path = io::hydra::cache_or_get_image_file(
bmain, scene, image, &tex_image->iuser);
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
if (!vector) {
vector = texcoord_node();
}
/* TODO: add math to vector depending of tex_image->projection */
std::string filtertype;
switch (tex_image->interpolation) {
case SHD_INTERP_LINEAR:
filtertype = "linear";
break;
case SHD_INTERP_CLOSEST:
filtertype = "closest";
break;
case SHD_INTERP_CUBIC:
case SHD_INTERP_SMART:
filtertype = "cubic";
break;
default:
BLI_assert_unreachable();
}
std::string addressmode;
switch (tex_image->extension) {
case SHD_IMAGE_EXTENSION_REPEAT:
addressmode = "periodic";
break;
case SHD_IMAGE_EXTENSION_EXTEND:
addressmode = "clamp";
break;
case SHD_IMAGE_EXTENSION_CLIP:
addressmode = "constant";
break;
case SHD_IMAGE_EXTENSION_MIRROR:
addressmode = "mirror";
break;
default:
BLI_assert_unreachable();
}
res = create_node("image",
NodeItem::Type::Color4,
{{"texcoord", vector},
{"filtertype", val(filtertype)},
{"uaddressmode", val(addressmode)},
{"vaddressmode", val(addressmode)}});
res.set_input("file", image_path, NodeItem::Type::Filename);
res.node->setName(image_node_name);
} }
/* TODO: add math to vector depending of tex_image->projection */
std::string filtertype;
switch (tex_image->interpolation) {
case SHD_INTERP_LINEAR:
filtertype = "linear";
break;
case SHD_INTERP_CLOSEST:
filtertype = "closest";
break;
case SHD_INTERP_CUBIC:
case SHD_INTERP_SMART:
filtertype = "cubic";
break;
default:
BLI_assert_unreachable();
}
std::string addressmode;
switch (tex_image->extension) {
case SHD_IMAGE_EXTENSION_REPEAT:
addressmode = "periodic";
break;
case SHD_IMAGE_EXTENSION_EXTEND:
addressmode = "clamp";
break;
case SHD_IMAGE_EXTENSION_CLIP:
addressmode = "constant";
break;
case SHD_IMAGE_EXTENSION_MIRROR:
addressmode = "mirror";
break;
default:
BLI_assert_unreachable();
}
res = create_node("image", NodeItem::Type::Color4);
res.set_input("file", image_path, NodeItem::Type::Filename);
res.set_input("texcoord", vector);
res.set_input("filtertype", val(filtertype));
res.set_input("uaddressmode", val(addressmode));
res.set_input("vaddressmode", val(addressmode));
} }
if (STREQ(socket_out_->name, "Alpha")) { if (STREQ(socket_out_->name, "Alpha")) {

View File

@ -267,11 +267,11 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem position = create_node("position", NodeItem::Type::Vector3); NodeItem position = create_node("position", NodeItem::Type::Vector3);
position = position * scale; position = position * scale;
NodeItem res = create_node("fractal3d", NodeItem::Type::Color3); return create_node("fractal3d",
res.set_input("position", position); NodeItem::Type::Color3,
res.set_input("octaves", val(int(detail.value->asA<float>()))); {{"position", position},
res.set_input("lacunarity", lacunarity); {"octaves", val(int(detail.value->asA<float>()))},
return res; {"lacunarity", lacunarity}});
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -42,9 +42,7 @@ NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
NodeItem value = get_output_default("Value", NodeItem::Type::Float); NodeItem value = get_output_default("Value", NodeItem::Type::Float);
NodeItem res = create_node("constant", NodeItem::Type::Float); return create_node("constant", NodeItem::Type::Float, {{"value", value}});
res.set_input("value", value);
return res;
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END