forked from blender/blender
Parsing Improvements #14
@ -32,7 +32,7 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
|||||||
}
|
}
|
||||||
|
|
||||||
CLOG_INFO(LOG_MATERIALX_SHADER,
|
CLOG_INFO(LOG_MATERIALX_SHADER,
|
||||||
2,
|
1,
|
||||||
"Material: %s\n%s",
|
"Material: %s\n%s",
|
||||||
material->id.name,
|
material->id.name,
|
||||||
MaterialX::writeToXmlString(doc).c_str());
|
MaterialX::writeToXmlString(doc).c_str());
|
||||||
|
@ -13,7 +13,7 @@ NodeItem BrightContrastNodeParser::compute()
|
|||||||
NodeItem contrast = get_input_value("Contrast", NodeItem::Type::Float);
|
NodeItem contrast = get_input_value("Contrast", NodeItem::Type::Float);
|
||||||
|
|
||||||
/* This formula was given from OSL shader code in Cycles. */
|
/* This formula was given from OSL shader code in Cycles. */
|
||||||
return (bright + color * (contrast + value(1.0f)) - contrast * value(0.5f)).max(value(0.0f));
|
return (bright + color * (contrast + val(1.0f)) - contrast * val(0.5f)).max(val(0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -16,7 +16,7 @@ NodeItem BSDFDiffuseNodeParser::compute()
|
|||||||
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
|
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
|
||||||
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
|
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
|
||||||
|
|
||||||
NodeItem res = create_node("oren_nayar_diffuse_bsdf", "BSDF");
|
NodeItem res = create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF);
|
||||||
res.set_input("color", color);
|
res.set_input("color", color);
|
||||||
res.set_input("roughness", roughness);
|
res.set_input("roughness", roughness);
|
||||||
if (normal) {
|
if (normal) {
|
||||||
|
@ -50,8 +50,8 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
|
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
|
||||||
|
|
||||||
/* Creating standard_surface */
|
/* Creating standard_surface */
|
||||||
NodeItem res = create_node("standard_surface", "surfaceshader");
|
NodeItem res = create_node("standard_surface", NodeItem::Type::SurfaceShader);
|
||||||
res.set_input("base", 1.0, "float");
|
res.set_input("base", val(1.0f));
|
||||||
res.set_input("base_color", base_color);
|
res.set_input("base_color", base_color);
|
||||||
res.set_input("diffuse_roughness", roughness);
|
res.set_input("diffuse_roughness", roughness);
|
||||||
if (normal) {
|
if (normal) {
|
||||||
|
@ -15,7 +15,7 @@ NodeItem EmissionNodeParser::compute()
|
|||||||
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
||||||
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
|
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
|
||||||
|
|
||||||
NodeItem res = create_node("uniform_edf", "EDF");
|
NodeItem res = create_node("uniform_edf", NodeItem::Type::EDF);
|
||||||
res.set_input("color", color * strength);
|
res.set_input("color", color * strength);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -12,19 +12,19 @@ NodeItem HueSatValNodeParser::compute()
|
|||||||
* source\blender\nodes\texture\nodes\node_texture_hueSatVal.cc */
|
* source\blender\nodes\texture\nodes\node_texture_hueSatVal.cc */
|
||||||
NodeItem hue = get_input_value("Hue", NodeItem::Type::Float);
|
NodeItem hue = get_input_value("Hue", NodeItem::Type::Float);
|
||||||
NodeItem saturation = get_input_value("Saturation", NodeItem::Type::Float);
|
NodeItem saturation = get_input_value("Saturation", NodeItem::Type::Float);
|
||||||
NodeItem val = get_input_value("Value", NodeItem::Type::Float);
|
NodeItem value = get_input_value("Value", NodeItem::Type::Float);
|
||||||
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
|
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
|
||||||
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
||||||
|
|
||||||
/* Modifier to follow Cycles result */
|
/* Modifier to follow Cycles result */
|
||||||
hue = hue - value(0.5f);
|
hue = hue - val(0.5f);
|
||||||
|
|
||||||
NodeItem combine = create_node("combine3", "vector3");
|
NodeItem combine = create_node("combine3", NodeItem::Type::Vector3);
|
||||||
combine.set_input("in1", hue);
|
combine.set_input("in1", hue);
|
||||||
combine.set_input("in2", saturation);
|
combine.set_input("in2", saturation);
|
||||||
combine.set_input("in3", val);
|
combine.set_input("in3", value);
|
||||||
|
|
||||||
NodeItem res = create_node("hsvadjust", "color3");
|
NodeItem res = create_node("hsvadjust", NodeItem::Type::Color3);
|
||||||
res.set_input("in", color);
|
res.set_input("in", color);
|
||||||
res.set_input("amount", combine);
|
res.set_input("amount", combine);
|
||||||
return res;
|
return res;
|
||||||
|
@ -35,7 +35,7 @@ NodeItem MathNodeParser::compute()
|
|||||||
res = x.atan();
|
res = x.atan();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_ROUND:
|
case NODE_MATH_ROUND:
|
||||||
res = (x + value(0.5f)).floor();
|
res = (x + val(0.5f)).floor();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_ABSOLUTE:
|
case NODE_MATH_ABSOLUTE:
|
||||||
res = x.abs();
|
res = x.abs();
|
||||||
@ -47,13 +47,13 @@ NodeItem MathNodeParser::compute()
|
|||||||
res = x.ceil();
|
res = x.ceil();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_FRACTION:
|
case NODE_MATH_FRACTION:
|
||||||
res = x % value(1.0f);
|
res = x % val(1.0f);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_SQRT:
|
case NODE_MATH_SQRT:
|
||||||
res = x.sqrt();
|
res = x.sqrt();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_INV_SQRT:
|
case NODE_MATH_INV_SQRT:
|
||||||
res = value(1.0f) / x.sqrt();
|
res = val(1.0f) / x.sqrt();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_SIGN:
|
case NODE_MATH_SIGN:
|
||||||
res = x.sign();
|
res = x.sign();
|
||||||
@ -62,10 +62,10 @@ NodeItem MathNodeParser::compute()
|
|||||||
res = x.exp();
|
res = x.exp();
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_RADIANS:
|
case NODE_MATH_RADIANS:
|
||||||
res = x * value(float(M_PI) / 180.0f);
|
res = x * val(float(M_PI) / 180.0f);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_DEGREES:
|
case NODE_MATH_DEGREES:
|
||||||
res = x * value(180.0f * float(M_1_PI));
|
res = x * val(180.0f * float(M_1_PI));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_SINH:
|
case NODE_MATH_SINH:
|
||||||
res = x.sinh();
|
res = x.sinh();
|
||||||
@ -109,10 +109,10 @@ NodeItem MathNodeParser::compute()
|
|||||||
res = x.max(y);
|
res = x.max(y);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_LESS_THAN:
|
case NODE_MATH_LESS_THAN:
|
||||||
res = x.if_else(NodeItem::CompareOp::Less, y, value(1.0f), value(0.0f));
|
res = x.if_else(NodeItem::CompareOp::Less, y, val(1.0f), val(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_GREATER_THAN:
|
case NODE_MATH_GREATER_THAN:
|
||||||
res = x.if_else(NodeItem::CompareOp::Greater, y, value(1.0f), value(0.0f));
|
res = x.if_else(NodeItem::CompareOp::Greater, y, val(1.0f), val(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_MODULO:
|
case NODE_MATH_MODULO:
|
||||||
res = x % y;
|
res = x % y;
|
||||||
@ -138,7 +138,7 @@ NodeItem MathNodeParser::compute()
|
|||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_COMPARE:
|
case NODE_MATH_COMPARE:
|
||||||
res = z.if_else(NodeItem::CompareOp::Less, (x - y).abs(), value(1.0f), value(0.0f));
|
res = z.if_else(NodeItem::CompareOp::Less, (x - y).abs(), val(1.0f), val(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_MULTIPLY_ADD:
|
case NODE_MATH_MULTIPLY_ADD:
|
||||||
res = x * y + z;
|
res = x * y + z;
|
||||||
|
@ -17,13 +17,13 @@ NodeItem MixShaderNodeParser::compute()
|
|||||||
NodeItem shader2 = get_input_shader(2, shader_type_);
|
NodeItem shader2 = get_input_shader(2, shader_type_);
|
||||||
|
|
||||||
if (shader1 && !shader2) {
|
if (shader1 && !shader2) {
|
||||||
res = shader1 * (value(1.0f) - fac);
|
res = shader1 * (val(1.0f) - fac);
|
||||||
}
|
}
|
||||||
else if (!shader1 && shader2) {
|
else if (!shader1 && shader2) {
|
||||||
res = shader2 * fac;
|
res = shader2 * fac;
|
||||||
}
|
}
|
||||||
else if (shader1 && shader2) {
|
else if (shader1 && shader2) {
|
||||||
res = create_node("mix", NodeItem::type(shader_type_));
|
res = create_node("mix", shader_type_);
|
||||||
res.set_input("fg", shader1);
|
res.set_input("fg", shader1);
|
||||||
res.set_input("bg", shader2);
|
res.set_input("bg", shader2);
|
||||||
res.set_input("mix", fac);
|
res.set_input("mix", fac);
|
||||||
@ -31,9 +31,9 @@ NodeItem MixShaderNodeParser::compute()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NodeItem::Type::SurfaceShader: {
|
case NodeItem::Type::SurfaceShader: {
|
||||||
res = get_input_shader(1, shader_type_);
|
res = get_input_shader(1, NodeItem::Type::SurfaceShader);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
res = get_input_shader(2, shader_type_);
|
res = get_input_shader(2, NodeItem::Type::SurfaceShader);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ NodeItem NodeItem::operator+(const NodeItem &other) const
|
|||||||
/* Special case: add BSDF/EDF shaders */
|
/* Special case: add BSDF/EDF shaders */
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
if (other.type() == type) {
|
if (other.type() == type) {
|
||||||
res.node = graph_->addNode("add", MaterialX::EMPTY_STRING, this->type(type));
|
res = create_node("add", type);
|
||||||
res.set_input("in1", *this);
|
res.set_input("in1", *this);
|
||||||
res.set_input("in2", other);
|
res.set_input("in2", other);
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ NodeItem NodeItem::operator*(const NodeItem &other) const
|
|||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
Type other_type = other.type();
|
Type other_type = other.type();
|
||||||
if (ELEM(other_type, Type::Float, Type::Color3)) {
|
if (ELEM(other_type, Type::Float, Type::Color3)) {
|
||||||
res.node = graph_->addNode("multiply", MaterialX::EMPTY_STRING, this->type(type));
|
res = create_node("multiply", type);
|
||||||
res.set_input("in1", *this);
|
res.set_input("in1", *this);
|
||||||
res.set_input("in2", other);
|
res.set_input("in2", other);
|
||||||
}
|
}
|
||||||
@ -222,9 +222,8 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const
|
|||||||
{
|
{
|
||||||
NodeItem d = arithmetic(other, "dotproduct", [](float a, float b) { return a * b; });
|
NodeItem d = arithmetic(other, "dotproduct", [](float a, float b) { return a * b; });
|
||||||
if (d.value) {
|
if (d.value) {
|
||||||
Type mx_type = d.type();
|
|
||||||
float f = 0.0f;
|
float f = 0.0f;
|
||||||
switch (mx_type) {
|
switch (d.type()) {
|
||||||
case Type::Float: {
|
case Type::Float: {
|
||||||
f = value->asA<float>();
|
f = value->asA<float>();
|
||||||
break;
|
break;
|
||||||
@ -350,7 +349,7 @@ NodeItem NodeItem::exp() const
|
|||||||
NodeItem NodeItem::extract(const int index) const
|
NodeItem NodeItem::extract(const int index) const
|
||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
res.node = graph_->addNode("extract", MaterialX::EMPTY_STRING, "float");
|
res = create_node("extract", Type::Float);
|
||||||
res.set_input("in", *this);
|
res.set_input("in", *this);
|
||||||
res.set_input("index", val(index));
|
res.set_input("index", val(index));
|
||||||
return res;
|
return res;
|
||||||
@ -534,7 +533,7 @@ NodeItem NodeItem::convert(Type to_type) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.node = graph_->addNode("convert", MaterialX::EMPTY_STRING, type(to_type));
|
res = create_node("convert", to_type);
|
||||||
res.set_input("in", *this);
|
res.set_input("in", *this);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -569,18 +568,18 @@ NodeItem NodeItem::if_else(CompareOp op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::function<bool(float, float)> func = nullptr;
|
std::function<bool(float, float)> func = nullptr;
|
||||||
std::string mx_category;
|
std::string category;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case CompareOp::Greater:
|
case CompareOp::Greater:
|
||||||
mx_category = "ifgreater";
|
category = "ifgreater";
|
||||||
func = [](float a, float b) { return a > b; };
|
func = [](float a, float b) { return a > b; };
|
||||||
break;
|
break;
|
||||||
case CompareOp::GreaterEq:
|
case CompareOp::GreaterEq:
|
||||||
mx_category = "ifgreatereq";
|
category = "ifgreatereq";
|
||||||
func = [](float a, float b) { return a >= b; };
|
func = [](float a, float b) { return a >= b; };
|
||||||
break;
|
break;
|
||||||
case CompareOp::Eq:
|
case CompareOp::Eq:
|
||||||
mx_category = "ifequal";
|
category = "ifequal";
|
||||||
func = [](float a, float b) { return a == b; };
|
func = [](float a, float b) { return a == b; };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -591,7 +590,7 @@ NodeItem NodeItem::if_else(CompareOp op,
|
|||||||
res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2;
|
res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(to_type));
|
res = create_node(category, to_type);
|
||||||
res.set_input("value1", *this);
|
res.set_input("value1", *this);
|
||||||
res.set_input("value2", other);
|
res.set_input("value2", other);
|
||||||
res.set_input("in1", item1);
|
res.set_input("in1", item1);
|
||||||
@ -617,53 +616,67 @@ NodeItem::Type NodeItem::type() const
|
|||||||
return Type::Empty;
|
return Type::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeItem::set_input(const std::string &name,
|
NodeItem NodeItem::create_node(const std::string &category, NodeItem::Type type) const
|
||||||
const NodeItem &item,
|
{
|
||||||
const std::string &output_name)
|
std::string type_str = this->type(type);
|
||||||
|
CLOG_INFO(LOG_MATERIALX_SHADER, 2, "<%s type=%s>", category.c_str(), type_str.c_str());
|
||||||
|
NodeItem res = empty();
|
||||||
|
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, type_str);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeItem::set_input(const std::string &in_name, const NodeItem &item)
|
||||||
{
|
{
|
||||||
if (item.value) {
|
if (item.value) {
|
||||||
Type item_type = item.type();
|
Type item_type = item.type();
|
||||||
std::string mx_type = type(item_type);
|
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
case Type::String:
|
case Type::String:
|
||||||
set_input(name, item.value->asA<std::string>(), mx_type);
|
set_input(in_name, item.value->asA<std::string>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Integer:
|
case Type::Integer:
|
||||||
set_input(name, item.value->asA<int>(), mx_type);
|
set_input(in_name, item.value->asA<int>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Float:
|
case Type::Float:
|
||||||
set_input(name, item.value->asA<float>(), mx_type);
|
set_input(in_name, item.value->asA<float>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Vector2:
|
case Type::Vector2:
|
||||||
set_input(name, item.value->asA<MaterialX::Vector2>(), mx_type);
|
set_input(in_name, item.value->asA<MaterialX::Vector2>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Vector3:
|
case Type::Vector3:
|
||||||
set_input(name, item.value->asA<MaterialX::Vector3>(), mx_type);
|
set_input(in_name, item.value->asA<MaterialX::Vector3>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Vector4:
|
case Type::Vector4:
|
||||||
set_input(name, item.value->asA<MaterialX::Vector4>(), mx_type);
|
set_input(in_name, item.value->asA<MaterialX::Vector4>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Color3:
|
case Type::Color3:
|
||||||
set_input(name, item.value->asA<MaterialX::Color3>(), mx_type);
|
set_input(in_name, item.value->asA<MaterialX::Color3>(), item_type);
|
||||||
break;
|
break;
|
||||||
case Type::Color4:
|
case Type::Color4:
|
||||||
set_input(name, item.value->asA<MaterialX::Color4>(), mx_type);
|
set_input(in_name, item.value->asA<MaterialX::Color4>(), item_type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item.node) {
|
else if (item.node) {
|
||||||
node->setConnectedNode(name, item.node);
|
node->setConnectedNode(in_name, item.node);
|
||||||
if (output_name != "") {
|
|
||||||
node->setConnectedOutput(name, item.node->getOutput(output_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", name.c_str());
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", in_name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeItem::set_input_output(const std::string &in_name,
|
||||||
|
const NodeItem &item,
|
||||||
|
const std::string &out_name)
|
||||||
|
{
|
||||||
|
if (!item.node) {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
node->setConnectedNode(in_name, item.node);
|
||||||
|
node->setConnectedOutput(in_name, item.node->getOutput(out_name));
|
||||||
|
}
|
||||||
|
|
||||||
void NodeItem::add_output(const std::string &name, Type out_type)
|
void NodeItem::add_output(const std::string &name, Type out_type)
|
||||||
{
|
{
|
||||||
node->addOutput(name, type(out_type));
|
node->addOutput(name, type(out_type));
|
||||||
@ -751,7 +764,7 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function<float(f
|
|||||||
else {
|
else {
|
||||||
/* TODO: Some of math functions (sin, cos, ...) doesn't work with Color types,
|
/* TODO: Some of math functions (sin, cos, ...) doesn't work with Color types,
|
||||||
* we have to convert to Vector */
|
* we have to convert to Vector */
|
||||||
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, this->type(type));
|
res = create_node(category, type);
|
||||||
res.set_input("in", *this);
|
res.set_input("in", *this);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -817,7 +830,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, type(to_type));
|
res = create_node(category, to_type);
|
||||||
res.set_input("in1", item1);
|
res.set_input("in1", item1);
|
||||||
res.set_input("in2", item2);
|
res.set_input("in2", item2);
|
||||||
}
|
}
|
||||||
|
@ -97,13 +97,14 @@ class NodeItem {
|
|||||||
NodeItem empty() const;
|
NodeItem empty() const;
|
||||||
template<class T> NodeItem val(const T &data) const;
|
template<class T> NodeItem val(const T &data) const;
|
||||||
Type type() const;
|
Type type() const;
|
||||||
|
NodeItem create_node(const std::string &category, NodeItem::Type type) const;
|
||||||
|
|
||||||
/* Functions to set input and output */
|
/* Functions to set input and output */
|
||||||
template<class T>
|
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 T &value, const std::string &in_type);
|
void set_input(const std::string &in_name, const NodeItem &item);
|
||||||
void set_input(const std::string &in_name,
|
void set_input_output(const std::string &in_name,
|
||||||
const NodeItem &item,
|
const NodeItem &item,
|
||||||
const std::string &out_name = "");
|
const std::string &out_name);
|
||||||
void add_output(const std::string &in_name, Type out_type);
|
void add_output(const std::string &in_name, Type out_type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -125,9 +126,9 @@ template<class T> NodeItem NodeItem::val(const T &data) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void NodeItem::set_input(const std::string &in_name, const T &value, const std::string &in_type)
|
void NodeItem::set_input(const std::string &in_name, const T &value, Type in_type)
|
||||||
{
|
{
|
||||||
node->setInputValue(in_name, value, in_type);
|
node->setInputValue(in_name, value, type(in_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -39,11 +39,9 @@ std::string NodeParser::node_name()
|
|||||||
std::string(node_->name) + "_" + socket_out_->name);
|
std::string(node_->name) + "_" + socket_out_->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type)
|
NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type type)
|
||||||
{
|
{
|
||||||
NodeItem res = empty();
|
return empty().create_node(category, type);
|
||||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, mx_type);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)
|
NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)
|
||||||
|
@ -33,7 +33,7 @@ class NodeParser {
|
|||||||
protected:
|
protected:
|
||||||
virtual NodeItem compute_full();
|
virtual NodeItem compute_full();
|
||||||
virtual std::string node_name();
|
virtual std::string node_name();
|
||||||
NodeItem create_node(const std::string &mx_category, const std::string &mx_type);
|
NodeItem create_node(const std::string &category, NodeItem::Type type);
|
||||||
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
|
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
|
||||||
NodeItem get_input_default(int index, NodeItem::Type to_type);
|
NodeItem get_input_default(int index, NodeItem::Type to_type);
|
||||||
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
|
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
|
||||||
@ -41,7 +41,7 @@ class NodeParser {
|
|||||||
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
|
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
|
||||||
NodeItem get_input_value(int index, NodeItem::Type to_type);
|
NodeItem get_input_value(int index, NodeItem::Type to_type);
|
||||||
NodeItem empty() const;
|
NodeItem empty() const;
|
||||||
template<class T> NodeItem value(const T &data) const;
|
template<class T> NodeItem val(const T &data) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
|
NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
|
||||||
@ -71,7 +71,7 @@ class ShaderNodeParser : public NodeParser {
|
|||||||
NodeItem get_input_shader(const bNodeSocket &socket, NodeItem::Type shader_type);
|
NodeItem get_input_shader(const bNodeSocket &socket, NodeItem::Type shader_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> NodeItem NodeParser::value(const T &data) const
|
template<class T> NodeItem NodeParser::val(const T &data) const
|
||||||
{
|
{
|
||||||
return empty().val(data);
|
return empty().val(data);
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,19 @@ NodeItem NormalMapNodeParser::compute()
|
|||||||
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
||||||
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
|
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
|
||||||
|
|
||||||
NodeItem res = create_node("normalmap", "vector3");
|
NodeItem res = create_node("normalmap", NodeItem::Type::Vector3);
|
||||||
res.set_input("in", color);
|
res.set_input("in", color);
|
||||||
res.set_input("scale", strength);
|
res.set_input("scale", strength);
|
||||||
|
|
||||||
switch (normal_map_node->space) {
|
switch (normal_map_node->space) {
|
||||||
case SHD_SPACE_TANGENT:
|
case SHD_SPACE_TANGENT:
|
||||||
res.set_input("space", value(std::string("tangent")));
|
res.set_input("space", val(std::string("tangent")));
|
||||||
break;
|
break;
|
||||||
case SHD_SPACE_OBJECT:
|
case SHD_SPACE_OBJECT:
|
||||||
res.set_input("space", value(std::string("tangent")));
|
res.set_input("space", val(std::string("tangent")));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res.set_input("space", value(default_space));
|
res.set_input("space", val(default_space));
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER,
|
CLOG_WARN(LOG_MATERIALX_SHADER,
|
||||||
"Ignoring unsupported Space: %d %s (%d), %s will be used",
|
"Ignoring unsupported Space: %d %s (%d), %s will be used",
|
||||||
normal_map_node->space,
|
normal_map_node->space,
|
||||||
|
@ -20,7 +20,7 @@ NodeItem OutputMaterialNodeParser::compute()
|
|||||||
NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF);
|
NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF);
|
||||||
NodeItem edf = get_input_shader("Surface", NodeItem::Type::EDF);
|
NodeItem edf = get_input_shader("Surface", NodeItem::Type::EDF);
|
||||||
if (bsdf || edf) {
|
if (bsdf || edf) {
|
||||||
surface = create_node("surface", "surfaceshader");
|
surface = create_node("surface", NodeItem::Type::SurfaceShader);
|
||||||
if (bsdf) {
|
if (bsdf) {
|
||||||
surface.set_input("bsdf", bsdf);
|
surface.set_input("bsdf", bsdf);
|
||||||
}
|
}
|
||||||
@ -33,30 +33,30 @@ NodeItem OutputMaterialNodeParser::compute()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
surface = create_node("standard_surface", "surfaceshader");
|
surface = create_node("standard_surface", NodeItem::Type::SurfaceShader);
|
||||||
surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
|
surface.set_input("base_color", val(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
|
||||||
}
|
}
|
||||||
NodeItem res = create_node("surfacematerial", "material");
|
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
|
||||||
res.set_input("surfaceshader", surface);
|
res.set_input("surfaceshader", surface);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem OutputMaterialNodeParser::compute_default()
|
NodeItem OutputMaterialNodeParser::compute_default()
|
||||||
{
|
{
|
||||||
NodeItem surface = create_node("standard_surface", "surfaceshader");
|
NodeItem surface = create_node("standard_surface", NodeItem::Type::SurfaceShader);
|
||||||
surface.set_input("base_color",
|
surface.set_input("base_color",
|
||||||
value(MaterialX::Color3(material_->r, material_->g, material_->b)));
|
val(MaterialX::Color3(material_->r, material_->g, material_->b)));
|
||||||
surface.set_input("diffuse_roughness", value(material_->roughness));
|
surface.set_input("diffuse_roughness", val(material_->roughness));
|
||||||
if (material_->metallic > 0.0f) {
|
if (material_->metallic > 0.0f) {
|
||||||
surface.set_input("metalness", value(material_->metallic));
|
surface.set_input("metalness", val(material_->metallic));
|
||||||
}
|
}
|
||||||
if (material_->spec) {
|
if (material_->spec) {
|
||||||
surface.set_input("specular", value(material_->spec));
|
surface.set_input("specular", val(material_->spec));
|
||||||
surface.set_input("specular_color", value(material_->spec));
|
surface.set_input("specular_color", val(material_->spec));
|
||||||
surface.set_input("specular_roughness", value(material_->roughness));
|
surface.set_input("specular_roughness", val(material_->roughness));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem res = create_node("surfacematerial", "material");
|
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
|
||||||
res.node->setName("Material_Default");
|
res.node->setName("Material_Default");
|
||||||
res.set_input("surfaceshader", surface);
|
res.set_input("surfaceshader", surface);
|
||||||
return res;
|
return res;
|
||||||
|
@ -18,12 +18,12 @@ NodeItem SeparateColorNodeParser::compute()
|
|||||||
case NODE_COMBSEP_COLOR_RGB:
|
case NODE_COMBSEP_COLOR_RGB:
|
||||||
break;
|
break;
|
||||||
case NODE_COMBSEP_COLOR_HSV:
|
case NODE_COMBSEP_COLOR_HSV:
|
||||||
convert = create_node("rgbtohsv", "color3");
|
convert = create_node("rgbtohsv", NodeItem::Type::Color3);
|
||||||
convert.set_input("in", color);
|
convert.set_input("in", color);
|
||||||
break;
|
break;
|
||||||
case NODE_COMBSEP_COLOR_HSL:
|
case NODE_COMBSEP_COLOR_HSL:
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported color model, using HSV instead: %d", mode);
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported color model, using HSV instead: %d", mode);
|
||||||
convert = create_node("rgbtohsv", "color3");
|
convert = create_node("rgbtohsv", NodeItem::Type::Color3);
|
||||||
convert.set_input("in", color);
|
convert.set_input("in", color);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -44,7 +44,7 @@ NodeItem CombineColorNodeParser::compute()
|
|||||||
NodeItem blue = get_input_value("Blue", NodeItem::Type::Float);
|
NodeItem blue = get_input_value("Blue", NodeItem::Type::Float);
|
||||||
|
|
||||||
NodeItem convert = empty();
|
NodeItem convert = empty();
|
||||||
NodeItem combine = create_node("combine3", "color3");
|
NodeItem combine = create_node("combine3", NodeItem::Type::Color3);
|
||||||
combine.set_input("in1", red);
|
combine.set_input("in1", red);
|
||||||
combine.set_input("in2", green);
|
combine.set_input("in2", green);
|
||||||
combine.set_input("in3", blue);
|
combine.set_input("in3", blue);
|
||||||
@ -53,12 +53,12 @@ NodeItem CombineColorNodeParser::compute()
|
|||||||
case NODE_COMBSEP_COLOR_RGB:
|
case NODE_COMBSEP_COLOR_RGB:
|
||||||
break;
|
break;
|
||||||
case NODE_COMBSEP_COLOR_HSV:
|
case NODE_COMBSEP_COLOR_HSV:
|
||||||
convert = create_node("hsvtorgb", "color3");
|
convert = create_node("hsvtorgb", NodeItem::Type::Color3);
|
||||||
convert.set_input("in", combine);
|
convert.set_input("in", combine);
|
||||||
break;
|
break;
|
||||||
case NODE_COMBSEP_COLOR_HSL:
|
case NODE_COMBSEP_COLOR_HSL:
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported color model, using HSV instead: %d", mode);
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported color model, using HSV instead: %d", mode);
|
||||||
convert = create_node("hsvtorgb", "color3");
|
convert = create_node("hsvtorgb", NodeItem::Type::Color3);
|
||||||
convert.set_input("in", combine);
|
convert.set_input("in", combine);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -18,7 +18,7 @@ NodeItem CombineXYZNodeParser::compute()
|
|||||||
NodeItem x = get_input_value("X", NodeItem::Type::Float);
|
NodeItem x = get_input_value("X", NodeItem::Type::Float);
|
||||||
NodeItem y = get_input_value("Y", NodeItem::Type::Float);
|
NodeItem y = get_input_value("Y", NodeItem::Type::Float);
|
||||||
NodeItem z = get_input_value("Z", NodeItem::Type::Float);
|
NodeItem z = get_input_value("Z", NodeItem::Type::Float);
|
||||||
NodeItem res = create_node("combine3", "vector3");
|
NodeItem res = create_node("combine3", NodeItem::Type::Vector3);
|
||||||
res.set_input("in1", x);
|
res.set_input("in1", x);
|
||||||
res.set_input("in2", y);
|
res.set_input("in2", y);
|
||||||
res.set_input("in3", z);
|
res.set_input("in3", z);
|
||||||
|
@ -14,12 +14,12 @@ NodeItem TexCheckerNodeParser::compute()
|
|||||||
NodeItem scale = get_input_value("Scale", NodeItem::Type::Float);
|
NodeItem scale = get_input_value("Scale", NodeItem::Type::Float);
|
||||||
|
|
||||||
if (!vector) {
|
if (!vector) {
|
||||||
vector = create_node("texcoord", "vector2");
|
vector = create_node("texcoord", NodeItem::Type::Vector2);
|
||||||
}
|
}
|
||||||
vector = (vector * scale) % value(2.0f);
|
vector = (vector * scale) % val(2.0f);
|
||||||
NodeItem mix = (vector.extract(0).floor() + vector.extract(1).floor())
|
NodeItem mix = (vector.extract(0).floor() + vector.extract(1).floor())
|
||||||
.if_else(NodeItem::CompareOp::Eq, value(1.0f), value(1.0f), value(0.0f));
|
.if_else(NodeItem::CompareOp::Eq, val(1.0f), val(1.0f), val(0.0f));
|
||||||
NodeItem res = create_node("mix", "color3");
|
NodeItem res = create_node("mix", NodeItem::Type::Color3);
|
||||||
res.set_input("fg", color1);
|
res.set_input("fg", color1);
|
||||||
res.set_input("bg", color2);
|
res.set_input("bg", color2);
|
||||||
res.set_input("mix", mix);
|
res.set_input("mix", mix);
|
||||||
|
@ -23,9 +23,9 @@ NodeItem TexEnvironmentNodeParser::compute()
|
|||||||
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeItem texcoord = create_node("texcoord", "vector2");
|
NodeItem texcoord = create_node("texcoord", NodeItem::Type::Vector2);
|
||||||
NodeItem res = create_node("image", "color3");
|
NodeItem res = create_node("image", NodeItem::Type::Color3);
|
||||||
res.set_input("file", image_path, "filename");
|
res.set_input("file", image_path, NodeItem::Type::Filename);
|
||||||
res.set_input("texcoord", texcoord);
|
res.set_input("texcoord", texcoord);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ NodeItem TexImageNodeParser::compute()
|
|||||||
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeItem texcoord = create_node("texcoord", "vector2");
|
NodeItem texcoord = create_node("texcoord", NodeItem::Type::Vector2);
|
||||||
NodeItem res = create_node("image", "color3");
|
NodeItem res = create_node("image", NodeItem::Type::Color3);
|
||||||
res.set_input("file", image_path, "filename");
|
res.set_input("file", image_path, NodeItem::Type::Filename);
|
||||||
res.set_input("texcoord", texcoord);
|
res.set_input("texcoord", texcoord);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,13 @@ NodeItem TexNoiseNodeParser::compute()
|
|||||||
NodeItem lacunarity = get_input_value("Lacunarity", NodeItem::Type::Float);
|
NodeItem lacunarity = get_input_value("Lacunarity", NodeItem::Type::Float);
|
||||||
|
|
||||||
if (detail.value && detail.type() == NodeItem::Type::Float) {
|
if (detail.value && detail.type() == NodeItem::Type::Float) {
|
||||||
detail = value(int(detail.value->asA<float>()));
|
detail = val(int(detail.value->asA<float>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem position = create_node("position", "vector3");
|
NodeItem position = create_node("position", NodeItem::Type::Vector3);
|
||||||
position = position * scale;
|
position = position * scale;
|
||||||
|
|
||||||
NodeItem res = create_node("fractal3d", "color3");
|
NodeItem res = create_node("fractal3d", NodeItem::Type::Color3);
|
||||||
res.set_input("position", position);
|
res.set_input("position", position);
|
||||||
res.set_input("octaves", detail);
|
res.set_input("octaves", detail);
|
||||||
res.set_input("lacunarity", lacunarity);
|
res.set_input("lacunarity", lacunarity);
|
||||||
|
@ -35,7 +35,7 @@ NodeItem VectorMathNodeParser::compute()
|
|||||||
res = x.ceil();
|
res = x.ceil();
|
||||||
break;
|
break;
|
||||||
case NODE_VECTOR_MATH_FRACTION:
|
case NODE_VECTOR_MATH_FRACTION:
|
||||||
res = x % value(1.0f);
|
res = x % val(1.0f);
|
||||||
break;
|
break;
|
||||||
case NODE_VECTOR_MATH_LENGTH:
|
case NODE_VECTOR_MATH_LENGTH:
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
||||||
|
Loading…
Reference in New Issue
Block a user