From 276bbbd55485f630243639534c5650e6f44c2ed0 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 14:29:39 +0300 Subject: [PATCH 01/16] NodeItem: extract -> operator[], blend() -> mix() + added shaders support. Code improvements in some nodes. --- .../nodes/shader/materialx/node_item.cc | 70 +++++++++++++++---- .../nodes/shader/materialx/node_item.h | 4 +- .../nodes/shader/materialx/node_parser.cc | 13 ++-- .../nodes/shader/materialx/node_parser.h | 2 +- .../nodes/shader/nodes/node_shader_invert.cc | 2 +- .../shader/nodes/node_shader_mix_shader.cc | 2 +- .../shader/nodes/node_shader_sepcomb_color.cc | 2 +- .../shader/nodes/node_shader_sepcomb_xyz.cc | 2 +- .../shader/nodes/node_shader_tex_brick.cc | 10 +-- .../shader/nodes/node_shader_tex_checker.cc | 10 +-- .../shader/nodes/node_shader_tex_gradient.cc | 10 +-- .../shader/nodes/node_shader_tex_image.cc | 2 +- .../shader/nodes/node_shader_tex_wave.cc | 70 +++++++++---------- 13 files changed, 121 insertions(+), 78 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index c1fa1d64bf6..5e2be49eb7e 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -177,6 +177,36 @@ NodeItem NodeItem::operator^(const NodeItem &other) const return arithmetic(other, "power", [](float a, float b) { return std::powf(a, b); }); } +NodeItem NodeItem::operator[](int index) const +{ + if (value) { + float v = 0.0f; + switch (type()) { + case Type::Float: + v = value->asA(); + break; + case Type::Vector2: + v = value->asA()[index]; + case Type::Vector3: + v = value->asA()[index]; + break; + case Type::Vector4: + v = value->asA()[index]; + break; + case Type::Color3: + v = value->asA()[index]; + break; + case Type::Color4: + v = value->asA()[index]; + break; + default: + BLI_assert_unreachable(); + } + return val(v); + } + return create_node("extract", Type::Float, {{"in", *this}, {"index", val(index)}}); +} + bool NodeItem::operator==(const NodeItem &other) const { if (!*this) { @@ -233,9 +263,8 @@ NodeItem NodeItem::max(const NodeItem &other) const NodeItem NodeItem::dotproduct(const NodeItem &other) const { - NodeItem d = arithmetic( - other, "dotproduct", [](float a, float b) { return a * b; }, Type::Float); - if (d.value) { + if (value && other.value) { + NodeItem d = *this * other; float f = 0.0f; switch (d.type()) { case Type::Float: { @@ -270,14 +299,32 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const default: BLI_assert_unreachable(); } - d.value = MaterialX::Value::createValue(f); + return val(f); } - return d; + + return create_node("dotproduct", Type::Float, {{"in1", *this}, {"in2", other}}); } -NodeItem NodeItem::blend(const NodeItem &a, const NodeItem &b) const +NodeItem NodeItem::mix(const NodeItem &val1, const NodeItem &val2) const { - return (val(1.0f) - *this) * a + *this * b; + BLI_assert(type() == Type::Float); + + if (value && val1.value && val2.value) { + return (val(1.0f) - *this) * val1 + *this * val2; + } + + Type type1 = val1.type(); + if (ELEM(type1, Type::BSDF, Type::EDF)) { + BLI_assert(val2.type() == type1); + + /* Special case: mix BSDF/EDF shaders */ + return create_node("mix", type1, {{}, {}}); + }; + + NodeItem item1 = val1; + NodeItem item2 = val2; + Type to_type = cast_types(item1, item2); + return create_node("mix", to_type, {{"bg", item1}, {"fg", item2}}); } NodeItem NodeItem::clamp(const NodeItem &min_val, const NodeItem &max_val) const @@ -375,7 +422,7 @@ NodeItem NodeItem::convert(Type to_type) const } if (to_type == Type::Float) { - return extract(0); + return (*this)[0]; } /* Converting types which requires > 1 iteration */ @@ -601,13 +648,6 @@ NodeItem NodeItem::if_else(CompareOp op, return res; } -NodeItem NodeItem::extract(const int index) const -{ - /* TODO: Add check if (value) { ... } */ - NodeItem res = create_node("extract", Type::Float, {{"in", *this}, {"index", val(index)}}); - return res; -} - NodeItem NodeItem::empty() const { return NodeItem(graph_); diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index d1c7cb81d0c..0305e68ac75 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -73,6 +73,7 @@ class NodeItem { NodeItem operator/(const NodeItem &other) const; NodeItem operator%(const NodeItem &other) const; NodeItem operator^(const NodeItem &other) const; + NodeItem operator[](int index) const; bool operator==(const NodeItem &other) const; bool operator!=(const NodeItem &other) const; @@ -83,7 +84,7 @@ class NodeItem { NodeItem min(const NodeItem &other) const; NodeItem max(const NodeItem &other) const; NodeItem dotproduct(const NodeItem &other) const; - NodeItem blend(const NodeItem &a, const NodeItem &b) const; + NodeItem mix(const NodeItem &val1, const NodeItem &val2) const; NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const; NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const; NodeItem sin() const; @@ -105,7 +106,6 @@ class NodeItem { const NodeItem &other, const NodeItem &if_val, const NodeItem &else_val) const; - NodeItem extract(const int index) const; /* Useful functions */ NodeItem empty() const; diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index 158a8be3351..e3522c557a6 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -146,13 +146,18 @@ NodeItem NodeParser::empty() const return NodeItem(graph_); } -NodeItem NodeParser::texcoord_node() +NodeItem NodeParser::texcoord_node(NodeItem::Type type) { + BLI_assert(ELEM(type, NodeItem::Type::Vector2, NodeItem::Type::Vector3)); + std::string name = TEXCOORD_NODE_NAME; + if (type == NodeItem::Type::Vector3) { + name += "_vector3"; + } NodeItem res = empty(); - res.node = graph_->getNode(TEXCOORD_NODE_NAME); + res.node = graph_->getNode(name); if (!res.node) { - res = create_node("texcoord", NodeItem::Type::Vector2); - res.node->setName(TEXCOORD_NODE_NAME); + res = create_node("texcoord", type); + res.node->setName(name); } return res; } diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index eaaa5c1d35b..05b510af413 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -59,7 +59,7 @@ class NodeParser { NodeItem get_input_value(int index, NodeItem::Type to_type); NodeItem empty() const; template NodeItem val(const T &data) const; - NodeItem texcoord_node(); + NodeItem texcoord_node(NodeItem::Type type = NodeItem::Type::Vector2); private: NodeItem get_default(const bNodeSocket &socket, NodeItem::Type to_type); diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.cc b/source/blender/nodes/shader/nodes/node_shader_invert.cc index 332d3b4e055..8246662d3ec 100644 --- a/source/blender/nodes/shader/nodes/node_shader_invert.cc +++ b/source/blender/nodes/shader/nodes/node_shader_invert.cc @@ -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, val(1.0f) - color); + return fac.mix(color, val(1.0f) - color); } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc index 08a671f5cab..ada5b6a6911 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc @@ -41,7 +41,7 @@ NODE_SHADER_MATERIALX_BEGIN res = shader2 * fac; } else if (shader1 && shader2) { - res = create_node("mix", to_type_, {{"fg", shader2}, {"bg", shader1}, {"mix", fac}}); + res = fac.mix(shader1, shader2); } break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc index eaf7f5f4d93..32c1e0def8d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_color.cc @@ -89,7 +89,7 @@ NODE_SHADER_MATERIALX_BEGIN } int index = STREQ(socket_out_->name, "Red") ? 0 : STREQ(socket_out_->name, "Green") ? 1 : 2; - return convert.extract(index); + return convert[index]; } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 4cf874e903e..b387a28d35b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -95,7 +95,7 @@ NODE_SHADER_MATERIALX_BEGIN { NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3); int index = STREQ(socket_out_->name, "X") ? 0 : STREQ(socket_out_->name, "Y") ? 1 : 2; - return vector.extract(index); + return vector[index]; } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index aa00e08e00f..8f588acbdfa 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -160,7 +160,7 @@ class BrickFunction : public mf::MultiFunction { return (3.0f * ff - 2.0f * ff * f); } - static float2 brick(float3 p, + static float2 brick(float3 pos, float mortar_size, float mortar_smooth, float bias, @@ -173,17 +173,17 @@ class BrickFunction : public mf::MultiFunction { { float offset = 0.0f; - const int rownum = int(floorf(p.y / row_height)); + const int rownum = int(floorf(pos.y / row_height)); if (offset_frequency && squash_frequency) { brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount); } - const int bricknum = int(floorf((p.x + offset) / brick_width)); + const int bricknum = int(floorf((pos.x + offset) / brick_width)); - const float x = (p.x + offset) - brick_width * bricknum; - const float y = p.y - row_height * rownum; + const float x = (pos.x + offset) - brick_width * bricknum; + const float y = pos.y - row_height * rownum; const float tint = clamp_f( brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias, 0.0f, 1.0f); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index 40dd136fafc..f7649ea5c32 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -80,11 +80,11 @@ class NodeTexChecker : public mf::MultiFunction { mask.foreach_index([&](const int64_t i) { /* Avoid precision issues on unit coordinates. */ - const float3 p = (vector[i] * scale[i] + 0.000001f) * 0.999999f; + const float3 pos = (vector[i] * scale[i] + 0.000001f) * 0.999999f; - const int xi = abs(int(floorf(p.x))); - const int yi = abs(int(floorf(p.y))); - const int zi = abs(int(floorf(p.z))); + const int xi = abs(int(floorf(pos.x))); + const int yi = abs(int(floorf(pos.y))); + const int zi = abs(int(floorf(pos.z))); r_fac[i] = ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f; }); @@ -118,7 +118,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem scale = get_input_value("Scale", NodeItem::Type::Float); vector = (vector * scale) % val(2.0f); - return (vector.extract(0).floor() + vector.extract(1).floor()) + return (vector[0].floor() + vector[1].floor()) .if_else(NodeItem::CompareOp::Eq, val(1.0f), value1, value2); } #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index 989a1e527ec..7dd9ad194bb 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -160,21 +160,21 @@ NODE_SHADER_MATERIALX_BEGIN switch (gradient_type) { case SHD_BLEND_LINEAR: - res = vector.extract(0); + res = vector[0]; break; case SHD_BLEND_QUADRATIC: - res = vector.extract(0); + res = vector[0]; res = res * res; break; case SHD_BLEND_EASING: - res = vector.extract(0).clamp(val(0.0f), val(1.0f)); + res = vector[0].clamp(); res = res * res * (val(3.0f) - val(2.0f) * res); break; case SHD_BLEND_DIAGONAL: - res = (vector.extract(0) + vector.extract(1)) * val(0.5f); + res = (vector[0] + vector[1]) * val(0.5f); break; case SHD_BLEND_RADIAL: - res = vector.extract(1).atan2(vector.extract(0)) / (val(float(M_PI * 2.0f))) + val(0.5f); + res = vector[1].atan2(vector[0]) / (val(float(M_PI * 2.0f))) + val(0.5f); break; case SHD_BLEND_QUADRATIC_SPHERE: res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f)); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index 537114b70d7..b081e00165d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -250,7 +250,7 @@ NODE_SHADER_MATERIALX_BEGIN } if (STREQ(socket_out_->name, "Alpha")) { - res = res.extract(3); + res = res[3]; } return res; } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index 63b0de98e44..d947012f9c7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -135,9 +135,9 @@ class WaveFunction : public mf::MultiFunction { MutableSpan r_fac = params.uninitialized_single_output(8, "Fac"); mask.foreach_index([&](const int64_t i) { - float3 p = vector[i] * scale[i]; + float3 pos = vector[i] * scale[i]; /* Prevent precision issues on unit coordinates. */ - p = (p + 0.000001f) * 0.999999f; + pos = (pos + 0.000001f) * 0.999999f; float n = 0.0f; float val = 0.0f; @@ -146,21 +146,21 @@ class WaveFunction : public mf::MultiFunction { case SHD_WAVE_BANDS: switch (bands_direction_) { case SHD_WAVE_BANDS_DIRECTION_X: - n = p.x * 20.0f; + n = pos.x * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_Y: - n = p.y * 20.0f; + n = pos.y * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_Z: - n = p.z * 20.0f; + n = pos.z * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_DIAGONAL: - n = (p.x + p.y + p.z) * 10.0f; + n = (pos.x + pos.y + pos.z) * 10.0f; break; } break; case SHD_WAVE_RINGS: - float3 rp = p; + float3 rp = pos; switch (rings_direction_) { case SHD_WAVE_RINGS_DIRECTION_X: rp *= float3(0.0f, 1.0f, 1.0f); @@ -183,7 +183,7 @@ class WaveFunction : public mf::MultiFunction { if (distortion[i] != 0.0f) { n += distortion[i] * - (noise::perlin_fractal(p * dscale[i], detail[i], droughness[i], 2.0f, true) * 2.0f - + (noise::perlin_fractal(pos * dscale[i], detail[i], droughness[i], 2.0f, true) * 2.0f - 1.0f); } @@ -223,51 +223,55 @@ NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { NodeTexWave *tex = (NodeTexWave *)node_->storage; - const int wave_type = tex->wave_type; - const int bands_direction = tex->bands_direction; - const int rings_direction = tex->rings_direction; - const int wave_profile = tex->wave_profile; NodeItem scale = get_input_value("Scale", NodeItem::Type::Float); - NodeItem distortion = get_input_value("Distortion", NodeItem::Type::Float) / - val(10.0f); // noise adjusment to get result as Cycles - NodeItem detail = get_input_value("Detail", NodeItem::Type::Float); - NodeItem detail_scale = get_input_value("Detail Scale", NodeItem::Type::Float) * - val(10.0f); // noise adjusment to get result as Cycles + NodeItem distortion = get_input_value("Distortion", NodeItem::Type::Float); + NodeItem detail = get_input_default("Detail", NodeItem::Type::Float); + NodeItem detail_scale = get_input_value("Detail Scale", NodeItem::Type::Float); NodeItem detail_rough = get_input_value("Detail Roughness", NodeItem::Type::Float); NodeItem phase_offset = get_input_value("Phase Offset", NodeItem::Type::Float); NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3); if (!vector) { - vector = texcoord_node(); + vector = texcoord_node(NodeItem::Type::Vector3); } - NodeItem p = vector * scale; - p = (p + val(0.000001f)) * val(0.999999f); + /* adjusment to get result as Cycles */ + distortion = distortion * val(10.0f); + detail_scale = detail_scale * val(10.0f); + + NodeItem pos = vector * scale; + //pos = (pos + val(0.000001f)) * val(0.999999f); + + NodeItem fractal = create_node("fractal3d", + NodeItem::Type::Float, + {{"position", pos}, + {"octaves", val(int(detail.value->asA()))}, + {"lacunarity", val(2.0f)}}); NodeItem n = val(0.0f); NodeItem value = val(0.0f); - switch (wave_type) { + switch (tex->wave_type) { case SHD_WAVE_BANDS: - switch (bands_direction) { + switch (tex->bands_direction) { case SHD_WAVE_BANDS_DIRECTION_X: - n = p.extract(0) * val(20.0f); + n = pos[0] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_Y: - n = p.extract(1) * val(20.0f); + n = pos[1] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_Z: - n = p.extract(2) * val(20.0f); + n = pos[2] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_DIAGONAL: - n = (p.extract(0) + p.extract(1) + p.extract(2)) * val(10.0f); + n = (pos[0] + pos[1] + pos[2]) * val(10.0f); break; default: BLI_assert_unreachable(); } break; case SHD_WAVE_RINGS: - NodeItem rp = p; - switch (rings_direction) { + NodeItem rp = pos; + switch (tex->rings_direction) { case SHD_WAVE_RINGS_DIRECTION_X: rp = rp * val(MaterialX::Vector3(0.0f, 1.0f, 1.0f)); break; @@ -286,15 +290,9 @@ NODE_SHADER_MATERIALX_BEGIN n = rp.dotproduct(rp).sqrt() * val(20.0f); break; } - n = n + phase_offset; - n = n + distortion * detail_scale * - create_node("fractal3d", - NodeItem::Type::Float, - {{"position", p}, - {"octaves", val(int(detail.value->asA()))}, - {"lacunarity", val(2.0f)}}); + n = n + phase_offset + distortion * detail_scale * fractal; - switch (wave_profile) { + switch (tex->wave_profile) { case SHD_WAVE_PROFILE_SIN: value = val(0.5f) + val(0.5f) * (n - val(float(M_PI_2))).sin(); break; -- 2.30.2 From 4739e384ca84eb68a7cbf1756fd6b25730e0ea1a Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 17:11:36 +0300 Subject: [PATCH 02/16] Fixed dotproduct, mix. Added length, to_vector. --- .../nodes/shader/materialx/node_item.cc | 44 ++++++++++++++++--- .../nodes/shader/materialx/node_item.h | 2 + .../nodes/shader/nodes/node_shader_mix.cc | 11 +++++ .../nodes/shader/nodes/node_shader_mix_rgb.cc | 10 ----- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 5e2be49eb7e..6b88fb393a2 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -251,6 +251,14 @@ NodeItem NodeItem::ceil() const return arithmetic("ceil", [](float a) { return std::ceilf(a); }); } +NodeItem NodeItem::length() const +{ + if (value) { + return dotproduct(*this).sqrt(); + } + return create_node("magnitude", Type::Float, {{"in", to_vector()}}); +} + NodeItem NodeItem::min(const NodeItem &other) const { return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); }); @@ -302,7 +310,10 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const return val(f); } - return create_node("dotproduct", Type::Float, {{"in1", *this}, {"in2", other}}); + NodeItem item1 = to_vector(); + NodeItem item2 = other.to_vector(); + cast_types(item1, item2); + return create_node("dotproduct", Type::Float, {{"in1", item1}, {"in2", item2}}); } NodeItem NodeItem::mix(const NodeItem &val1, const NodeItem &val2) const @@ -318,13 +329,13 @@ NodeItem NodeItem::mix(const NodeItem &val1, const NodeItem &val2) const BLI_assert(val2.type() == type1); /* Special case: mix BSDF/EDF shaders */ - return create_node("mix", type1, {{}, {}}); + return create_node("mix", type1, {{"bg", val1}, {"fg", val2}, {"mix", *this}}); }; NodeItem item1 = val1; NodeItem item2 = val2; Type to_type = cast_types(item1, item2); - return create_node("mix", to_type, {{"bg", item1}, {"fg", item2}}); + return create_node("mix", to_type, {{"bg", item1}, {"fg", item2}, {"mix", *this}}); } NodeItem NodeItem::clamp(const NodeItem &min_val, const NodeItem &max_val) const @@ -590,6 +601,27 @@ NodeItem NodeItem::convert(Type to_type) const return res; } +NodeItem NodeItem::to_vector() const +{ + switch (type()) { + case Type::Float: + case Type::Vector2: + case Type::Vector3: + case Type::Vector4: + return *this; + + case Type::Color3: + return convert(Type::Vector3); + + case Type::Color4: + return convert(Type::Vector4); + + default: + BLI_assert_unreachable(); + } + return empty(); +} + NodeItem NodeItem::if_else(CompareOp op, const NodeItem &other, const NodeItem &if_val, @@ -857,12 +889,10 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function(clamp, mix_type); } -NODE_SHADER_MATERIALX_BEGIN -#ifdef WITH_MATERIALX -{ - /* TODO: Implement */ - return empty(); -} -#endif -NODE_SHADER_MATERIALX_END - } // namespace blender::nodes::node_shader_mix_rgb_cc void register_node_type_sh_mix_rgb() @@ -173,6 +164,5 @@ void register_node_type_sh_mix_rgb() ntype.gpu_fn = file_ns::gpu_shader_mix_rgb; ntype.build_multi_function = file_ns::sh_node_mix_rgb_build_multi_function; ntype.gather_link_search_ops = nullptr; - ntype.materialx_fn = file_ns::node_shader_materialx; nodeRegisterType(&ntype); } -- 2.30.2 From e90a7fa7f767f7e4ebef1770bdd1ed4a9a0ef288 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 19:44:11 +0300 Subject: [PATCH 03/16] Implemented mix node --- .../nodes/shader/materialx/node_item.cc | 4 +- .../nodes/shader/nodes/node_shader_mix.cc | 47 ++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 6b88fb393a2..a07220e9509 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -318,9 +318,7 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const NodeItem NodeItem::mix(const NodeItem &val1, const NodeItem &val2) const { - BLI_assert(type() == Type::Float); - - if (value && val1.value && val2.value) { + if ((value && val1.value && val2.value) || type() != Type::Float) { return (val(1.0f) - *this) * val1 + *this * val2; } diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 930dfadb5e8..54a8affb561 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -546,8 +546,51 @@ static void sh_node_mix_build_multi_function(NodeMultiFunctionBuilder &builder) NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - /* TODO: Implement */ - return empty(); + const NodeShaderMix *data = (NodeShaderMix *)node_->storage; + + NodeItem factor = empty(); + NodeItem value1 = empty(); + NodeItem value2 = empty(); + switch (data->data_type) { + case SOCK_FLOAT: + factor = get_input_value(0, NodeItem::Type::Float); + value1 = get_input_value(2, NodeItem::Type::Float); + value2 = get_input_value(3, NodeItem::Type::Float); + break; + + case SOCK_VECTOR: + if (data->factor_mode == NODE_MIX_MODE_UNIFORM) { + factor = get_input_value(0, NodeItem::Type::Float); + } + else { + factor = get_input_value(1, NodeItem::Type::Vector3); + } + value1 = get_input_value(4, NodeItem::Type::Vector3); + value2 = get_input_value(5, NodeItem::Type::Vector3); + break; + + case SOCK_RGBA: + factor = get_input_value(0, NodeItem::Type::Float); + value1 = get_input_value(6, NodeItem::Type::Color4); + value2 = get_input_value(7, NodeItem::Type::Color4); + break; + + default: + BLI_assert_unreachable(); + } + + if (data->clamp_factor) { + factor = factor.clamp(); + } + NodeItem res = factor.mix(value1, value2); + if (data->data_type == SOCK_RGBA) { + /* TODO: Apply data->blend_type */ + + if (data->clamp_result) { + res = res.clamp(); + } + } + return res; } #endif NODE_SHADER_MATERIALX_END -- 2.30.2 From 51cfa8f2676de4b6dd74737d8af75aba18d03d44 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 20:02:53 +0300 Subject: [PATCH 04/16] Simplified node_shader_tex_wave.cc --- .../shader/nodes/node_shader_tex_wave.cc | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index d947012f9c7..379ca657c0a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -240,46 +240,42 @@ NODE_SHADER_MATERIALX_BEGIN detail_scale = detail_scale * val(10.0f); NodeItem pos = vector * scale; - //pos = (pos + val(0.000001f)) * val(0.999999f); - NodeItem fractal = create_node("fractal3d", NodeItem::Type::Float, {{"position", pos}, {"octaves", val(int(detail.value->asA()))}, {"lacunarity", val(2.0f)}}); - NodeItem n = val(0.0f); NodeItem value = val(0.0f); - switch (tex->wave_type) { case SHD_WAVE_BANDS: switch (tex->bands_direction) { case SHD_WAVE_BANDS_DIRECTION_X: - n = pos[0] * val(20.0f); + value = pos[0] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_Y: - n = pos[1] * val(20.0f); + value = pos[1] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_Z: - n = pos[2] * val(20.0f); + value = pos[2] * val(20.0f); break; case SHD_WAVE_BANDS_DIRECTION_DIAGONAL: - n = (pos[0] + pos[1] + pos[2]) * val(10.0f); + value = (pos[0] + pos[1] + pos[2]) * val(10.0f); break; default: BLI_assert_unreachable(); } break; case SHD_WAVE_RINGS: - NodeItem rp = pos; + NodeItem rpos = pos; switch (tex->rings_direction) { case SHD_WAVE_RINGS_DIRECTION_X: - rp = rp * val(MaterialX::Vector3(0.0f, 1.0f, 1.0f)); + rpos = pos * val(MaterialX::Vector3(0.0f, 1.0f, 1.0f)); break; case SHD_WAVE_RINGS_DIRECTION_Y: - rp = rp * val(MaterialX::Vector3(1.0f, 0.0f, 1.0f)); + rpos = pos * val(MaterialX::Vector3(1.0f, 0.0f, 1.0f)); break; case SHD_WAVE_RINGS_DIRECTION_Z: - rp = rp * val(MaterialX::Vector3(1.0f, 1.0f, 0.0f)); + rpos = pos * val(MaterialX::Vector3(1.0f, 1.0f, 0.0f)); break; case SHD_WAVE_RINGS_DIRECTION_SPHERICAL: /* Ignore. */ @@ -287,27 +283,28 @@ NODE_SHADER_MATERIALX_BEGIN default: BLI_assert_unreachable(); } - n = rp.dotproduct(rp).sqrt() * val(20.0f); + value = rpos.length() * val(20.0f); break; } - n = n + phase_offset + distortion * detail_scale * fractal; + value = value + phase_offset + distortion * detail_scale * fractal; + NodeItem res = empty(); switch (tex->wave_profile) { case SHD_WAVE_PROFILE_SIN: - value = val(0.5f) + val(0.5f) * (n - val(float(M_PI_2))).sin(); + res = val(0.5f) + val(0.5f) * (value - val(float(M_PI_2))).sin(); break; case SHD_WAVE_PROFILE_SAW: - n = n / val(float(M_PI * 2.0f)); - value = n - n.floor(); + value = value / val(float(M_PI * 2.0f)); + res = value - value.floor(); break; case SHD_WAVE_PROFILE_TRI: - n = n / val(float(M_PI * 2.0f)); - value = (n - (n + val(0.5f)).floor()).abs() * val(2.0f); + value = value / val(float(M_PI * 2.0f)); + res = (value - (value + val(0.5f)).floor()).abs() * val(2.0f); break; default: BLI_assert_unreachable(); } - return value; + return res; } #endif NODE_SHADER_MATERIALX_END -- 2.30.2 From 273bb4d0e1da92a8d84ad606b21781bf4c54f31c Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 20:19:27 +0300 Subject: [PATCH 05/16] More correct implementation of clamp() --- source/blender/nodes/shader/materialx/node_item.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index a07220e9509..8cbc4ece15b 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -338,7 +338,19 @@ NodeItem NodeItem::mix(const NodeItem &val1, const NodeItem &val2) const NodeItem NodeItem::clamp(const NodeItem &min_val, const NodeItem &max_val) const { - return min(max_val).max(min_val); + if (value && min_val.value && max_val.value) { + return min(max_val).max(min_val); + } + + if (min_val.type() == Type::Float && max_val.type() == Type::Float) { + return create_node("clamp", type(), {{"in", *this}, {"low", min_val}, {"high", max_val}}); + } + + Type type = this->type(); + return create_node( + "clamp", + type, + {{"in", *this}, {"low", min_val.convert(type)}, {"high", max_val.convert(type)}}); } NodeItem NodeItem::clamp(float min_val, float max_val) const -- 2.30.2 From dae8c96e20f5b775266529e2205cd345f8ee4a17 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 20:31:20 +0300 Subject: [PATCH 06/16] Moving BSDFPrincipled to use mix() function --- .../nodes/node_shader_bsdf_principled.cc | 72 +++++++++++-------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index ada2bb7be86..ab688a5d630 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -396,10 +396,12 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3); NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * in["coat_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_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness, + val(1.0f)); + // 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", @@ -424,12 +426,14 @@ NODE_SHADER_MATERIALX_BEGIN {"normal", normal}, {"tangent", n_main_tangent}}); - 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_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix( + (roughness + roughness).clamp(), val(1.0f)); + // 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", @@ -459,10 +463,11 @@ NODE_SHADER_MATERIALX_BEGIN {"anisotropy", in["subsurface_anisotropy"]}, {"normal", normal}}); - 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_selected_subsurface_bsdf = n_subsurface_bsdf; + // 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_sheen_bsdf = create_node("sheen_bsdf", NodeItem::Type::BSDF, @@ -478,26 +483,29 @@ NODE_SHADER_MATERIALX_BEGIN {"weight", val(1.0f)}, {"normal", normal}}); - NodeItem n_subsurface_mix = create_node( - "mix", - NodeItem::Type::BSDF, - {{"fg", n_selected_subsurface_bsdf}, {"bg", n_diffuse_bsdf}, {"mix", in["subsurface"]}}); + NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_selected_subsurface_bsdf); + // NodeItem n_subsurface_mix = create_node( + // "mix", + // NodeItem::Type::BSDF, + // {{"fg", n_selected_subsurface_bsdf}, {"bg", n_diffuse_bsdf}, {"mix", in["subsurface"]}}); NodeItem n_sheen_layer = create_node( "layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}}); - NodeItem n_transmission_mix = create_node( - "mix", - NodeItem::Type::BSDF, - {{"fg", n_transmission_bsdf}, {"bg", n_sheen_layer}, {"mix", in["transmission"]}}); + NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf); + // NodeItem n_transmission_mix = create_node( + // "mix", + // NodeItem::Type::BSDF, + // {{"fg", n_transmission_bsdf}, {"bg", n_sheen_layer}, {"mix", in["transmission"]}}); NodeItem n_specular_layer = create_node( "layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}}); - NodeItem n_metalness_mix = create_node( - "mix", - NodeItem::Type::BSDF, - {{"fg", n_metal_bsdf}, {"bg", n_specular_layer}, {"mix", in["metallic"]}}); + NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf); + // NodeItem n_metalness_mix = create_node( + // "mix", + // NodeItem::Type::BSDF, + // {{"fg", n_metal_bsdf}, {"bg", n_specular_layer}, {"mix", in["metallic"]}}); NodeItem n_thin_film_layer = create_node( "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}}); @@ -505,11 +513,13 @@ NODE_SHADER_MATERIALX_BEGIN 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", in["coat_tint"]}, - {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}, - {"mix", coat}}); + NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)), + in["coat_tint"]); + // NodeItem n_coat_attenuation = create_node("mix", + // NodeItem::Type::Color3, + // {{"fg", in["coat_tint"]}, + // {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}, + // {"mix", coat}}); res = create_node("layer", NodeItem::Type::BSDF, -- 2.30.2 From a901f806d7eb5fb7780fcd3a58a8d67387635675 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 22:52:54 +0300 Subject: [PATCH 07/16] Code improvement in BSDFPrincipled --- .../nodes/node_shader_bsdf_principled.cc | 433 +++++++++--------- 1 file changed, 204 insertions(+), 229 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index ab688a5d630..f0099d002b2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -289,9 +289,11 @@ static void node_shader_update_principled(bNodeTree *ntree, bNode *node) NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { + using InputsType = std::map; + /* NOTE: commented inputs aren't used for node creation. */ - auto bsdf_inputs = [&]() { - return std::map{ + auto bsdf_inputs = [&]() -> InputsType { + return { {"base_color", get_input_value("Base Color", NodeItem::Type::Color3)}, {"subsurface", get_input_value("Subsurface", NodeItem::Type::Float)}, {"subsurface_scale", get_input_value("Subsurface Scale", NodeItem::Type::Float)}, @@ -320,265 +322,238 @@ NODE_SHADER_MATERIALX_BEGIN }; }; - auto edf_inputs = [&]() { - return std::map{ + auto edf_inputs = [&]() -> InputsType { + return { {"emission", get_input_value("Emission Strength", NodeItem::Type::Float)}, - {"emission_color", get_input_value("Emission", NodeItem::Type::Color3)}}; + {"emission_color", get_input_value("Emission", NodeItem::Type::Color3)}, + }; }; NodeItem res = empty(); - if (to_type_ == NodeItem::Type::BSDF) { - auto in = bsdf_inputs(); + + switch (to_type_) { + case NodeItem::Type::BSDF: { + auto in = bsdf_inputs(); - NodeItem roughness = in["roughness"]; - NodeItem anisotropy = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"]; - NodeItem base_color = in["base_color"]; - NodeItem specular = in["specular"]; - NodeItem coat = in["coat"]; - NodeItem ior = in["ior"]; - NodeItem normal = in["normal"]; - NodeItem tangent = in["tangent"]; - NodeItem coat_normal = in["coat_normal"]; + NodeItem roughness = in["roughness"]; + NodeItem anisotropy = in["anisotropic"]; + NodeItem rotation = in["anisotropic_rotation"]; + NodeItem base_color = in["base_color"]; + NodeItem specular = in["specular"]; + NodeItem coat = in["coat"]; + NodeItem ior = in["ior"]; + NodeItem normal = in["normal"]; + NodeItem tangent = in["tangent"]; + NodeItem coat_normal = in["coat_normal"]; - NodeItem n_main_tangent = empty(); - if (tangent && normal) { - NodeItem n_tangent_rotate = create_node( - "rotate3d", - NodeItem::Type::Vector3, - {{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", normal}}); + NodeItem n_main_tangent = empty(); + if (tangent && 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, {{"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); - } + n_main_tangent = anisotropy.if_else( + NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent); + } - NodeItem n_coat_roughness_vector = create_node( - "roughness_anisotropy", - NodeItem::Type::Vector2, - {{"roughness", in["coat_roughness"]}, {"anisotropy", anisotropy}}); + NodeItem n_coat_roughness_vector = create_node( + "roughness_anisotropy", + NodeItem::Type::Vector2, + {{"roughness", in["coat_roughness"]}, {"anisotropy", anisotropy}}); - NodeItem n_coat_bsdf = create_node("dielectric_bsdf", - NodeItem::Type::BSDF, - {{"weight", coat}, - {"tint", in["coat_tint"]}, - {"ior", in["coat_ior"]}, - {"scatter_mode", val(std::string("R"))}, - {"roughness", n_coat_roughness_vector}, - {"normal", coat_normal}}); + NodeItem n_coat_bsdf = create_node("dielectric_bsdf", + NodeItem::Type::BSDF, + {{"weight", coat}, + {"tint", in["coat_tint"]}, + {"ior", in["coat_ior"]}, + {"scatter_mode", val(std::string("R"))}, + {"roughness", n_coat_roughness_vector}, + {"normal", coat_normal}}); - if (tangent && coat_normal) { - NodeItem n_coat_tangent_rotate = create_node( - "rotate3d", - NodeItem::Type::Vector3, - {{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}}); + if (tangent && coat_normal) { + NodeItem n_coat_tangent_rotate = create_node( + "rotate3d", + NodeItem::Type::Vector3, + {{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_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, {{"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 n_coat_tangent = anisotropy.if_else( + NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent); - n_coat_bsdf.set_input("tangent", n_coat_tangent); - } + n_coat_bsdf.set_input("tangent", n_coat_tangent); + } - NodeItem n_thin_film_bsdf = create_node( - "thin_film_bsdf", NodeItem::Type::BSDF, {{"thickness", val(0.0f)}, {"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, + {{"reflectivity", base_color * val(1.0f)}, {"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_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) * in["coat_roughness"]; - NodeItem n_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness, - val(1.0f)); - // 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_coat_affect_roughness_multiply2 = coat * val(0.0f) * in["coat_roughness"]; + NodeItem n_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness, + val(1.0f)); - NodeItem n_main_roughness = create_node( - "roughness_anisotropy", - NodeItem::Type::Vector2, - {{"roughness", n_coat_affected_roughness}, {"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, - {{"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, - {{"weight", specular}, - {"tint", in["specular_tint"]}, - {"ior", ior}, - {"scatter_mode", val(std::string("R"))}, - {"roughness", n_main_roughness}, - {"normal", normal}, - {"tangent", n_main_tangent}}); - - NodeItem n_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix( - (roughness + roughness).clamp(), val(1.0f)); - // 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_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, - {{"color", n_coat_affected_subsurface_color}, {"normal", normal}}); - - NodeItem n_subsurface_bsdf = create_node( - "subsurface_bsdf", - NodeItem::Type::BSDF, - {{"color", n_coat_affected_subsurface_color}, - {"radius", in["subsurface_radius"] * in["subsurface_scale"]}, - {"anisotropy", in["subsurface_anisotropy"]}, - {"normal", normal}}); - - NodeItem n_selected_subsurface_bsdf = n_subsurface_bsdf; - // 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_sheen_bsdf = create_node("sheen_bsdf", - NodeItem::Type::BSDF, - {{"weight", in["sheen"]}, - {"color", in["sheen_tint"]}, - {"roughness", in["sheen_roughness"]}, - {"normal", normal}}); - - NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf", + NodeItem n_metal_bsdf = create_node("conductor_bsdf", NodeItem::Type::BSDF, - {{"color", base_color.max(val(0.0f)) ^ n_coat_gamma}, - {"roughness", roughness}, - {"weight", val(1.0f)}, + {{"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, + {{"weight", specular}, + {"tint", in["specular_tint"]}, + {"ior", ior}, + {"scatter_mode", val(std::string("R"))}, + {"roughness", n_main_roughness}, + {"normal", normal}, + {"tangent", n_main_tangent}}); + + NodeItem n_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix( + (roughness + roughness).clamp(), val(1.0f)); + + 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_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, + {{"color", n_coat_affected_subsurface_color}, {"normal", normal}}); + + NodeItem n_subsurface_bsdf = create_node( + "subsurface_bsdf", + NodeItem::Type::BSDF, + {{"color", n_coat_affected_subsurface_color}, + {"radius", in["subsurface_radius"] * in["subsurface_scale"]}, + {"anisotropy", in["subsurface_anisotropy"]}, + {"normal", normal}}); + + NodeItem n_sheen_bsdf = create_node("sheen_bsdf", + NodeItem::Type::BSDF, + {{"weight", in["sheen"]}, + {"color", in["sheen_tint"]}, + {"roughness", in["sheen_roughness"]}, {"normal", normal}}); - NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_selected_subsurface_bsdf); - // NodeItem n_subsurface_mix = create_node( - // "mix", - // NodeItem::Type::BSDF, - // {{"fg", n_selected_subsurface_bsdf}, {"bg", n_diffuse_bsdf}, {"mix", in["subsurface"]}}); + 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_sheen_layer = create_node( - "layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}}); + NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_subsurface_bsdf); - NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf); - // NodeItem n_transmission_mix = create_node( - // "mix", - // NodeItem::Type::BSDF, - // {{"fg", n_transmission_bsdf}, {"bg", n_sheen_layer}, {"mix", in["transmission"]}}); + NodeItem n_sheen_layer = create_node( + "layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}}); - NodeItem n_specular_layer = create_node( - "layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}}); + NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf); - NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf); - // NodeItem n_metalness_mix = create_node( - // "mix", - // NodeItem::Type::BSDF, - // {{"fg", n_metal_bsdf}, {"bg", n_specular_layer}, {"mix", in["metallic"]}}); + NodeItem n_specular_layer = create_node( + "layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}}); - NodeItem n_thin_film_layer = create_node( - "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}}); + NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf); - NodeItem n_opacity_luminance = create_node( - "luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}}); + NodeItem n_thin_film_layer = create_node( + "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}}); - NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)), - in["coat_tint"]); - // NodeItem n_coat_attenuation = create_node("mix", - // NodeItem::Type::Color3, - // {{"fg", in["coat_tint"]}, - // {"bg", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}, - // {"mix", coat}}); + NodeItem n_opacity_luminance = create_node( + "luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}}); - res = create_node("layer", - NodeItem::Type::BSDF, - {{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}}); + NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)), + in["coat_tint"]); + + res = create_node("layer", + NodeItem::Type::BSDF, + {{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}}); + break; + } + + case NodeItem::Type::EDF: { + auto in = edf_inputs(); + res = create_node( + "uniform_edf", NodeItem::Type::EDF, {{"color", in["emission_color"] * in["emission"]}}); + break; + } + + case NodeItem::Type::SurfaceShader: { + auto in = bsdf_inputs(); + auto e_in = edf_inputs(); + in.insert(e_in.begin(), e_in.end()); + + NodeItem roughness = in["roughness"]; + NodeItem base_color = in["base_color"]; + NodeItem anisotropic = in["anisotropic"]; + NodeItem rotation = in["anisotropic_rotation"]; + + res = create_node("standard_surface", + NodeItem::Type::SurfaceShader, + {{"base", val(1.0f)}, + {"base_color", base_color}, + {"diffuse_roughness", roughness}, + {"metalness", in["metallic"]}, + {"specular", in["specular"]}, + {"specular_color", in["specular_tint"]}, + {"specular_roughness", roughness}, + {"specular_IOR", in["ior"]}, + {"specular_anisotropy", anisotropic}, + {"specular_rotation", rotation}, + {"transmission", in["transmission"]}, + {"transmission_color", base_color}, + {"transmission_extra_roughness", roughness}, + {"subsurface", in["subsurface"]}, + {"subsurface_color", base_color}, + {"subsurface_radius", in["subsurface_radius"] * in["subsurface_scale"]}, + {"subsurface_anisotropy", in["subsurface_anisotropy"]}, + {"sheen", in["sheen"]}, + {"sheen_color", in["sheen_tint"]}, + {"sheen_roughness", in["sheen_roughness"]}, + {"coat", in["coat"]}, + {"coat_color", in["coat_tint"]}, + {"coat_roughness", in["coat_roughness"]}, + {"coat_IOR", in["coat_ior"]}, + {"coat_anisotropy", anisotropic}, + {"coat_rotation", rotation}, + {"coat_normal", in["coat_normal"]}, + {"emission", in["emission"]}, + {"emission_color", in["emission_color"]}, + {"normal", in["normal"]}, + {"tangent", in["tangent"]}}); + break; + } + default: + BLI_assert_unreachable(); } - else if (to_type_ == NodeItem::Type::EDF) { - auto in = edf_inputs(); - - res = create_node( - "uniform_edf", NodeItem::Type::EDF, {{"color", in["emission_color"] * in["emission"]}}); - } - else if (to_type_ == NodeItem::Type::SurfaceShader) { - auto in = bsdf_inputs(); - auto e_in = edf_inputs(); - in.insert(e_in.begin(), e_in.end()); - - NodeItem roughness = in["roughness"]; - NodeItem base_color = in["base_color"]; - NodeItem anisotropic = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"]; - - res = create_node("standard_surface", - NodeItem::Type::SurfaceShader, - {{"base", val(1.0f)}, - {"base_color", base_color}, - {"diffuse_roughness", roughness}, - {"metalness", in["metallic"]}, - {"specular", in["specular"]}, - {"specular_color", in["specular_tint"]}, - {"specular_roughness", roughness}, - {"specular_IOR", in["ior"]}, - {"specular_anisotropy", anisotropic}, - {"specular_rotation", rotation}, - {"transmission", in["transmission"]}, - {"transmission_color", base_color}, - {"transmission_extra_roughness", roughness}, - {"subsurface", in["subsurface"]}, - {"subsurface_color", base_color}, - {"subsurface_radius", in["subsurface_radius"] * in["subsurface_scale"]}, - {"subsurface_anisotropy", in["subsurface_anisotropy"]}, - {"sheen", in["sheen"]}, - {"sheen_color", in["sheen_tint"]}, - {"sheen_roughness", in["sheen_roughness"]}, - {"coat", in["coat"]}, - {"coat_color", in["coat_tint"]}, - {"coat_roughness", in["coat_roughness"]}, - {"coat_IOR", in["coat_ior"]}, - {"coat_anisotropy", anisotropic}, - {"coat_rotation", rotation}, - {"coat_normal", in["coat_normal"]}, - {"emission", in["emission"]}, - {"emission_color", in["emission_color"]}, - {"normal", in["normal"]}, - {"tangent", in["tangent"]}}); - } - else { - BLI_assert_unreachable(); - } - return res; } #endif -- 2.30.2 From 834ee030b6df28cff83c59f418941a1e7918a903 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 21 Sep 2023 23:13:54 +0300 Subject: [PATCH 08/16] Code improvements in math functions --- .../nodes/shader/materialx/node_item.cc | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 8cbc4ece15b..6f111ace3cf 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -360,62 +360,68 @@ NodeItem NodeItem::clamp(float min_val, float max_val) const NodeItem NodeItem::sin() const { - return arithmetic("sin", [](float a) { return std::sinf(a); }); + return to_vector().arithmetic("sin", [](float a) { return std::sinf(a); }); } NodeItem NodeItem::cos() const { - return arithmetic("cos", [](float a) { return std::cosf(a); }); + return to_vector().arithmetic("cos", [](float a) { return std::cosf(a); }); } NodeItem NodeItem::tan() const { - return arithmetic("tan", [](float a) { return std::tanf(a); }); + return to_vector().arithmetic("tan", [](float a) { return std::tanf(a); }); } NodeItem NodeItem::asin() const { - return arithmetic("asin", [](float a) { return std::asinf(a); }); + return to_vector().arithmetic("asin", [](float a) { return std::asinf(a); }); } NodeItem NodeItem::acos() const { - return arithmetic("acos", [](float a) { return std::acosf(a); }); + return to_vector().arithmetic("acos", [](float a) { return std::acosf(a); }); } NodeItem NodeItem::atan() const { - return arithmetic("atan", [](float a) { return std::atanf(a); }); + return to_vector().arithmetic("atan", [](float a) { return std::atanf(a); }); } NodeItem NodeItem::atan2(const NodeItem &other) const { - return arithmetic(other, "atan2", [](float a, float b) { return std::atan2f(a, b); }); + return to_vector().arithmetic( + other, "atan2", [](float a, float b) { return std::atan2f(a, b); }); } NodeItem NodeItem::sinh() const { - return (exp() - (-*this).exp()) / val(2.0f); + NodeItem v = to_vector(); + return (v.exp() - (-v).exp()) / val(2.0f); } NodeItem NodeItem::cosh() const { - return (exp() - (-*this).exp()) / val(2.0f); + NodeItem v = to_vector(); + return (v.exp() + (-v).exp()) / val(2.0f); } NodeItem NodeItem::tanh() const { - return sinh() / cosh(); + NodeItem v = to_vector(); + NodeItem a = v.exp(); + NodeItem b = (-v).exp(); + return (a - b) / (a + b); } NodeItem NodeItem::ln() const { - return arithmetic("ln", [](float a) { return std::logf(a); }); + return to_vector().arithmetic("ln", [](float a) { return std::logf(a); }); } NodeItem NodeItem::sqrt() const { - return arithmetic("sqrt", [](float a) { return std::sqrtf(a); }); + return to_vector().arithmetic("sqrt", [](float a) { return std::sqrtf(a); }); } NodeItem NodeItem::sign() const @@ -425,7 +431,7 @@ NodeItem NodeItem::sign() const NodeItem NodeItem::exp() const { - return arithmetic("exp", [](float a) { return std::expf(a); }); + return to_vector().arithmetic("exp", [](float a) { return std::expf(a); }); } NodeItem NodeItem::convert(Type to_type) const @@ -898,13 +904,7 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function Date: Thu, 21 Sep 2023 23:40:53 +0300 Subject: [PATCH 09/16] Reverted some changes --- .../nodes/shader/nodes/node_shader_bsdf_principled.cc | 2 +- .../nodes/shader/nodes/node_shader_tex_brick.cc | 10 +++++----- .../nodes/shader/nodes/node_shader_tex_checker.cc | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index f0099d002b2..cb532434e79 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -330,7 +330,7 @@ NODE_SHADER_MATERIALX_BEGIN }; NodeItem res = empty(); - + switch (to_type_) { case NodeItem::Type::BSDF: { auto in = bsdf_inputs(); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 8f588acbdfa..aa00e08e00f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -160,7 +160,7 @@ class BrickFunction : public mf::MultiFunction { return (3.0f * ff - 2.0f * ff * f); } - static float2 brick(float3 pos, + static float2 brick(float3 p, float mortar_size, float mortar_smooth, float bias, @@ -173,17 +173,17 @@ class BrickFunction : public mf::MultiFunction { { float offset = 0.0f; - const int rownum = int(floorf(pos.y / row_height)); + const int rownum = int(floorf(p.y / row_height)); if (offset_frequency && squash_frequency) { brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount); } - const int bricknum = int(floorf((pos.x + offset) / brick_width)); + const int bricknum = int(floorf((p.x + offset) / brick_width)); - const float x = (pos.x + offset) - brick_width * bricknum; - const float y = pos.y - row_height * rownum; + const float x = (p.x + offset) - brick_width * bricknum; + const float y = p.y - row_height * rownum; const float tint = clamp_f( brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias, 0.0f, 1.0f); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index f7649ea5c32..4fe06cd5094 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -80,11 +80,11 @@ class NodeTexChecker : public mf::MultiFunction { mask.foreach_index([&](const int64_t i) { /* Avoid precision issues on unit coordinates. */ - const float3 pos = (vector[i] * scale[i] + 0.000001f) * 0.999999f; + const float3 p = (vector[i] * scale[i] + 0.000001f) * 0.999999f; - const int xi = abs(int(floorf(pos.x))); - const int yi = abs(int(floorf(pos.y))); - const int zi = abs(int(floorf(pos.z))); + const int xi = abs(int(floorf(p.x))); + const int yi = abs(int(floorf(p.y))); + const int zi = abs(int(floorf(p.z))); r_fac[i] = ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f; }); -- 2.30.2 From 01d67d34fe8e45a04ecab307326d6f002c6688d0 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 13:08:55 +0300 Subject: [PATCH 10/16] Added rotate(), normalize() to NodeItem. Adjusted code. Added/fixed comments. --- source/blender/io/usd/hydra/material.cc | 2 +- .../nodes/shader/materialx/node_item.cc | 59 ++++++++++++------- .../nodes/shader/materialx/node_item.h | 18 +++--- .../nodes/shader/materialx/node_parser.h | 19 +++++- .../nodes/node_shader_bsdf_principled.cc | 19 +----- .../nodes/shader/nodes/node_shader_gamma.cc | 1 + .../nodes/shader/nodes/node_shader_mapping.cc | 16 ++--- .../shader/nodes/node_shader_vector_rotate.cc | 3 +- 8 files changed, 80 insertions(+), 57 deletions(-) diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index 9fdf47965a8..ae08298147d 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -82,7 +82,7 @@ void MaterialData::init() scene_delegate_->depsgraph, (Material *)id); pxr::UsdMtlxRead(doc, stage); - /* Logging stage: creating lambda stage_str() for not to call stage->ExportToString() + /* Logging stage: creating lambda stage_str() to not call stage->ExportToString() * if log won't be printed. */ auto stage_str = [&stage]() { std::string str; diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index dc9af705455..97018383941 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -184,6 +184,8 @@ NodeItem NodeItem::operator^(const NodeItem &other) const NodeItem NodeItem::operator[](int index) const { + BLI_assert(is_arithmetic(type())); + if (value) { float v = 0.0f; switch (type()) { @@ -264,6 +266,14 @@ NodeItem NodeItem::length() const return create_node("magnitude", Type::Float, {{"in", to_vector()}}); } +NodeItem NodeItem::normalize() const +{ + if (value) { + return *this / length(); + } + return create_node("normalize", Type::Vector3, {{"in", to_vector()}}); +} + NodeItem NodeItem::min(const NodeItem &other) const { return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); }); @@ -363,6 +373,34 @@ NodeItem NodeItem::clamp(float min_val, float max_val) const return clamp(val(min_val), val(max_val)); } +NodeItem NodeItem::rotate(const NodeItem &angle, const NodeItem &axis) +{ + BLI_assert(type() == Type::Vector3); + BLI_assert(angle.type() == Type::Float); + BLI_assert(axis.type() == Type::Vector3); + + return create_node( + "rotate3d", + NodeItem::Type::Vector3, + {{"in", *this}, {"amount", angle * val(float(180.0f / M_PI))}, {"axis", axis}}); +} + +NodeItem NodeItem::rotate(const NodeItem &angle_xyz, bool invert) +{ + NodeItem angle = angle_xyz * val(float(180.0f / M_PI)); + NodeItem x = angle[0]; + NodeItem y = angle[1]; + NodeItem z = angle[2]; + if (invert) { + return rotate(z, val(MaterialX::Vector3(0.0f, 0.0f, 1.0f))) + .rotate(y, val(MaterialX::Vector3(0.0f, 1.0f, 0.0f))) + .rotate(x, val(MaterialX::Vector3(1.0f, 0.0f, 0.0f))); + } + return rotate(x, val(MaterialX::Vector3(1.0f, 0.0f, 0.0f))) + .rotate(y, val(MaterialX::Vector3(0.0f, 1.0f, 0.0f))) + .rotate(z, val(MaterialX::Vector3(0.0f, 0.0f, 1.0f))); +} + NodeItem NodeItem::sin() const { return to_vector().arithmetic("sin", [](float a) { return std::sinf(a); }); @@ -706,23 +744,6 @@ NodeItem NodeItem::empty() const return NodeItem(graph_); } -NodeItem NodeItem::rotate3d(NodeItem rotation, bool invert) -{ - NodeItem res = *this; - if (res.type() == Type::Vector3 && rotation.type() == Type::Vector3) { - for (int i = 0; i <= 2; i++) { - int j = invert ? 2 - i : i; - MaterialX::Vector3 axis_vector = MaterialX::Vector3(); - axis_vector[j] = 1.0f; - res = create_node( - "rotate3d", - NodeItem::Type::Vector3, - {{"in", res}, {"amount", rotation.extract(j)}, {"axis", val(axis_vector)}}); - } - } - return res; -} - NodeItem::Type NodeItem::type() const { if (value) { @@ -882,9 +903,7 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::functiontype(); - if (!is_arithmetic(type)) { - return res; - } + BLI_assert(is_arithmetic(type)); if (value) { switch (type) { diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index 9f4971ceae0..e79d1135672 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -10,9 +10,11 @@ namespace blender::nodes::materialx { -/* This class serves as abstraction from MateralX API. It implements arithmetic operations, +/** + * This class serves as abstraction from MateralX API. It implements arithmetic operations, * convertions between different types, adding new nodes, setting inputs, etc. - * All work should be done via this class instead of using MaterialX API directly. */ + * All work should be done via this class instead of using MaterialX API directly. + */ class NodeItem { public: using Inputs = std::vector>; @@ -21,22 +23,22 @@ class NodeItem { Any = 0, Empty, Multioutput, + /* Value types */ String, Filename, Boolean, Integer, - /* Block of arithmetic types. Ordered by type cast */ + + /* Arithmetic types. NOTE: Ordered by type cast */ Float, Vector2, Vector3, Color3, Vector4, Color4, - /* End of arithmetic types */ - /* Shader types - * NOTE: There are only supported types */ + /* Shader types. NOTE: There are only supported types */ BSDF, EDF, Displacementshader, @@ -83,12 +85,15 @@ class NodeItem { NodeItem floor() const; NodeItem ceil() const; NodeItem length() const; + NodeItem normalize() const; NodeItem min(const NodeItem &other) const; NodeItem max(const NodeItem &other) const; NodeItem dotproduct(const NodeItem &other) const; NodeItem mix(const NodeItem &val1, const NodeItem &val2) const; NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const; NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const; + NodeItem rotate(const NodeItem &angle, const NodeItem &axis); + NodeItem rotate(const NodeItem &angle_xyz, bool invert = false); NodeItem sin() const; NodeItem cos() const; NodeItem tan() const; @@ -112,7 +117,6 @@ class NodeItem { /* Useful functions */ NodeItem empty() const; - NodeItem rotate3d(NodeItem rotation, bool invert = false); template NodeItem val(const T &data) const; Type type() const; diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 05b510af413..41821efd153 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -18,6 +18,10 @@ extern struct CLG_LogRef *LOG_MATERIALX_SHADER; class GroupNodeParser; +/** + * This is base abstraction class for parsing Blender nodes into MaterialX nodes. + * NodeParser::compute() should be overrides in child classes. + */ class NodeParser { protected: MaterialX::GraphElement *graph_; @@ -72,8 +76,21 @@ template NodeItem NodeParser::val(const T &data) const return empty().val(data); } -/* +/** * Defines for including MaterialX node parsing code into node_shader_.cc + * + * Example: + * \code{.c} + * NODE_SHADER_MATERIALX_BEGIN + * #ifdef WITH_MATERIALX + * { + * NodeItem color = get_input_value("Color", NodeItem::Type::Color4); + * NodeItem gamma = get_input_value("Gamma", NodeItem::Type::Float); + * return color ^ gamma; + * } + * #endif + * NODE_SHADER_MATERIALX_END + * \endcode */ struct NodeParserData { MaterialX::GraphElement *graph; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index cb532434e79..8eefbac6e20 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -348,14 +348,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem n_main_tangent = empty(); if (tangent && 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, {{"in", n_tangent_rotate}}); - + NodeItem n_tangent_rotate_normalize = tangent.rotate(rotation, normal).normalize(); n_main_tangent = anisotropy.if_else( NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent); } @@ -375,14 +368,8 @@ NODE_SHADER_MATERIALX_BEGIN {"normal", coat_normal}}); if (tangent && coat_normal) { - NodeItem n_coat_tangent_rotate = create_node( - "rotate3d", - NodeItem::Type::Vector3, - {{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}}); - - NodeItem n_coat_tangent_rotate_normalize = create_node( - "normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}}); - + NodeItem n_coat_tangent_rotate_normalize = + tangent.rotate(rotation, coat_normal).normalize(); NodeItem n_coat_tangent = anisotropy.if_else( NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent); diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.cc b/source/blender/nodes/shader/nodes/node_shader_gamma.cc index 13964192252..96dd74475ab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_gamma.cc +++ b/source/blender/nodes/shader/nodes/node_shader_gamma.cc @@ -22,6 +22,7 @@ static int node_shader_gpu_gamma(GPUMaterial *mat, { return GPU_stack_link(mat, node, "node_gamma", in, out); } + NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.cc b/source/blender/nodes/shader/nodes/node_shader_mapping.cc index b1fff267626..96a647c0f62 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.cc @@ -79,34 +79,30 @@ NODE_SHADER_MATERIALX_BEGIN { NodeItem res = empty(); NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3); - if (!vector) { - return res; + return empty(); } NodeItem scale = get_input_value("Scale", NodeItem::Type::Vector3); NodeItem location = get_input_value("Location", NodeItem::Type::Vector3); - NodeItem rotation = (get_input_value("Rotation", NodeItem::Type::Vector3) * - val(float(180.0f / M_PI))); + NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3); switch (node_->custom1) { case NODE_MAPPING_TYPE_POINT: - res = (vector * scale).rotate3d(rotation) + location; + return (vector * scale).rotate(rotation) + location; break; case NODE_MAPPING_TYPE_TEXTURE: - res = (vector - location).rotate3d(rotation, true) / scale; + res = (vector - location).rotate(rotation, true) / scale; break; case NODE_MAPPING_TYPE_VECTOR: - res = (vector * scale).rotate3d(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f))); + res = (vector * scale).rotate(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f))); break; case NODE_MAPPING_TYPE_NORMAL: - res = create_node( - "normalize", NodeItem::Type::Vector3, {{"in", (vector / scale).rotate3d(rotation)}}); + res = (vector / scale).rotate(rotation).normalize(); break; default: BLI_assert_unreachable(); } - return res; } #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index 5d71a97def4..7c369199e62 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -237,12 +237,11 @@ NODE_SHADER_MATERIALX_BEGIN angle = get_input_value("Angle", NodeItem::Type::Float); } - angle = angle * val(float(180.0f / M_PI)); angle = invert ? angle * val(-1.0f) : angle; switch (mode) { case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: { - return res.rotate3d(angle, invert) + center; + return res.rotate(angle, invert) + center; } case NODE_VECTOR_ROTATE_TYPE_AXIS: { axis = get_input_value("Axis", NodeItem::Type::Vector3) * -- 2.30.2 From 4ca83bc08f92495cb2e39b79a7d0b8a94c74890a Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 13:27:31 +0300 Subject: [PATCH 11/16] Angle fixes --- .../blender/nodes/shader/materialx/node_item.cc | 16 ++++++++-------- .../blender/nodes/shader/materialx/node_item.h | 4 ++-- .../shader/nodes/node_shader_bsdf_principled.cc | 7 ++++--- .../nodes/shader/nodes/node_shader_mapping.cc | 3 ++- .../shader/nodes/node_shader_vector_rotate.cc | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 97018383941..1af34376a68 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -379,18 +379,18 @@ NodeItem NodeItem::rotate(const NodeItem &angle, const NodeItem &axis) BLI_assert(angle.type() == Type::Float); BLI_assert(axis.type() == Type::Vector3); - return create_node( - "rotate3d", - NodeItem::Type::Vector3, - {{"in", *this}, {"amount", angle * val(float(180.0f / M_PI))}, {"axis", axis}}); + return create_node("rotate3d", + NodeItem::Type::Vector3, + {{"in", *this}, + {"amount", angle}, + {"axis", axis}}); } NodeItem NodeItem::rotate(const NodeItem &angle_xyz, bool invert) { - NodeItem angle = angle_xyz * val(float(180.0f / M_PI)); - NodeItem x = angle[0]; - NodeItem y = angle[1]; - NodeItem z = angle[2]; + NodeItem x = angle_xyz[0]; + NodeItem y = angle_xyz[1]; + NodeItem z = angle_xyz[2]; if (invert) { return rotate(z, val(MaterialX::Vector3(0.0f, 0.0f, 1.0f))) .rotate(y, val(MaterialX::Vector3(0.0f, 1.0f, 0.0f))) diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index e79d1135672..027989bf618 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -92,8 +92,8 @@ class NodeItem { NodeItem mix(const NodeItem &val1, const NodeItem &val2) const; NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const; NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const; - NodeItem rotate(const NodeItem &angle, const NodeItem &axis); - NodeItem rotate(const NodeItem &angle_xyz, bool invert = false); + NodeItem rotate(const NodeItem &angle, const NodeItem &axis); /* angle in degrees */ + NodeItem rotate(const NodeItem &angle_xyz, bool invert = false); /* angle in degrees */ NodeItem sin() const; NodeItem cos() const; NodeItem tan() const; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index 8eefbac6e20..abb1d324d8f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -337,7 +337,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = in["roughness"]; NodeItem anisotropy = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"]; + NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI));; NodeItem base_color = in["base_color"]; NodeItem specular = in["specular"]; NodeItem coat = in["coat"]; @@ -348,7 +348,8 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem n_main_tangent = empty(); if (tangent && normal) { - NodeItem n_tangent_rotate_normalize = tangent.rotate(rotation, normal).normalize(); + NodeItem n_tangent_rotate_normalize = + tangent.rotate(rotation, normal).normalize(); n_main_tangent = anisotropy.if_else( NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent); } @@ -501,7 +502,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = in["roughness"]; NodeItem base_color = in["base_color"]; NodeItem anisotropic = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"]; + NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI)); res = create_node("standard_surface", NodeItem::Type::SurfaceShader, diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.cc b/source/blender/nodes/shader/nodes/node_shader_mapping.cc index 96a647c0f62..80db047831c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.cc @@ -85,7 +85,8 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem scale = get_input_value("Scale", NodeItem::Type::Vector3); NodeItem location = get_input_value("Location", NodeItem::Type::Vector3); - NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3); + NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3) * + val(float(180.0f / M_PI)); switch (node_->custom1) { case NODE_MAPPING_TYPE_POINT: diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index 7c369199e62..c7116f6b13d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -227,7 +227,7 @@ NODE_SHADER_MATERIALX_BEGIN val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); NodeItem res = vector - center; int mode = node_->custom1; - bool invert = node_->custom1; + bool invert = node_->custom2; if (mode == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { angle = get_input_value("Rotation", NodeItem::Type::Vector3); -- 2.30.2 From c713a2185175803366bfb6d551334bf26f1a5ef9 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 14:07:15 +0300 Subject: [PATCH 12/16] Simplified code in Mapping and Vector rotate nodes. make format --- .../nodes/shader/materialx/node_item.cc | 7 +- .../nodes/shader/materialx/node_item.h | 4 +- .../nodes/shader/materialx/node_parser.h | 2 +- .../nodes/node_shader_bsdf_principled.cc | 5 +- .../nodes/shader/nodes/node_shader_mapping.cc | 37 +++++------ .../shader/nodes/node_shader_vector_rotate.cc | 66 +++++++------------ 6 files changed, 49 insertions(+), 72 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 1af34376a68..4e38fb3dedb 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -379,11 +379,8 @@ NodeItem NodeItem::rotate(const NodeItem &angle, const NodeItem &axis) BLI_assert(angle.type() == Type::Float); BLI_assert(axis.type() == Type::Vector3); - return create_node("rotate3d", - NodeItem::Type::Vector3, - {{"in", *this}, - {"amount", angle}, - {"axis", axis}}); + return create_node( + "rotate3d", NodeItem::Type::Vector3, {{"in", *this}, {"amount", angle}, {"axis", axis}}); } NodeItem NodeItem::rotate(const NodeItem &angle_xyz, bool invert) diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index 027989bf618..0b6069c406a 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -92,8 +92,8 @@ class NodeItem { NodeItem mix(const NodeItem &val1, const NodeItem &val2) const; NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const; NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const; - NodeItem rotate(const NodeItem &angle, const NodeItem &axis); /* angle in degrees */ - NodeItem rotate(const NodeItem &angle_xyz, bool invert = false); /* angle in degrees */ + NodeItem rotate(const NodeItem &angle, const NodeItem &axis); /* angle in degrees */ + NodeItem rotate(const NodeItem &angle_xyz, bool invert = false); /* angle in degrees */ NodeItem sin() const; NodeItem cos() const; NodeItem tan() const; diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 41821efd153..937a8bfdb9e 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -78,7 +78,7 @@ template NodeItem NodeParser::val(const T &data) const /** * Defines for including MaterialX node parsing code into node_shader_.cc - * + * * Example: * \code{.c} * NODE_SHADER_MATERIALX_BEGIN diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index abb1d324d8f..1be6d1ccc03 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -337,7 +337,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = in["roughness"]; NodeItem anisotropy = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI));; + NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI)); NodeItem base_color = in["base_color"]; NodeItem specular = in["specular"]; NodeItem coat = in["coat"]; @@ -348,8 +348,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem n_main_tangent = empty(); if (tangent && normal) { - NodeItem n_tangent_rotate_normalize = - tangent.rotate(rotation, normal).normalize(); + NodeItem n_tangent_rotate_normalize = tangent.rotate(rotation, normal).normalize(); n_main_tangent = anisotropy.if_else( NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent); } diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.cc b/source/blender/nodes/shader/nodes/node_shader_mapping.cc index 80db047831c..9937c02cd17 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.cc @@ -77,34 +77,31 @@ static void node_shader_update_mapping(bNodeTree *ntree, bNode *node) NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - NodeItem res = empty(); - NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3); - if (!vector) { - return empty(); - } - + NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3); NodeItem scale = get_input_value("Scale", NodeItem::Type::Vector3); - NodeItem location = get_input_value("Location", NodeItem::Type::Vector3); NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3) * val(float(180.0f / M_PI)); - switch (node_->custom1) { - case NODE_MAPPING_TYPE_POINT: + int type = node_->custom1; + switch (type) { + case NODE_MAPPING_TYPE_POINT: { + NodeItem location = get_input_value("Location", NodeItem::Type::Vector3); return (vector * scale).rotate(rotation) + location; - break; - case NODE_MAPPING_TYPE_TEXTURE: - res = (vector - location).rotate(rotation, true) / scale; - break; - case NODE_MAPPING_TYPE_VECTOR: - res = (vector * scale).rotate(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f))); - break; - case NODE_MAPPING_TYPE_NORMAL: - res = (vector / scale).rotate(rotation).normalize(); - break; + } + case NODE_MAPPING_TYPE_TEXTURE: { + NodeItem location = get_input_value("Location", NodeItem::Type::Vector3); + return (vector - location).rotate(rotation, true) / scale; + } + case NODE_MAPPING_TYPE_VECTOR: { + return (vector * scale).rotate(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f))); + } + case NODE_MAPPING_TYPE_NORMAL: { + return (vector / scale).rotate(rotation).normalize(); + } default: BLI_assert_unreachable(); } - return res; + return empty(); } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index c7116f6b13d..59a4294bd01 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -215,61 +215,45 @@ static void node_shader_update_vector_rotate(bNodeTree *ntree, bNode *node) NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3); + /* Axes */ + const NodeItem X = val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)); + const NodeItem Y = val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)); + const NodeItem Z = val(MaterialX::Vector3(0.0f, 0.0f, -1.0f)); - if (!vector) { - return empty(); - } - - NodeItem angle = empty(); - NodeItem axis = empty(); - NodeItem center = get_input_value("Center", NodeItem::Type::Vector3) * - val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); - NodeItem res = vector - center; int mode = node_->custom1; bool invert = node_->custom2; + NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3); + NodeItem center = get_input_value("Center", NodeItem::Type::Vector3) * (X + Y + Z); + + vector = vector - center; + if (mode == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { - angle = get_input_value("Rotation", NodeItem::Type::Vector3); - angle = angle * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); - } - else { - angle = get_input_value("Angle", NodeItem::Type::Float); - } - - angle = invert ? angle * val(-1.0f) : angle; + NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3) * + val(float(180.0f / M_PI)) * (X + Y + Z); + return vector.rotate(invert ? -rotation : rotation, invert) + center; + } + NodeItem angle = get_input_value("Angle", NodeItem::Type::Float) * val(float(180.0f / M_PI)); + NodeItem axis = empty(); switch (mode) { - case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: { - return res.rotate(angle, invert) + center; - } - case NODE_VECTOR_ROTATE_TYPE_AXIS: { - axis = get_input_value("Axis", NodeItem::Type::Vector3) * - val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); + case NODE_VECTOR_ROTATE_TYPE_AXIS: + axis = get_input_value("Axis", NodeItem::Type::Vector3) * (X + Y + Z); break; - } - case NODE_VECTOR_ROTATE_TYPE_AXIS_X: { - axis = val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)); + case NODE_VECTOR_ROTATE_TYPE_AXIS_X: + axis = X; break; - } - case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: { - axis = val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)); + case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: + axis = Y; break; - } - case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: { - axis = val(MaterialX::Vector3(0.0f, 0.0f, -1.0f)); + case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: + axis = Z; break; - } - default: { + default: BLI_assert_unreachable(); - return vector; - } } - return create_node("rotate3d", - NodeItem::Type::Vector3, - {{"in", res}, {"amount", angle}, {"axis", axis}}) + - center; + return vector.rotate(invert ? -angle : angle, axis) + center; } #endif NODE_SHADER_MATERIALX_END -- 2.30.2 From 3ea023ba4aca1d5f2c4790116ecf9f19071cb32b Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 14:48:26 +0300 Subject: [PATCH 13/16] Fixing rotations --- .../nodes/node_shader_bsdf_principled.cc | 4 ++-- .../shader/nodes/node_shader_vector_rotate.cc | 20 ++++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc index 1be6d1ccc03..6a8b16ef14b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc @@ -337,7 +337,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = in["roughness"]; NodeItem anisotropy = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI)); + NodeItem rotation = in["anisotropic_rotation"] * val(360.0f); NodeItem base_color = in["base_color"]; NodeItem specular = in["specular"]; NodeItem coat = in["coat"]; @@ -501,7 +501,7 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = in["roughness"]; NodeItem base_color = in["base_color"]; NodeItem anisotropic = in["anisotropic"]; - NodeItem rotation = in["anisotropic_rotation"] * val(float(180.0f / M_PI)); + NodeItem rotation = in["anisotropic_rotation"]; res = create_node("standard_surface", NodeItem::Type::SurfaceShader, diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index 59a4294bd01..9b737ace87b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -215,39 +215,35 @@ static void node_shader_update_vector_rotate(bNodeTree *ntree, bNode *node) NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - /* Axes */ - const NodeItem X = val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)); - const NodeItem Y = val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)); - const NodeItem Z = val(MaterialX::Vector3(0.0f, 0.0f, -1.0f)); - int mode = node_->custom1; bool invert = node_->custom2; NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3); - NodeItem center = get_input_value("Center", NodeItem::Type::Vector3) * (X + Y + Z); - + NodeItem center = get_input_value("Center", NodeItem::Type::Vector3); vector = vector - center; if (mode == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3) * - val(float(180.0f / M_PI)) * (X + Y + Z); + val(MaterialX::Vector3(1.0f, 1.0f, -1.0f) * 180.0f / M_PI); return vector.rotate(invert ? -rotation : rotation, invert) + center; } + NodeItem angle = get_input_value("Angle", NodeItem::Type::Float) * val(float(180.0f / M_PI)); NodeItem axis = empty(); switch (mode) { case NODE_VECTOR_ROTATE_TYPE_AXIS: - axis = get_input_value("Axis", NodeItem::Type::Vector3) * (X + Y + Z); + axis = get_input_value("Axis", NodeItem::Type::Vector3) * + val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); break; case NODE_VECTOR_ROTATE_TYPE_AXIS_X: - axis = X; + axis = val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)); break; case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: - axis = Y; + axis = val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)); break; case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: - axis = Z; + axis = val(MaterialX::Vector3(0.0f, 0.0f, -1.0f)); break; default: BLI_assert_unreachable(); -- 2.30.2 From 9bcb2ff0fb70c645624361d6c468f8f9b20efb8b Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 15:03:24 +0300 Subject: [PATCH 14/16] Changed order of getting shader type in MaterialOutput: SurfaceShader starts first. Adjusted Add, Mix shaders. --- .../shader/nodes/node_shader_add_shader.cc | 45 +++++++---------- .../shader/nodes/node_shader_mix_shader.cc | 48 +++++++------------ .../nodes/node_shader_output_material.cc | 25 +++++----- 3 files changed, 46 insertions(+), 72 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_add_shader.cc b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc index 7f5ba0162d7..6e0e0a81a51 100644 --- a/source/blender/nodes/shader/nodes/node_shader_add_shader.cc +++ b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc @@ -25,36 +25,23 @@ static int node_shader_gpu_add_shader(GPUMaterial *mat, NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - NodeItem res = empty(); - switch (to_type_) { - case NodeItem::Type::BSDF: - case NodeItem::Type::EDF: { - NodeItem shader1 = get_input_link(0, to_type_); - NodeItem shader2 = get_input_link(1, to_type_); - - if (shader1 && !shader2) { - res = shader1; - } - else if (!shader1 && shader2) { - res = shader2; - } - else if (shader1 && shader2) { - res = shader1 + shader2; - } - break; - } - case NodeItem::Type::SurfaceShader: { - /* SurfaceShaders can't be added, returning the first one connected */ - res = get_input_link(0, to_type_); - if (!res) { - res = get_input_link(1, to_type_); - } - break; - } - default: - BLI_assert_unreachable(); + if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) { + return empty(); } - return res; + + NodeItem shader1 = get_input_link(0, to_type_); + NodeItem shader2 = get_input_link(1, to_type_); + if (!shader1 && !shader2) { + return empty(); + } + + if (shader1 && !shader2) { + return shader1; + } + if (!shader1 && shader2) { + return shader2; + } + return shader1 + shader2; } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc index ada5b6a6911..249d4f85c7a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc @@ -26,37 +26,25 @@ static int node_shader_gpu_mix_shader(GPUMaterial *mat, NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - NodeItem res = empty(); - switch (to_type_) { - case NodeItem::Type::BSDF: - case NodeItem::Type::EDF: { - NodeItem fac = get_input_value(0, NodeItem::Type::Float); - NodeItem shader1 = get_input_link(1, to_type_); - NodeItem shader2 = get_input_link(2, to_type_); - - if (shader1 && !shader2) { - res = shader1 * (val(1.0f) - fac); - } - else if (!shader1 && shader2) { - res = shader2 * fac; - } - else if (shader1 && shader2) { - res = fac.mix(shader1, shader2); - } - break; - } - case NodeItem::Type::SurfaceShader: { - /* SurfaceShaders can't be mixed, returning the first one connected */ - res = get_input_link(1, NodeItem::Type::SurfaceShader); - if (!res) { - res = get_input_link(2, NodeItem::Type::SurfaceShader); - } - break; - } - default: - BLI_assert_unreachable(); + if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) { + return empty(); } - return res; + + NodeItem shader1 = get_input_link(1, to_type_); + NodeItem shader2 = get_input_link(2, to_type_); + if (!shader1 && !shader2) { + return empty(); + } + + NodeItem fac = get_input_value(0, NodeItem::Type::Float); + + if (shader1 && !shader2) { + return shader1 * (val(1.0f) - fac); + } + if (!shader1 && shader2) { + return shader2 * fac; + } + return fac.mix(shader1, shader2); } #endif NODE_SHADER_MATERIALX_END diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.cc b/source/blender/nodes/shader/nodes/node_shader_output_material.cc index f9aa8cf13e6..b405c40e8af 100644 --- a/source/blender/nodes/shader/nodes/node_shader_output_material.cc +++ b/source/blender/nodes/shader/nodes/node_shader_output_material.cc @@ -46,20 +46,19 @@ static int node_shader_gpu_output_material(GPUMaterial *mat, NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { - NodeItem bsdf = get_input_link("Surface", NodeItem::Type::BSDF); - NodeItem edf = get_input_link("Surface", NodeItem::Type::EDF); - NodeItem surface = empty(); - if (bsdf || edf) { - surface = create_node("surface", NodeItem::Type::SurfaceShader); - if (bsdf) { - surface.set_input("bsdf", bsdf); + NodeItem surface = get_input_link("Surface", NodeItem::Type::SurfaceShader); + if (!surface) { + NodeItem bsdf = get_input_link("Surface", NodeItem::Type::BSDF); + NodeItem edf = get_input_link("Surface", NodeItem::Type::EDF); + if (bsdf || edf) { + surface = create_node("surface", NodeItem::Type::SurfaceShader); + if (bsdf) { + surface.set_input("bsdf", bsdf); + } + if (edf) { + surface.set_input("edf", edf); + } } - if (edf) { - surface.set_input("edf", edf); - } - } - else { - surface = get_input_link("Surface", NodeItem::Type::SurfaceShader); } return create_node("surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}}); } -- 2.30.2 From 14a381c024455f9675af5c39b0aca33022bc6f6b Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 15:12:40 +0300 Subject: [PATCH 15/16] Reverting back mistake changes --- .../nodes/shader/nodes/node_shader_tex_wave.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index 379ca657c0a..73b0a97e65a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -135,9 +135,9 @@ class WaveFunction : public mf::MultiFunction { MutableSpan r_fac = params.uninitialized_single_output(8, "Fac"); mask.foreach_index([&](const int64_t i) { - float3 pos = vector[i] * scale[i]; + float3 p = vector[i] * scale[i]; /* Prevent precision issues on unit coordinates. */ - pos = (pos + 0.000001f) * 0.999999f; + p = (p + 0.000001f) * 0.999999f; float n = 0.0f; float val = 0.0f; @@ -146,21 +146,21 @@ class WaveFunction : public mf::MultiFunction { case SHD_WAVE_BANDS: switch (bands_direction_) { case SHD_WAVE_BANDS_DIRECTION_X: - n = pos.x * 20.0f; + n = p.x * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_Y: - n = pos.y * 20.0f; + n = p.y * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_Z: - n = pos.z * 20.0f; + n = p.z * 20.0f; break; case SHD_WAVE_BANDS_DIRECTION_DIAGONAL: - n = (pos.x + pos.y + pos.z) * 10.0f; + n = (p.x + p.y + p.z) * 10.0f; break; } break; case SHD_WAVE_RINGS: - float3 rp = pos; + float3 rp = p; switch (rings_direction_) { case SHD_WAVE_RINGS_DIRECTION_X: rp *= float3(0.0f, 1.0f, 1.0f); @@ -183,7 +183,7 @@ class WaveFunction : public mf::MultiFunction { if (distortion[i] != 0.0f) { n += distortion[i] * - (noise::perlin_fractal(pos * dscale[i], detail[i], droughness[i], 2.0f, true) * 2.0f - + (noise::perlin_fractal(p * dscale[i], detail[i], droughness[i], 2.0f, true) * 2.0f - 1.0f); } -- 2.30.2 From aaa31cdd9d27111613740edb73f8b1227f9c198c Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 22 Sep 2023 18:49:20 +0300 Subject: [PATCH 16/16] Fixed review comments --- source/blender/nodes/shader/materialx/node_item.cc | 12 ++++++------ source/blender/nodes/shader/materialx/node_parser.h | 2 +- .../nodes/shader/nodes/node_shader_vector_rotate.cc | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 4e38fb3dedb..bcb7bdf52f9 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -291,31 +291,31 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const float f = 0.0f; switch (d.type()) { case Type::Float: { - f = value->asA(); + f = d.value->asA(); break; } case Type::Vector2: { - auto v = value->asA(); + auto v = d.value->asA(); f = v[0] + v[1]; break; } case Type::Vector3: { - auto v = value->asA(); + auto v = d.value->asA(); f = v[0] + v[1] + v[2]; break; } case Type::Vector4: { - auto v = value->asA(); + auto v = d.value->asA(); f = v[0] + v[1] + v[2] + v[3]; break; } case Type::Color3: { - auto v = value->asA(); + auto v = d.value->asA(); f = v[0] + v[1] + v[2]; break; } case Type::Color4: { - auto v = value->asA(); + auto v = d.value->asA(); f = v[0] + v[1] + v[2] + v[3]; break; } diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 937a8bfdb9e..0483bc13b23 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -20,7 +20,7 @@ class GroupNodeParser; /** * This is base abstraction class for parsing Blender nodes into MaterialX nodes. - * NodeParser::compute() should be overrides in child classes. + * NodeParser::compute() should be overrided in child classes. */ class NodeParser { protected: diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index 9b737ace87b..c93cac85b81 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -219,7 +219,8 @@ NODE_SHADER_MATERIALX_BEGIN bool invert = node_->custom2; NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3); - NodeItem center = get_input_value("Center", NodeItem::Type::Vector3); + NodeItem center = get_input_value("Center", NodeItem::Type::Vector3) * + val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)); vector = vector - center; if (mode == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { -- 2.30.2