forked from bartvdbraak/blender
Shading: Add Clamp node to Cycles and EEVEE.
This patch adds a new node that clamps a value between a maximum and a minimum values. Reviewers: brecht Differential Revision: https://developer.blender.org/D5476
This commit is contained in:
parent
42798a5ca1
commit
313b789289
@ -318,6 +318,9 @@ static ShaderNode *add_node(Scene *scene,
|
||||
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
|
||||
node = new MapRangeNode();
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
|
||||
node = new ClampNode();
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeMath)) {
|
||||
BL::ShaderNodeMath b_math_node(b_node);
|
||||
MathNode *math = new MathNode();
|
||||
|
@ -179,6 +179,7 @@ set(SRC_SVM_HEADERS
|
||||
svm/svm_blackbody.h
|
||||
svm/svm_bump.h
|
||||
svm/svm_camera.h
|
||||
svm/svm_clamp.h
|
||||
svm/svm_closure.h
|
||||
svm/svm_convert.h
|
||||
svm/svm_checker.h
|
||||
|
@ -13,6 +13,7 @@ set(SRC_OSL
|
||||
node_bump.osl
|
||||
node_camera.osl
|
||||
node_checker_texture.osl
|
||||
node_clamp.osl
|
||||
node_combine_rgb.osl
|
||||
node_combine_hsv.osl
|
||||
node_combine_xyz.osl
|
||||
|
23
intern/cycles/kernel/shaders/node_clamp.osl
Normal file
23
intern/cycles/kernel/shaders/node_clamp.osl
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2011-2013 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "stdosl.h"
|
||||
|
||||
shader node_clamp(float Value = 1.0, float Min = 0.0, float Max = 1.0,
|
||||
output float Result = 0.0)
|
||||
{
|
||||
Result = clamp(Value, Min, Max);
|
||||
}
|
@ -193,6 +193,7 @@ CCL_NAMESPACE_END
|
||||
#include "kernel/svm/svm_voxel.h"
|
||||
#include "kernel/svm/svm_bump.h"
|
||||
#include "kernel/svm/svm_map_range.h"
|
||||
#include "kernel/svm/svm_clamp.h"
|
||||
|
||||
#ifdef __SHADER_RAYTRACE__
|
||||
# include "kernel/svm/svm_ao.h"
|
||||
@ -490,6 +491,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
|
||||
case NODE_MAP_RANGE:
|
||||
svm_node_map_range(kg, sd, stack, node.y, node.z, node.w, &offset);
|
||||
break;
|
||||
case NODE_CLAMP:
|
||||
svm_node_clamp(kg, sd, stack, node.y, node.z, node.w, &offset);
|
||||
break;
|
||||
# endif /* __EXTRA_NODES__ */
|
||||
# if NODES_FEATURE(NODE_FEATURE_VOLUME)
|
||||
case NODE_TEX_VOXEL:
|
||||
|
41
intern/cycles/kernel/svm/svm_clamp.h
Normal file
41
intern/cycles/kernel/svm/svm_clamp.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011-2013 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Clamp Node */
|
||||
|
||||
ccl_device void svm_node_clamp(KernelGlobals *kg,
|
||||
ShaderData *sd,
|
||||
float *stack,
|
||||
uint value_stack_offset,
|
||||
uint parameters_stack_offsets,
|
||||
uint result_stack_offset,
|
||||
int *offset)
|
||||
{
|
||||
uint min_stack_offset, max_stack_offset;
|
||||
decode_node_uchar4(parameters_stack_offsets, &min_stack_offset, &max_stack_offset, NULL, NULL);
|
||||
|
||||
uint4 defaults = read_node(kg, offset);
|
||||
|
||||
float value = stack_load_float(stack, value_stack_offset);
|
||||
float min = stack_load_float_default(stack, min_stack_offset, defaults.x);
|
||||
float max = stack_load_float_default(stack, max_stack_offset, defaults.y);
|
||||
|
||||
stack_store_float(stack, result_stack_offset, clamp(value, min, max));
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@ -139,6 +139,7 @@ typedef enum ShaderNodeType {
|
||||
NODE_PRINCIPLED_VOLUME,
|
||||
NODE_IES,
|
||||
NODE_MAP_RANGE,
|
||||
NODE_CLAMP,
|
||||
} ShaderNodeType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
|
@ -5328,6 +5328,56 @@ void MapRangeNode::compile(OSLCompiler &compiler)
|
||||
compiler.add(this, "node_map_range");
|
||||
}
|
||||
|
||||
/* Clamp Node */
|
||||
|
||||
NODE_DEFINE(ClampNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("clamp", create, NodeType::SHADER);
|
||||
|
||||
SOCKET_IN_FLOAT(value, "Value", 1.0f);
|
||||
SOCKET_IN_FLOAT(min, "Min", 0.0f);
|
||||
SOCKET_IN_FLOAT(max, "Max", 1.0f);
|
||||
|
||||
SOCKET_OUT_FLOAT(result, "Result");
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
ClampNode::ClampNode() : ShaderNode(node_type)
|
||||
{
|
||||
}
|
||||
|
||||
void ClampNode::constant_fold(const ConstantFolder &folder)
|
||||
{
|
||||
if (folder.all_inputs_constant()) {
|
||||
folder.make_constant(clamp(value, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
void ClampNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
ShaderInput *value_in = input("Value");
|
||||
ShaderInput *min_in = input("Min");
|
||||
ShaderInput *max_in = input("Max");
|
||||
ShaderOutput *result_out = output("Result");
|
||||
|
||||
int value_stack_offset = compiler.stack_assign(value_in);
|
||||
int min_stack_offset = compiler.stack_assign(min_in);
|
||||
int max_stack_offset = compiler.stack_assign(max_in);
|
||||
int result_stack_offset = compiler.stack_assign(result_out);
|
||||
|
||||
compiler.add_node(NODE_CLAMP,
|
||||
value_stack_offset,
|
||||
compiler.encode_uchar4(min_stack_offset, max_stack_offset),
|
||||
result_stack_offset);
|
||||
compiler.add_node(__float_as_int(min), __float_as_int(max));
|
||||
}
|
||||
|
||||
void ClampNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
compiler.add(this, "node_clamp");
|
||||
}
|
||||
|
||||
/* Math */
|
||||
|
||||
NODE_DEFINE(MathNode)
|
||||
|
@ -1239,6 +1239,17 @@ class MapRangeNode : public ShaderNode {
|
||||
float value, from_min, from_max, to_min, to_max;
|
||||
};
|
||||
|
||||
class ClampNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(ClampNode)
|
||||
void constant_fold(const ConstantFolder &folder);
|
||||
virtual int get_group()
|
||||
{
|
||||
return NODE_GROUP_LEVEL_3;
|
||||
}
|
||||
float value, min, max;
|
||||
};
|
||||
|
||||
class MathNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(MathNode)
|
||||
|
@ -259,6 +259,7 @@ shader_node_categories = [
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[
|
||||
NodeItem("ShaderNodeMapRange"),
|
||||
NodeItem("ShaderNodeClamp"),
|
||||
NodeItem("ShaderNodeMath"),
|
||||
NodeItem("ShaderNodeValToRGB"),
|
||||
NodeItem("ShaderNodeRGBToBW"),
|
||||
|
@ -977,6 +977,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
|
||||
/* 201..700 occupied by other node types, continue from 701 */
|
||||
#define SH_NODE_BSDF_HAIR_PRINCIPLED 701
|
||||
#define SH_NODE_MAP_RANGE 702
|
||||
#define SH_NODE_CLAMP 703
|
||||
|
||||
/* custom defines options for Material node */
|
||||
#define SH_NODE_MAT_DIFF 1
|
||||
|
@ -3857,6 +3857,7 @@ static void registerShaderNodes(void)
|
||||
register_node_type_sh_curve_vec();
|
||||
register_node_type_sh_curve_rgb();
|
||||
register_node_type_sh_map_range();
|
||||
register_node_type_sh_clamp();
|
||||
register_node_type_sh_math();
|
||||
register_node_type_sh_vect_math();
|
||||
register_node_type_sh_vect_transform();
|
||||
|
@ -971,9 +971,9 @@ void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
|
||||
out_vec = clamp(vec, min, max);
|
||||
}
|
||||
|
||||
void clamp_val(float value, float min, float max, out float out_value)
|
||||
void clamp_value(float value, float min, float max, out float result)
|
||||
{
|
||||
out_value = clamp(value, min, max);
|
||||
result = clamp(value, min, max);
|
||||
}
|
||||
|
||||
void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
|
||||
|
@ -147,6 +147,7 @@ set(SRC
|
||||
shader/nodes/node_shader_bsdf_velvet.c
|
||||
shader/nodes/node_shader_bump.c
|
||||
shader/nodes/node_shader_camera.c
|
||||
shader/nodes/node_shader_clamp.c
|
||||
shader/nodes/node_shader_common.c
|
||||
shader/nodes/node_shader_curves.c
|
||||
shader/nodes/node_shader_displacement.c
|
||||
|
@ -49,6 +49,7 @@ void register_node_type_sh_mapping(void);
|
||||
void register_node_type_sh_curve_vec(void);
|
||||
void register_node_type_sh_curve_rgb(void);
|
||||
void register_node_type_sh_map_range(void);
|
||||
void register_node_type_sh_clamp(void);
|
||||
void register_node_type_sh_math(void);
|
||||
void register_node_type_sh_vect_math(void);
|
||||
void register_node_type_sh_squeeze(void);
|
||||
|
@ -51,6 +51,7 @@ DefNode(ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_
|
||||
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_MAP_RANGE, 0, "MAP_RANGE", MapRange, "Map Range", "" )
|
||||
DefNode(ShaderNode, SH_NODE_CLAMP, 0, "CLAMP", Clamp, "Clamp", "" )
|
||||
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_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" )
|
||||
|
56
source/blender/nodes/shader/nodes/node_shader_clamp.c
Normal file
56
source/blender/nodes/shader/nodes/node_shader_clamp.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup shdnodes
|
||||
*/
|
||||
|
||||
#include "node_shader_util.h"
|
||||
|
||||
/* **************** Clamp ******************** */
|
||||
static bNodeSocketTemplate sh_node_clamp_in[] = {
|
||||
{SOCK_FLOAT, 1, N_("Value"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
|
||||
{SOCK_FLOAT, 1, N_("Min"), 0.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
|
||||
{SOCK_FLOAT, 1, N_("Max"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
|
||||
{-1, 0, ""},
|
||||
};
|
||||
static bNodeSocketTemplate sh_node_clamp_out[] = {
|
||||
{SOCK_FLOAT, 0, N_("Result")},
|
||||
{-1, 0, ""},
|
||||
};
|
||||
|
||||
static int gpu_shader_clamp(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "clamp_value", in, out);
|
||||
}
|
||||
|
||||
void register_node_type_sh_clamp(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
sh_node_type_base(&ntype, SH_NODE_CLAMP, "Clamp", NODE_CLASS_CONVERTOR, 0);
|
||||
node_type_socket_templates(&ntype, sh_node_clamp_in, sh_node_clamp_out);
|
||||
node_type_gpu(&ntype, gpu_shader_clamp);
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
@ -360,7 +360,7 @@ static int gpu_shader_math(GPUMaterial *mat,
|
||||
if (node->custom2 & SHD_MATH_CLAMP) {
|
||||
float min[3] = {0.0f, 0.0f, 0.0f};
|
||||
float max[3] = {1.0f, 1.0f, 1.0f};
|
||||
GPU_link(mat, "clamp_val", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
|
||||
GPU_link(mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user