MaterialX: Implement Gradient Texture node. #28

Merged
Bogdan Nagirniak merged 6 commits from Vasyl-Pidhirskyi/blender:BLEN-550 into matx-export-material 2023-09-21 09:31:28 +02:00
3 changed files with 52 additions and 4 deletions

View File

@ -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<float(f
NodeItem NodeItem::arithmetic(const NodeItem &other,
const std::string &category,
std::function<float(float, float)> func) const
std::function<float(float, float)> 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;
}

View File

@ -127,7 +127,8 @@ class NodeItem {
NodeItem arithmetic(const std::string &category, std::function<float(float)> func) const;
NodeItem arithmetic(const NodeItem &other,
const std::string &category,
std::function<float(float, float)> func) const;
std::function<float(float, float)> func,
Type to_type = Type::Any) const;
};
template<class T> NodeItem NodeItem::val(const T &data) const

View File

@ -147,6 +147,50 @@ static void sh_node_gradient_tex_build_multi_function(NodeMultiFunctionBuilder &
builder.construct_and_set_matching_fn<GradientFunction>(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:
Vasyl-Pidhirskyi marked this conversation as resolved
Review

seems can be simplified to
res = res * res * (val(3.0f) - val(2.0f) * res)

seems can be simplified to `res = res * res * (val(3.0f) - val(2.0f) * res)`
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;
Vasyl-Pidhirskyi marked this conversation as resolved Outdated

use res = res.dotproduct(res).sqrt()

use `res = res.dotproduct(res).sqrt()`
case SHD_BLEND_SPHERICAL:
Vasyl-Pidhirskyi marked this conversation as resolved Outdated

Why not 1.0f? Need comment why 0.999999f is used instead of 1.0f

Why not 1.0f? Need comment why 0.999999f is used instead of 1.0f

It's made according to Blender's implementation.

          /* Bias a little bit for the case where input is a unit length vector,
           * to get exactly zero instead of a small random value depending
           * on float precision. */
          const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
It's made according to Blender's implementation. ``` /* Bias a little bit for the case where input is a unit length vector, * to get exactly zero instead of a small random value depending * on float precision. */ const float r = std::max(0.999999f - math::length(vector[i]), 0.0f); ```

Added comment

Added comment
res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
break;
default:
BLI_assert_unreachable();
}
return res;
}
Vasyl-Pidhirskyi marked this conversation as resolved Outdated

add default: BLI_assert_unreachable()

add `default: BLI_assert_unreachable()`
#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);
}