MaterialX: add convert nodes #15

Merged
Bogdan Nagirniak merged 8 commits from matx-add-convert-nodes into matx-export-material 2023-09-08 16:55:00 +02:00
9 changed files with 141 additions and 2 deletions

View File

@ -148,6 +148,7 @@ if(WITH_MATERIALX)
list(APPEND SRC
materialx/material.cc
materialx/nodes/add_shader.cc
materialx/nodes/blackbody.cc
materialx/nodes/brightness.cc
materialx/nodes/bsdf_diffuse.cc
materialx/nodes/bsdf_glass.cc
@ -158,9 +159,11 @@ if(WITH_MATERIALX)
materialx/nodes/bsdf_toon.cc
materialx/nodes/bsdf_translucent.cc
materialx/nodes/bsdf_transparent.cc
materialx/nodes/clamp.cc
materialx/nodes/emission.cc
materialx/nodes/huesatval.cc
materialx/nodes/invert.cc
materialx/nodes/map_range.cc
materialx/nodes/math.cc
materialx/nodes/mix_rgb.cc
materialx/nodes/mix_shader.cc
@ -168,15 +171,16 @@ if(WITH_MATERIALX)
materialx/nodes/node_parser.cc
materialx/nodes/normal_map.cc
materialx/nodes/output_material.cc
materialx/nodes/rgb_to_bw.cc
materialx/nodes/sepcomb_color.cc
materialx/nodes/sepcomb_xyz.cc
materialx/nodes/subsurface_scattering.cc
materialx/nodes/tex_checker.cc
materialx/nodes/tex_environment.cc
materialx/nodes/tex_image.cc
materialx/nodes/tex_noise.cc
materialx/nodes/tex_noise.cc
materialx/nodes/vector_math.cc
materialx/material.h
materialx/nodes/node_item.h
materialx/nodes/node_parser.h

View File

@ -0,0 +1,22 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BlackbodyNodeParser::compute()
{
/* This node doesn't have an implementation in MaterialX 1.38.6.
* It's added in MaterialX 1.38.8. Uncomment this code after switching to 1.38.8.
BogdanNagirniak marked this conversation as resolved Outdated

It is exists in pbrlib_def.mtlx, can be used here

It is exists in pbrlib_def.mtlx, can be used here
*
* NodeItem temperature = get_input_value("Temperature", NodeItem::Type::Float);
* NodeItem res = create_node("blackbody", NodeItem::Type::Color3);
* res.set_input("temperature", temperature);
* return res; */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,27 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem ClampNodeParser::compute()
{
auto type = node_->custom1;
NodeItem value = get_input_value("Value", NodeItem::Type::Float);
NodeItem min = get_input_value("Min", NodeItem::Type::Float);
NodeItem max = get_input_value("Max", NodeItem::Type::Float);
NodeItem res = empty();
if (type == NODE_CLAMP_RANGE) {
BogdanNagirniak marked this conversation as resolved Outdated

min = min.min(max)

`min = min.min(max)`
res = min.if_else(
NodeItem::CompareOp::Less, max, value.clamp(min, max), value.clamp(max, min));
BogdanNagirniak marked this conversation as resolved Outdated

does it correctly work with RANGE? do we need swap min max if min > max?

does it correctly work with RANGE? do we need swap min max if min > max?
}
else {
res = value.clamp(min, max);
}
return res;
}
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,51 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem MapRangeNodeParser::compute()
{
/* Interpolation isn't supported by MaterialX. */
const NodeMapRange *map_range = static_cast<NodeMapRange *>(node_->storage);
NodeItem::Type type;
NodeItem value = empty();
NodeItem from_min = empty();
NodeItem from_max = empty();
NodeItem to_min = empty();
NodeItem to_max = empty();
switch (map_range->data_type) {
case CD_PROP_FLOAT:
type = NodeItem::Type::Float;
value = get_input_value("Value", type);
from_min = get_input_value(1, type);
from_max = get_input_value(2, type);
to_min = get_input_value(3, type);
to_max = get_input_value(4, type);
break;
case CD_PROP_FLOAT3:
type = NodeItem::Type::Vector3;
value = get_input_value("Vector", type);
from_min = get_input_value(7, type);
from_max = get_input_value(8, type);
to_min = get_input_value(9, type);
to_max = get_input_value(10, type);
break;
default:
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;
}
} // namespace blender::nodes::materialx

View File

@ -20,6 +20,9 @@ NodeItem::Type NodeItem::type(const std::string &type_str)
if (type_str == "filename") {
return Type::Filename;
}
if (type_str == "boolean") {
return Type::Boolean;
}
if (type_str == "integer") {
return Type::Integer;
}
@ -64,6 +67,8 @@ std::string NodeItem::type(Type type)
return "string";
case Type::Filename:
return "filename";
case Type::Boolean:
return "boolean";
case Type::Integer:
return "integer";
case Type::Float:
@ -633,6 +638,9 @@ void NodeItem::set_input(const std::string &in_name, const NodeItem &item)
case Type::String:
set_input(in_name, item.value->asA<std::string>(), item_type);
break;
case Type::Boolean:
set_input(in_name, item.value->asA<bool>(), item_type);
break;
case Type::Integer:
set_input(in_name, item.value->asA<int>(), item_type);
break;

View File

@ -17,6 +17,7 @@ class NodeItem {
/* Value types */
String,
Filename,
Boolean,
BogdanNagirniak marked this conversation as resolved Outdated

Maybe rename to Boolean, as we use full names for other types?

Maybe rename to Boolean, as we use full names for other types?
Integer,
/* Block of arithmetic types. Ordered by type cast */
Float,

View File

@ -136,14 +136,18 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
break;
switch (from_node->typeinfo->type) {
CASE_NODE_TYPE(SH_NODE_BLACKBODY, BlackbodyNodeParser)
CASE_NODE_TYPE(SH_NODE_BRIGHTCONTRAST, BrightContrastNodeParser)
CASE_NODE_TYPE(SH_NODE_CLAMP, ClampNodeParser)
CASE_NODE_TYPE(SH_NODE_COMBINE_COLOR, CombineColorNodeParser)
CASE_NODE_TYPE(SH_NODE_COMBXYZ, CombineXYZNodeParser)
CASE_NODE_TYPE(SH_NODE_HUE_SAT, HueSatValNodeParser)
CASE_NODE_TYPE(SH_NODE_INVERT, InvertNodeParser)
CASE_NODE_TYPE(SH_NODE_MAP_RANGE, MapRangeNodeParser)
CASE_NODE_TYPE(SH_NODE_MATH, MathNodeParser)
CASE_NODE_TYPE(SH_NODE_MIX_RGB_LEGACY, MixRGBNodeParser)
CASE_NODE_TYPE(SH_NODE_NORMAL_MAP, NormalMapNodeParser)
CASE_NODE_TYPE(SH_NODE_RGBTOBW, RGBToBWNodeParser)
CASE_NODE_TYPE(SH_NODE_SEPARATE_COLOR, SeparateColorNodeParser)
CASE_NODE_TYPE(SH_NODE_SEPXYZ, SeparateXYZNodeParser)
CASE_NODE_TYPE(SH_NODE_TEX_CHECKER, TexCheckerNodeParser)

View File

@ -90,14 +90,18 @@ template<class T> NodeItem NodeParser::val(const T &data) const
NodeItem compute() override; \
};
DECLARE_NODE_PARSER(BlackbodyNodeParser)
DECLARE_NODE_PARSER(BrightContrastNodeParser)
DECLARE_NODE_PARSER(ClampNodeParser)
DECLARE_NODE_PARSER(CombineColorNodeParser)
DECLARE_NODE_PARSER(CombineXYZNodeParser)
DECLARE_NODE_PARSER(HueSatValNodeParser)
DECLARE_NODE_PARSER(InvertNodeParser)
DECLARE_NODE_PARSER(MapRangeNodeParser)
DECLARE_NODE_PARSER(MathNodeParser)
DECLARE_NODE_PARSER(MixRGBNodeParser)
DECLARE_NODE_PARSER(NormalMapNodeParser)
DECLARE_NODE_PARSER(RGBToBWNodeParser)
DECLARE_NODE_PARSER(SeparateColorNodeParser)
DECLARE_NODE_PARSER(SeparateXYZNodeParser)
DECLARE_NODE_PARSER(TexCheckerNodeParser)

View File

@ -0,0 +1,18 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem RGBToBWNodeParser::compute()
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
BogdanNagirniak marked this conversation as resolved Outdated

use Color4 type

use Color4 type
NodeItem res = create_node("luminance", NodeItem::Type::Color4);
res.set_input("in", color);
return res;
}
} // namespace blender::nodes::materialx