35 b.add_input<
decl::Float>(
"Value").min(-10000.0f).
max(10000.0f).default_value(1.0f);
37 b.add_input<
decl::Float>(
"From Max").min(-10000.0f).
max(10000.0f).default_value(1.0f);
39 b.add_input<
decl::Float>(
"To Max").min(-10000.0f).
max(10000.0f).default_value(1.0f);
40 b.add_input<
decl::Float>(
"Steps").min(-10000.0f).
max(10000.0f).default_value(4.0f);
84 new_input_availability[index] = socket->type == type;
87 new_output_availability[index] = socket->type == type;
92 new_input_availability[5] =
false;
95 new_input_availability[11] =
false;
126 bNode &node =
params.add_node(
"ShaderNodeMapRange");
127 node_storage(node).data_type =
data_type;
135 switch (socket.
type) {
183 return "vector_map_range_linear";
185 return "vector_map_range_stepped";
187 return "vector_map_range_smoothstep";
189 return "vector_map_range_smootherstep";
195 return "map_range_linear";
197 return "map_range_stepped";
199 return "map_range_smoothstep";
201 return "map_range_smootherstep";
219 if (
name !=
nullptr) {
225 if (
ret && storage.
clamp && !use_vector &&
247 return mf::build::SI5_SO<float, float, float, float, float, float>(
248 Clamp ?
"Map Range (clamped)" :
"Map Range (unclamped)",
249 [](
float value,
float from_min,
float from_max,
float to_min,
float to_max) ->
float {
250 const float factor =
safe_divide(value - from_min, from_max - from_min);
251 float result = to_min + factor * (to_max - to_min);
252 if constexpr (
Clamp) {
257 mf::build::exec_presets::SomeSpanOrSingle<0>());
262 return mf::build::SI6_SO<float, float, float, float, float, float, float>(
263 Clamp ?
"Map Range Stepped (clamped)" :
"Map Range Stepped (unclamped)",
264 [](
float value,
float from_min,
float from_max,
float to_min,
float to_max,
float steps)
266 float factor =
safe_divide(value - from_min, from_max - from_min);
268 float result = to_min + factor * (to_max - to_min);
269 if constexpr (
Clamp) {
274 mf::build::exec_presets::SomeSpanOrSingle<0>());
279 return mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
280 Clamp ?
"Vector Map Range (clamped)" :
"Vector Map Range (unclamped)",
288 if constexpr (
Clamp) {
293 mf::build::exec_presets::SomeSpanOrSingle<0>());
298 return mf::build::SI6_SO<float3, float3, float3, float3, float3, float3, float3>(
299 Clamp ?
"Vector Map Range Stepped (clamped)" :
"Vector Map Range Stepped (unclamped)",
309 if constexpr (
Clamp) {
314 mf::build::exec_presets::SomeSpanOrSingle<0>());
325 switch (interpolation_type) {
349 static auto fn = mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
350 "Vector Map Range Smoothstep",
358 factor = (
float3(3.0f) - 2.0f * factor) * (factor * factor);
359 return factor * (to_max - to_min) + to_min;
361 mf::build::exec_presets::SomeSpanOrSingle<0>());
366 static auto fn = mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
367 "Vector Map Range Smootherstep",
375 factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
376 return factor * (to_max - to_min) + to_min;
378 mf::build::exec_presets::SomeSpanOrSingle<0>());
387 switch (interpolation_type) {
411 static auto fn = mf::build::SI5_SO<float, float, float, float, float, float>(
412 "Map Range Smoothstep",
413 [](
float value,
float from_min,
float from_max,
float to_min,
float to_max)
415 float factor =
safe_divide(value - from_min, from_max - from_min);
416 factor = std::clamp(factor, 0.0f, 1.0f);
417 factor = (3.0f - 2.0f * factor) * (factor * factor);
418 return to_min + factor * (to_max - to_min);
420 mf::build::exec_presets::SomeSpanOrSingle<0>());
425 static auto fn = mf::build::SI5_SO<float, float, float, float, float, float>(
426 "Map Range Smoothstep",
427 [](
float value,
float from_min,
float from_max,
float to_min,
float to_max)
429 float factor =
safe_divide(value - from_min, from_max - from_min);
430 factor = std::clamp(factor, 0.0f, 1.0f);
431 factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
432 return to_min + factor * (to_max - to_min);
434 mf::build::exec_presets::SomeSpanOrSingle<0>());
450 NodeItem value = empty();
451 NodeItem from_min = empty();
452 NodeItem from_max = empty();
453 NodeItem to_min = empty();
454 NodeItem to_max = empty();
455 NodeItem steps = empty();
458 type = NodeItem::Type::Float;
459 value = get_input_value(
"Value", type);
460 from_min = get_input_value(1, type);
461 from_max = get_input_value(2, type);
462 to_min = get_input_value(3, type);
463 to_max = get_input_value(4, type);
465 steps = get_input_value(5, type);
469 type = NodeItem::Type::Vector3;
470 value = get_input_value(
"Vector", type);
471 from_min = get_input_value(7, type);
472 from_max = get_input_value(8, type);
473 to_min = get_input_value(9, type);
474 to_max = get_input_value(10, type);
476 steps = get_input_value(11, type);
483 NodeItem res = empty();
486 res = create_node(
"remap",
490 {
"inhigh", from_max},
492 {
"outhigh", to_max}});
495 NodeItem factor = create_node(
496 "remap", type, {{
"in", value}, {
"inlow", from_min}, {
"inhigh", from_max}});
497 value = (factor * (steps + val(1.0f))).
floor() / steps;
498 res = create_node(
"remap", type, {{
"in", value}, {
"outlow", to_min}, {
"outhigh", to_max}});
504 "smoothstep", type, {{
"in", value}, {
"low", from_min}, {
"high", from_max}});
505 res = create_node(
"remap", type, {{
"in", value}, {
"outlow", to_min}, {
"outhigh", to_max}});
511 if (map_range->
clamp != 0) {
512 res = res.clamp(to_min, to_max);
529 ntype.
ui_description =
"Remap a value from a range to a target range";
532 ntype.
declare = file_ns::sh_node_map_range_declare;
533 ntype.
draw_buttons = file_ns::node_shader_buts_map_range;
534 ntype.
ui_class = file_ns::node_shader_map_range_ui_class;
535 ntype.
initfunc = file_ns::node_shader_init_map_range;
538 ntype.
updatefunc = file_ns::node_shader_update_map_range;
539 ntype.
gpu_fn = file_ns::gpu_shader_map_range;
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_OP_VECTOR
#define SH_NODE_MAP_RANGE
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float safe_divide(float a, float b)
MINLINE void clamp_v3(float vec[3], float min, float max)
@ NODE_MAP_RANGE_SMOOTHERSTEP
@ NODE_MAP_RANGE_SMOOTHSTEP
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
bool GPU_link(GPUMaterial *mat, const char *name,...)
static double Clamp(const double x, const double min, const double max)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
BMesh const char void * data
void set_matching_fn(const mf::MultiFunction *fn)
void operator()(LinkSearchOpParams ¶ms)
eCustomDataType data_type
constexpr T clamp(T, U, U) RET
void * MEM_callocN(size_t len, const char *str)
void node_register_type(bNodeType &ntype)
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
T safe_divide(const T &a, const T &b)
static int gpu_shader_map_range(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static auto build_vector_linear()
static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_buts_map_range(uiLayout *layout, bContext *, PointerRNA *ptr)
static auto build_vector_stepped()
static void node_shader_init_map_range(bNodeTree *, bNode *node)
static auto build_float_linear()
static const char * gpu_shader_get_name(int mode, bool use_vector)
static int node_shader_map_range_ui_class(const bNode *node)
static float clamp_range(const float value, const float min, const float max)
static std::optional< eCustomDataType > node_type_from_other_socket(const bNodeSocket &socket)
static void node_shader_update_map_range(bNodeTree *ntree, bNode *node)
static void node_map_range_gather_link_searches(GatherLinkSearchOpParams ¶ms)
static void sh_node_map_range_declare(NodeDeclarationBuilder &b)
static auto build_float_stepped()
VecBase< float, 3 > float3
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_map_range()
void common_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
int RNA_enum_get(PointerRNA *ptr, const char *name)
uint8_t interpolation_type
NodeMaterialXFunction materialx_fn
std::string ui_description
int(* ui_class)(const bNode *node)
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGPUExecFunction gpu_fn
NodeMultiFunctionBuildFunction build_multi_function
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
NodeDeclareFunction declare
void(* updatefunc)(bNodeTree *ntree, bNode *node)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)