diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index 8fa84213de7a..c1fa1d64bf67 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -233,7 +233,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; }); + NodeItem d = arithmetic( + other, "dotproduct", [](float a, float b) { return a * b; }, Type::Float); if (d.value) { float f = 0.0f; switch (d.type()) { @@ -830,12 +831,13 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function func) const + std::function func, + Type to_type) const { NodeItem res = empty(); NodeItem item1 = *this; NodeItem item2 = other; - Type to_type = cast_types(item1, item2); + to_type = (to_type == Type::Any) ? cast_types(item1, item2) : to_type; if (to_type == Type::Empty) { return res; } diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index 40be1153031b..7cdf8cc59ee1 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -127,7 +127,8 @@ class NodeItem { NodeItem arithmetic(const std::string &category, std::function func) const; NodeItem arithmetic(const NodeItem &other, const std::string &category, - std::function func) const; + std::function func, + Type to_type = Type::Any) const; }; template NodeItem NodeItem::val(const T &data) const 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 dc1b8046e084..989a1e527ec5 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -147,6 +147,50 @@ static void sh_node_gradient_tex_build_multi_function(NodeMultiFunctionBuilder & builder.construct_and_set_matching_fn(tex->gradient_type); } +NODE_SHADER_MATERIALX_BEGIN +#ifdef WITH_MATERIALX +{ + NodeTexGradient *tex = (NodeTexGradient *)node_->storage; + const int gradient_type = tex->gradient_type; + NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); + if (!vector) { + vector = texcoord_node(); + } + NodeItem res = empty(); + + switch (gradient_type) { + case SHD_BLEND_LINEAR: + res = vector.extract(0); + break; + case SHD_BLEND_QUADRATIC: + res = vector.extract(0); + res = res * res; + break; + case SHD_BLEND_EASING: + res = vector.extract(0).clamp(val(0.0f), val(1.0f)); + 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); + break; + case SHD_BLEND_RADIAL: + res = vector.extract(1).atan2(vector.extract(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)); + res = res * res; + break; + case SHD_BLEND_SPHERICAL: + res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f)); + break; + default: + BLI_assert_unreachable(); + } + return res; +} +#endif +NODE_SHADER_MATERIALX_END + } // namespace blender::nodes::node_shader_tex_gradient_cc void register_node_type_sh_tex_gradient() @@ -163,6 +207,7 @@ void register_node_type_sh_tex_gradient() &ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage); ntype.gpu_fn = file_ns::node_shader_gpu_tex_gradient; ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function; + ntype.materialx_fn = file_ns::node_shader_materialx; nodeRegisterType(&ntype); }