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

View File

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

View File

@ -3,6 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_item.h"
#include "node_parser.h"
#include "BLI_assert.h"
#include "BLI_utildefines.h"
@ -120,9 +121,7 @@ NodeItem NodeItem::operator+(const NodeItem &other) const
/* Special case: add BSDF/EDF shaders */
NodeItem res = empty();
if (other.type() == type) {
res = create_node("add", type);
res.set_input("in1", *this);
res.set_input("in2", other);
res = create_node("add", type, {{"in1", *this}, {"in2", other}});
}
else {
BLI_assert_unreachable();
@ -151,9 +150,7 @@ NodeItem NodeItem::operator*(const NodeItem &other) const
NodeItem res = empty();
Type other_type = other.type();
if (ELEM(other_type, Type::Float, Type::Color3)) {
res = create_node("multiply", type);
res.set_input("in1", *this);
res.set_input("in2", other);
res = create_node("multiply", type, {{"in1", *this}, {"in2", other}});
}
else {
BLI_assert_unreachable();
@ -540,8 +537,7 @@ NodeItem NodeItem::convert(Type to_type) const
}
}
else {
res = create_node("convert", to_type);
res.set_input("in", *this);
res = create_node("convert", to_type, {{"in", *this}});
}
return res;
}
@ -597,11 +593,8 @@ NodeItem NodeItem::if_else(CompareOp op,
res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2;
}
else {
res = create_node(category, to_type);
res.set_input("value1", *this);
res.set_input("value2", other);
res.set_input("in1", item1);
res.set_input("in2", item2);
res = create_node(
category, to_type, {{"value1", *this}, {"value2", other}, {"in1", item1}, {"in2", item2}});
}
return res;
@ -610,9 +603,7 @@ NodeItem NodeItem::if_else(CompareOp op,
NodeItem NodeItem::extract(const int index) const
{
/* TODO: Add check if (value) { ... } */
NodeItem res = create_node("extract", Type::Float);
res.set_input("in", *this);
res.set_input("index", val(index));
NodeItem res = create_node("extract", Type::Float, {{"in", *this}, {"index", val(index)}});
return res;
}
@ -635,7 +626,7 @@ NodeItem::Type NodeItem::type() const
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);
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;
}
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)
{
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;
v = v.convert(type);
}
res = create_node(category, type);
res.set_input("in", v);
res = create_node(category, type, {{"in", v}});
}
return res;
}
@ -887,9 +888,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
}
}
else {
res = create_node(category, to_type);
res.set_input("in1", item1);
res.set_input("in2", item2);
res = create_node(category, to_type, {{"in1", item1}, {"in2", item2}});
}
return res;
}

View File

@ -4,6 +4,8 @@
#pragma once
#include <map>
#include <MaterialXCore/Node.h>
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. */
class NodeItem {
public:
using Inputs = std::vector<std::pair<std::string, NodeItem>>;
enum class Type {
Any = 0,
Empty,
@ -106,7 +110,8 @@ class NodeItem {
Type type() const;
/* 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);
void set_input(const std::string &in_name, const NodeItem &item);
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);
}
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)
{
return empty().create_input(name, item);

View File

@ -44,6 +44,9 @@ class NodeParser {
protected:
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,
const NodeItem::Inputs &inputs);
NodeItem create_input(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);

View File

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

View File

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

View File

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

View File

@ -303,8 +303,7 @@ NODE_SHADER_MATERIALX_BEGIN
/* 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);
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);
@ -326,35 +325,36 @@ NODE_SHADER_MATERIALX_BEGIN
subsurface_radius = subsurface_radius * subsurface_scale;
return std::map<std::string, NodeItem> {{"base", val(1.0f)},
{"base_color", base_color},
{"diffuse_roughness", roughness},
{"normal", normal},
{"tangent", tangent},
{"metalness", metallic},
{"specular", specular},
{"specular_color", base_color},
{"specular_roughness", roughness},
{"specular_IOR", ior},
{"specular_anisotropy", anisotropic},
{"specular_rotation", anisotropic_rotation},
{"transmission", transmission},
{"transmission_color", base_color},
{"transmission_extra_roughness", roughness},
{"subsurface", subsurface},
{"subsurface_color", base_color},
{"subsurface_radius", subsurface_radius},
{"subsurface_anisotropy", anisotropic},
{"sheen", sheen},
{"sheen_color", base_color},
{"sheen_roughness", roughness},
{"coat", coat},
{"coat_color", base_color},
{"coat_roughness", coat_roughness},
{"coat_IOR", ior},
{"coat_anisotropy", anisotropic},
{"coat_rotation", anisotropic_rotation},
{"coat_normal", coat_normal},
return std::map<std::string, NodeItem>{
{"base", val(1.0f)},
{"base_color", base_color},
{"diffuse_roughness", roughness},
{"normal", normal},
{"tangent", tangent},
{"metalness", metallic},
{"specular", specular},
{"specular_color", base_color},
{"specular_roughness", roughness},
{"specular_IOR", ior},
{"specular_anisotropy", anisotropic},
{"specular_rotation", anisotropic_rotation},
{"transmission", transmission},
{"transmission_color", base_color},
{"transmission_extra_roughness", roughness},
{"subsurface", subsurface},
{"subsurface_color", base_color},
{"subsurface_radius", subsurface_radius},
{"subsurface_anisotropy", anisotropic},
{"sheen", sheen},
{"sheen_color", base_color},
{"sheen_roughness", roughness},
{"coat", coat},
{"coat_color", base_color},
{"coat_roughness", coat_roughness},
{"coat_IOR", ior},
{"coat_anisotropy", anisotropic},
{"coat_rotation", anisotropic_rotation},
{"coat_normal", coat_normal},
};
};
@ -379,190 +379,265 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem ior = inputs.find("specular_IOR")->second;
NodeItem normal = inputs.find("normal")->second;
NodeItem tangent = inputs.find("tangent")->second;
NodeItem n_main_tangent = empty();
if (tangent) {
NodeItem n_tangent_rotate = create_node("rotate3d", NodeItem::Type::Vector3);
n_tangent_rotate.set_input("in", tangent);
n_tangent_rotate.set_input("amount", rotation * val(360.0f));
n_tangent_rotate.set_input("axis", normal);
NodeItem n_tangent_rotate = create_node("rotate3d",
NodeItem::Type::Vector3,
{
{"in", tangent},
{"amount", rotation * val(360.0f)},
{"axis", normal},
});
NodeItem n_tangent_rotate_normalize = create_node("normalize", NodeItem::Type::Vector3);
n_tangent_rotate_normalize.set_input("in", n_tangent_rotate);
NodeItem n_tangent_rotate_normalize = create_node(
"normalize", NodeItem::Type::Vector3, {{"in", n_tangent_rotate}});
n_main_tangent = anisotropy.if_else(
NodeItem::CompareOp::Greater,
val(0.0f),
n_tangent_rotate_normalize,
tangent);
NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
}
NodeItem n_coat_roughness_vector = create_node("roughness_anisotropy",
NodeItem::Type::Vector2);
n_coat_roughness_vector.set_input("roughness", roughness);
n_coat_roughness_vector.set_input("anisotropy", anisotropy);
NodeItem::Type::Vector2,
{
{"roughness", roughness},
{"anisotropy", anisotropy},
});
NodeItem n_coat_bsdf = create_node("dielectric_bsdf", NodeItem::Type::BSDF);
n_coat_bsdf.set_input("weight", coat);
n_coat_bsdf.set_input("tint", val(MaterialX::Color3(1.0f, 1.0f, 1.0f)));
n_coat_bsdf.set_input("ior", ior);
n_coat_bsdf.set_input("scatter_mode", val(std::string("R")));
n_coat_bsdf.set_input("roughness", n_coat_roughness_vector);
n_coat_bsdf.set_input("normal", normal);
NodeItem n_coat_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{
{"weight", coat},
{"tint", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))},
{"ior", ior},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_coat_roughness_vector},
{"normal", normal},
});
if (tangent) {
NodeItem n_coat_tangent_rotate = create_node("rotate3d", NodeItem::Type::Vector3);
n_coat_tangent_rotate.set_input("in", tangent);
n_coat_tangent_rotate.set_input("amount", rotation * val(360.0f));
n_coat_tangent_rotate.set_input("axis", normal);
NodeItem n_coat_tangent_rotate = create_node("rotate3d",
NodeItem::Type::Vector3,
{
{"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::CompareOp::Greater,
val(0.0f),
n_coat_tangent_rotate_normalize,
tangent);
NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
n_coat_bsdf.set_input("tangent", n_coat_tangent);
}
NodeItem n_thin_film_bsdf = create_node("thin_film_bsdf", NodeItem::Type::BSDF);
n_thin_film_bsdf.set_input("thickness", val(0.0f));
n_thin_film_bsdf.set_input("ior", val(1.5f));
NodeItem n_thin_film_bsdf = create_node("thin_film_bsdf",
NodeItem::Type::BSDF,
{
{"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_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3);
NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) *
roughness;
NodeItem n_coat_affected_roughness = create_node("mix", NodeItem::Type::Float);
n_coat_affected_roughness.set_input("fg", val(1.0f));
n_coat_affected_roughness.set_input("bg", roughness);
n_coat_affected_roughness.set_input("mix", n_coat_affect_roughness_multiply2);
NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * roughness;
NodeItem n_coat_affected_roughness = create_node(
"mix",
NodeItem::Type::Float,
{
{"fg", val(1.0f)},
{"bg", roughness},
{"mix", n_coat_affect_roughness_multiply2},
});
NodeItem n_main_roughness = create_node("roughness_anisotropy", NodeItem::Type::Vector2);
n_main_roughness.set_input("roughness", n_coat_affected_roughness);
n_main_roughness.set_input("anisotropy", anisotropy);
NodeItem n_main_roughness = create_node("roughness_anisotropy",
NodeItem::Type::Vector2,
{
{"roughness", n_coat_affected_roughness},
{"anisotropy", anisotropy},
});
NodeItem n_metal_bsdf = create_node("conductor_bsdf", NodeItem::Type::BSDF);
n_metal_bsdf.set_input("ior", n_ior_out);
n_metal_bsdf.set_input("extinction", n_extinction_out);
n_metal_bsdf.set_input("roughness", n_main_roughness);
n_metal_bsdf.set_input("normal", normal);
n_metal_bsdf.set_input("tangent", n_main_tangent);
NodeItem n_metal_bsdf = create_node("conductor_bsdf",
NodeItem::Type::BSDF,
{
{"ior", n_ior_out},
{"extinction", n_extinction_out},
{"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent},
});
NodeItem n_specular_bsdf = create_node("dielectric_bsdf", NodeItem::Type::BSDF);
n_specular_bsdf.set_input("weight", specular);
n_specular_bsdf.set_input("tint", base_color);
n_specular_bsdf.set_input("ior", ior);
n_specular_bsdf.set_input("scatter_mode", val(std::string("R")));
n_specular_bsdf.set_input("roughness", n_main_roughness);
n_specular_bsdf.set_input("normal", normal);
n_specular_bsdf.set_input("tangent", n_main_tangent);
NodeItem n_coat_affected_transmission_roughness = create_node("mix", NodeItem::Type::Float);
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_specular_bsdf = create_node("dielectric_bsdf",
NodeItem::Type::BSDF,
{
{"weight", specular},
{"tint", base_color},
{"ior", ior},
{"scatter_mode", val(std::string("R"))},
{"roughness", n_main_roughness},
{"normal", normal},
{"tangent", n_main_tangent},
});
NodeItem n_transmission_roughness = create_node("roughness_anisotropy",
NodeItem::Type::Vector2);
n_transmission_roughness.set_input("roughness", n_coat_affected_transmission_roughness);
n_transmission_roughness.set_input("anisotropy", anisotropy);
NodeItem n_coat_affected_transmission_roughness = create_node(
"mix",
NodeItem::Type::Float,
{
{"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},
});
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_affected_subsurface_color = base_color.max(val(0.0f)) ^
n_coat_gamma;
NodeItem n_translucent_bsdf = create_node("translucent_bsdf", NodeItem::Type::BSDF);
n_translucent_bsdf.set_input("color", n_coat_affected_subsurface_color);
n_translucent_bsdf.set_input("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_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ n_coat_gamma;
NodeItem n_translucent_bsdf = create_node("translucent_bsdf",
NodeItem::Type::BSDF,
{
{"color", n_coat_affected_subsurface_color},
{"normal", normal},
});
NodeItem n_sheen_bsdf = create_node("sheen_bsdf", NodeItem::Type::BSDF);
n_sheen_bsdf.set_input("weight", inputs.find("sheen")->second);
n_sheen_bsdf.set_input("color", base_color);
n_sheen_bsdf.set_input("roughness", roughness);
n_sheen_bsdf.set_input("normal", normal);
NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF);
n_diffuse_bsdf.set_input("color",
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_subsurface_bsdf = create_node(
"subsurface_bsdf",
NodeItem::Type::BSDF,
{
{"color", n_coat_affected_subsurface_color},
{"radius", inputs.find("subsurface_radius")->second},
{"anisotropy", anisotropy},
{"normal", normal},
});
NodeItem n_sheen_layer = create_node("layer", NodeItem::Type::BSDF);
n_sheen_layer.set_input("top", n_sheen_bsdf);
n_sheen_layer.set_input("base", n_subsurface_mix);
NodeItem n_selected_subsurface_bsdf = create_node("mix",
NodeItem::Type::BSDF,
{
{"fg", n_translucent_bsdf},
{"bg", n_subsurface_bsdf},
{"mix", val(0.0f)},
});
NodeItem n_transmission_mix = create_node("mix", NodeItem::Type::BSDF);
n_transmission_mix.set_input("fg", n_transmission_bsdf);
n_transmission_mix.set_input("bg", n_sheen_layer);
n_transmission_mix.set_input("mix", inputs.find("transmission")->second);
NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
NodeItem::Type::BSDF,
{
{"weight", inputs.find("sheen")->second},
{"color", base_color},
{"roughness", roughness},
{"normal", normal},
});
NodeItem n_specular_layer = create_node("layer", NodeItem::Type::BSDF);
n_specular_layer.set_input("top", n_specular_bsdf);
n_specular_layer.set_input("base", n_transmission_mix);
NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
NodeItem::Type::BSDF,
{
{"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);
n_metalness_mix.set_input("fg", n_metal_bsdf);
n_metalness_mix.set_input("bg", n_specular_layer);
n_metalness_mix.set_input("mix", inputs.find("metalness")->second);
NodeItem n_subsurface_mix = create_node("mix",
NodeItem::Type::BSDF,
{
{"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);
n_thin_film_layer.set_input("top", n_thin_film_bsdf);
n_thin_film_layer.set_input("base", n_metalness_mix);
NodeItem n_sheen_layer = create_node("layer",
NodeItem::Type::BSDF,
{
{"top", n_sheen_bsdf},
{"base", n_subsurface_mix},
});
NodeItem n_opacity_luminance = create_node("luminance", NodeItem::Type::Color3);
n_opacity_luminance.set_input("in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f)));
NodeItem n_transmission_mix = create_node("mix",
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);
n_coat_attenuation.set_input("fg", base_color);
n_coat_attenuation.set_input("bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f)));
n_coat_attenuation.set_input("mix", coat);
NodeItem n_specular_layer = create_node("layer",
NodeItem::Type::BSDF,
{
{"top", n_specular_bsdf},
{"base", n_transmission_mix},
});
res = create_node("layer", NodeItem::Type::BSDF);
res.set_input("top", n_coat_bsdf);
res.set_input("base", n_thin_film_layer * n_coat_attenuation);
NodeItem n_metalness_mix = create_node("mix",
NodeItem::Type::BSDF,
{
{"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;
}
else if (to_type_ == NodeItem::Type::EDF) {
auto inputs = edf_inputs();
res = create_node("uniform_edf", NodeItem::Type::EDF);
res.set_input("color", inputs.find("emission_color")->second * inputs.find("emission")->second);
res = create_node(
"uniform_edf",
NodeItem::Type::EDF,
{
{"color", inputs.find("emission_color")->second * inputs.find("emission")->second},
});
}
else if (to_type_ == NodeItem::Type::SurfaceShader) {
auto b_inputs = bsdf_inputs();
@ -573,47 +648,42 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem anisotropic = b_inputs.find("specular_anisotropy")->second;
NodeItem ior = b_inputs.find("specular_IOR")->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.set_input("specular", b_inputs.find("specular")->second );
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", rotation);
res.set_input("transmission", b_inputs.find("transmission")->second );
res.set_input("transmission_color", base_color);
res.set_input("transmission_extra_roughness", roughness);
res.set_input("subsurface", b_inputs.find("subsurface")->second );
res.set_input("subsurface_color", base_color);
res.set_input("subsurface_radius", b_inputs.find("subsurface_radius")->second );
res.set_input("subsurface_anisotropy", anisotropic);
res.set_input("sheen", b_inputs.find("sheen")->second );
res.set_input("sheen_color", base_color);
res.set_input("sheen_roughness", roughness);
res.set_input("coat", b_inputs.find("coat")->second );
res.set_input("coat_color", base_color);
res.set_input("coat_roughness", b_inputs.find("coat_roughness")->second );
res.set_input("coat_IOR", ior);
res.set_input("coat_anisotropy", anisotropic);
res.set_input("coat_rotation", rotation);
res.set_input("coat_normal", b_inputs.find("coat_normal")->second );
res.set_input("emission", e_inputs.find("emission")->second);
res.set_input("emission_color", e_inputs.find("emission_color")->second);
res.set_input("normal", b_inputs.find("normal")->second);
res.set_input("tangent", b_inputs.find("tangent")->second);
res = create_node("standard_surface",
NodeItem::Type::SurfaceShader,
{
{"base", val(1.0f)},
{"base_color", base_color},
{"diffuse_roughness", roughness},
{"metalness", b_inputs.find("metalness")->second},
{"specular", b_inputs.find("specular")->second},
{"specular_color", base_color},
{"specular_roughness", roughness},
{"specular_IOR", ior},
{"specular_anisotropy", anisotropic},
{"specular_rotation", rotation},
{"transmission", b_inputs.find("transmission")->second},
{"transmission_color", base_color},
{"transmission_extra_roughness", roughness},
{"subsurface", b_inputs.find("subsurface")->second},
{"subsurface_color", base_color},
{"subsurface_radius", b_inputs.find("subsurface_radius")->second},
{"subsurface_anisotropy", anisotropic},
{"sheen", b_inputs.find("sheen")->second},
{"sheen_color", base_color},
{"sheen_roughness", roughness},
{"coat", b_inputs.find("coat")->second},
{"coat_color", base_color},
{"coat_roughness", b_inputs.find("coat_roughness")->second},
{"coat_IOR", ior},
{"coat_anisotropy", anisotropic},
{"coat_rotation", rotation},
{"coat_normal", b_inputs.find("coat_normal")->second},
{"emission", e_inputs.find("emission")->second},
{"emission_color", e_inputs.find("emission_color")->second},
{"normal", b_inputs.find("normal")->second},
{"tangent", b_inputs.find("tangent")->second},
});
}
return res;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@ NODE_SHADER_MATERIALX_BEGIN
{
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
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
NODE_SHADER_MATERIALX_END

View File

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

View File

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

View File

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

View File

@ -38,8 +38,7 @@ NODE_SHADER_MATERIALX_BEGIN
std::string name = socket_out_->name;
if (name == "Location") {
res = create_node("position", NodeItem::Type::Vector3);
res.set_input("space", val(std::string("world")));
res = create_node("position", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
}
/* 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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,10 @@
#include "IMB_colormanagement.h"
#include "hydra/image.h"
#include "DEG_depsgraph_query.h"
namespace blender::nodes::node_shader_tex_environment_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -130,8 +134,50 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: Implement */
return empty();
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
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
NODE_SHADER_MATERIALX_END

View File

@ -179,64 +179,74 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN
#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;
if (image) {
NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage);
Scene *scene = DEG_get_input_scene(depsgraph_);
Main *bmain = DEG_get_bmain(depsgraph_);
NodeItem res = empty();
res.node = graph_->getNode(image_node_name);
if (!res.node) {
res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
/* 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_image->iuser);
Image *image = (Image *)node_->id;
if (image) {
NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage);
Scene *scene = DEG_get_input_scene(depsgraph_);
Main *bmain = DEG_get_bmain(depsgraph_);
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
if (!vector) {
vector = texcoord_node();
/* 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_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")) {

View File

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

View File

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