forked from blender/blender
MaterialX: Implement Gradient Texture node. #28
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
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
Bogdan Nagirniak
commented
use use `res = res.dotproduct(res).sqrt()`
|
||||
case SHD_BLEND_SPHERICAL:
|
||||
Vasyl-Pidhirskyi marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
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
Vasyl Pidhirskyi
commented
It's made according to Blender's implementation.
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);
```
Vasyl Pidhirskyi
commented
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
Bogdan Nagirniak
commented
add 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user
seems can be simplified to
res = res * res * (val(3.0f) - val(2.0f) * res)