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
Showing only changes of commit 33b7a7a0fd - Show all commits

View File

@ -147,6 +147,52 @@ 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();
NodeItem res_1 = 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_1 = res * res;
res = (val(3.0f) * res_1 - val(2.0f) * res_1 * res);
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)`
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 = create_node("dotproduct", NodeItem::Type::Float, {{"in1", vector}, {"in2", vector}});
Vasyl-Pidhirskyi marked this conversation as resolved Outdated

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

use `res = res.dotproduct(res).sqrt()`
res = (val(0.999999f) - res).max(val(0.0f));
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 = res * res;
break;
case SHD_BLEND_SPHERICAL:
res = create_node("dotproduct", NodeItem::Type::Float, {{"in1", vector}, {"in2", vector}});
res = (val(0.999999f) - res).max(val(0.0f));
break;
}
Vasyl-Pidhirskyi marked this conversation as resolved Outdated

add default: BLI_assert_unreachable()

add `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 +209,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);
}