forked from blender/blender
MaterialX: split standard_surface into basic nodes #26
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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")) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user