Shading: Add a clamp option to the Map Range node.
If the option is enabled, the output is clamped to the target range. The target range is [To Min, To Max]. The option is enabled by default. The clamp option is implemented in EEVEE by linking to the `clamp_value` GLSL function. And it is implemented in Cycles using a graph expand function. Reviewers: brecht, JacquesLucke Differential Revision: https://developer.blender.org/D5477
This commit is contained in:
@@ -316,7 +316,10 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
node = new RGBToBWNode();
|
node = new RGBToBWNode();
|
||||||
}
|
}
|
||||||
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
|
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
|
||||||
node = new MapRangeNode();
|
BL::ShaderNodeMapRange b_map_range_node(b_node);
|
||||||
|
MapRangeNode *map_range_node = new MapRangeNode();
|
||||||
|
map_range_node->clamp = b_map_range_node.clamp();
|
||||||
|
node = map_range_node;
|
||||||
}
|
}
|
||||||
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
|
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
|
||||||
node = new ClampNode();
|
node = new ClampNode();
|
||||||
|
|||||||
@@ -5280,6 +5280,21 @@ MapRangeNode::MapRangeNode() : ShaderNode(node_type)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapRangeNode::expand(ShaderGraph *graph)
|
||||||
|
{
|
||||||
|
if (clamp) {
|
||||||
|
ShaderOutput *result_out = output("Result");
|
||||||
|
if (!result_out->links.empty()) {
|
||||||
|
ClampNode *clamp_node = new ClampNode();
|
||||||
|
clamp_node->min = to_min;
|
||||||
|
clamp_node->max = to_max;
|
||||||
|
graph->add(clamp_node);
|
||||||
|
graph->relink(result_out, clamp_node->output("Result"));
|
||||||
|
graph->connect(result_out, clamp_node->input("Value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MapRangeNode::constant_fold(const ConstantFolder &folder)
|
void MapRangeNode::constant_fold(const ConstantFolder &folder)
|
||||||
{
|
{
|
||||||
if (folder.all_inputs_constant()) {
|
if (folder.all_inputs_constant()) {
|
||||||
|
|||||||
@@ -1236,7 +1236,10 @@ class MapRangeNode : public ShaderNode {
|
|||||||
{
|
{
|
||||||
return NODE_GROUP_LEVEL_3;
|
return NODE_GROUP_LEVEL_3;
|
||||||
}
|
}
|
||||||
|
void expand(ShaderGraph *graph);
|
||||||
|
|
||||||
float value, from_min, from_max, to_min, to_max;
|
float value, from_min, from_max, to_min, to_max;
|
||||||
|
bool clamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClampNode : public ShaderNode {
|
class ClampNode : public ShaderNode {
|
||||||
|
|||||||
@@ -249,6 +249,11 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void node_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
uiItemR(layout, ptr, "clamp", 0, NULL, ICON_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
|
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
|
||||||
@@ -1209,6 +1214,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
|||||||
case SH_NODE_VALTORGB:
|
case SH_NODE_VALTORGB:
|
||||||
ntype->draw_buttons = node_buts_colorramp;
|
ntype->draw_buttons = node_buts_colorramp;
|
||||||
break;
|
break;
|
||||||
|
case SH_NODE_MAP_RANGE:
|
||||||
|
ntype->draw_buttons = node_buts_map_range;
|
||||||
|
break;
|
||||||
case SH_NODE_MATH:
|
case SH_NODE_MATH:
|
||||||
ntype->draw_buttons = node_buts_math;
|
ntype->draw_buttons = node_buts_math;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3834,6 +3834,16 @@ static void def_frame(StructRNA *srna)
|
|||||||
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
|
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void def_map_range(StructRNA *srna)
|
||||||
|
{
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "clamp", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
|
||||||
|
RNA_def_property_ui_text(prop, "Clamp", "Clamp the result to the target range [To Min, To Max]");
|
||||||
|
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||||
|
}
|
||||||
|
|
||||||
static void def_math(StructRNA *srna)
|
static void def_math(StructRNA *srna)
|
||||||
{
|
{
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ DefNode(ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPIN
|
|||||||
DefNode(ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" )
|
DefNode(ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" )
|
DefNode(ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" )
|
DefNode(ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_MAP_RANGE, 0, "MAP_RANGE", MapRange, "Map Range", "" )
|
DefNode(ShaderNode, SH_NODE_MAP_RANGE, def_map_range, "MAP_RANGE", MapRange, "Map Range", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_CLAMP, 0, "CLAMP", Clamp, "Clamp", "" )
|
DefNode(ShaderNode, SH_NODE_CLAMP, 0, "CLAMP", Clamp, "Clamp", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" )
|
DefNode(ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" )
|
||||||
DefNode(ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
|
DefNode(ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
|
||||||
|
|||||||
@@ -37,13 +37,22 @@ static bNodeSocketTemplate sh_node_map_range_out[] = {
|
|||||||
{-1, 0, ""},
|
{-1, 0, ""},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node)
|
||||||
|
{
|
||||||
|
node->custom1 = true;
|
||||||
|
}
|
||||||
|
|
||||||
static int gpu_shader_map_range(GPUMaterial *mat,
|
static int gpu_shader_map_range(GPUMaterial *mat,
|
||||||
bNode *node,
|
bNode *node,
|
||||||
bNodeExecData *UNUSED(execdata),
|
bNodeExecData *UNUSED(execdata),
|
||||||
GPUNodeStack *in,
|
GPUNodeStack *in,
|
||||||
GPUNodeStack *out)
|
GPUNodeStack *out)
|
||||||
{
|
{
|
||||||
return GPU_stack_link(mat, node, "map_range", in, out);
|
GPU_stack_link(mat, node, "map_range", in, out);
|
||||||
|
if (node->custom1) {
|
||||||
|
GPU_link(mat, "clamp_value", out[0].link, in[3].link, in[4].link, &out[0].link);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_node_type_sh_map_range(void)
|
void register_node_type_sh_map_range(void)
|
||||||
@@ -52,6 +61,7 @@ void register_node_type_sh_map_range(void)
|
|||||||
|
|
||||||
sh_node_type_base(&ntype, SH_NODE_MAP_RANGE, "Map Range", NODE_CLASS_CONVERTOR, 0);
|
sh_node_type_base(&ntype, SH_NODE_MAP_RANGE, "Map Range", NODE_CLASS_CONVERTOR, 0);
|
||||||
node_type_socket_templates(&ntype, sh_node_map_range_in, sh_node_map_range_out);
|
node_type_socket_templates(&ntype, sh_node_map_range_in, sh_node_map_range_out);
|
||||||
|
node_type_init(&ntype, node_shader_init_map_range);
|
||||||
node_type_gpu(&ntype, gpu_shader_map_range);
|
node_type_gpu(&ntype, gpu_shader_map_range);
|
||||||
|
|
||||||
nodeRegisterType(&ntype);
|
nodeRegisterType(&ntype);
|
||||||
|
|||||||
Reference in New Issue
Block a user