Blender V5.0
node_shader_bump.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "node_shader_util.hh"
10
12#include "UI_resources.hh"
13
14/* **************** BUMP ******************** */
15
17
19{
20#define SOCK_STRENGTH_ID 0
21 b.add_input<decl::Float>("Strength")
22 .default_value(1.0f)
23 .min(0.0f)
24 .max(1.0f)
26 .description(
27 "Strength of the bump mapping effect, interpolating between "
28 "no bump mapping and full bump mapping")
29 .translation_context(BLT_I18NCONTEXT_AMOUNT);
30#define SOCK_DISTANCE_ID 1
31 b.add_input<decl::Float>("Distance")
32 .default_value(0.001f)
33 .min(0.0f)
34 .max(1000.0f)
36 "Multiplier for the height value to control the overall distance for bump mapping");
37#define SOCK_FILTER_WIDTH_ID 2
38 b.add_input<decl::Float>("Filter Width")
39 .default_value(0.1f)
40 .min(0.001)
41 .max(10.0f)
43 .description(
44 "Filter width in pixels, used to compute the bump mapping direction. For most textures "
45 "the default value of 0.1 enables subpixel filtering for stable results. For stepwise "
46 "textures a larger filter width can be used to get a bevel like effect on the edges");
47#define SOCK_HEIGHT_ID 3
48 b.add_input<decl::Float>("Height")
49 .default_value(1.0f)
50 .min(-1000.0f)
51 .max(1000.0f)
52 .hide_value()
53 .description("Height above surface. Connect the height map texture to this input");
54#define SOCK_NORMAL_ID 4
55 b.add_input<decl::Vector>("Normal").min(-1.0f).max(1.0f).hide_value();
56 b.add_output<decl::Vector>("Normal");
57}
58
59static void node_shader_buts_bump(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
60{
61 layout->prop(ptr, "invert", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
62}
63
65 bNode *node,
66 bNodeExecData * /*execdata*/,
69{
70 /* If there is no Height input, the node becomes a no-op. */
71 if (!in[SOCK_HEIGHT_ID].link) {
72 if (!in[SOCK_NORMAL_ID].link) {
73 return GPU_link(mat, "world_normals_get", &out[0].link);
74 }
75 /* Actually running the bump code would normalize, but Cycles handles it as total no-op. */
76 return GPU_link(mat, "vector_copy", in[SOCK_NORMAL_ID].link, &out[0].link);
77 }
78
79 if (!in[SOCK_NORMAL_ID].link) {
80 GPU_link(mat, "world_normals_get", &in[SOCK_NORMAL_ID].link);
81 }
82
83 const float filter_width = in[SOCK_FILTER_WIDTH_ID].vec[0];
84 const char *height_function = GPU_material_split_sub_function(
85 mat, GPU_FLOAT, &in[SOCK_HEIGHT_ID].link);
86
87 /* TODO (Miguel Pozo):
88 * Currently, this doesn't compute the actual differentials, just the height at dX and dY
89 * offsets. The actual differentials are computed inside the GLSL node_bump function by
90 * subtracting the height input. This avoids redundant computations when the height input is
91 * also needed by regular nodes as part in the main function (See #103903 for context).
92 * A better option would be to add a "value" input socket (in this case the height) to the
93 * differentiate node, but currently this kind of intermediate nodes are pruned in the
94 * code generation process (see #104265), so we need to fix that first. */
95 GPUNodeLink *dheight = GPU_differentiate_float_function(height_function, filter_width);
96
97 float invert = (node->custom1) ? -1.0 : 1.0;
98
99 return GPU_stack_link(mat, node, "node_bump", in, out, dheight, GPU_constant(&invert));
100}
101
103#ifdef WITH_MATERIALX
104{
105 NodeItem height = get_input_link("Height", NodeItem::Type::Float);
106 NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
107
108 if (!height) {
109 if (!normal) {
110 return create_node(
111 "normal", NodeItem::Type::Vector3, {{"space", val(std::string("world"))}});
112 }
113 return normal;
114 }
115
116 NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
117 NodeItem distance = get_input_value("Distance", NodeItem::Type::Float);
118 NodeItem height_normal = create_node(
119 "heighttonormal", NodeItem::Type::Vector3, {{"in", height}, {"scale", strength}});
120
121 return create_node("normalmap",
122 NodeItem::Type::Vector3,
123 {{"in", height_normal},
124 {"scale", node_->custom1 ? distance * val(-1.0f) : distance},
125 {"normal", normal}});
126}
127#endif
129
130} // namespace blender::nodes::node_shader_bump_cc
131
132/* node type definition */
134{
135 namespace file_ns = blender::nodes::node_shader_bump_cc;
136
137 static blender::bke::bNodeType ntype;
138
139 sh_node_type_base(&ntype, "ShaderNodeBump", SH_NODE_BUMP);
140 ntype.ui_name = "Bump";
141 ntype.ui_description =
142 "Generate a perturbed normal from a height texture for bump mapping. Typically used for "
143 "faking highly detailed surfaces";
144 ntype.enum_name_legacy = "BUMP";
146 ntype.declare = file_ns::node_declare;
147 ntype.draw_buttons = file_ns::node_shader_buts_bump;
148 ntype.gpu_fn = file_ns::gpu_shader_bump;
149 ntype.materialx_fn = file_ns::node_shader_materialx;
150
152}
#define NODE_CLASS_OP_VECTOR
Definition BKE_node.hh:450
#define SH_NODE_BUMP
#define BLT_I18NCONTEXT_AMOUNT
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
@ GPU_FLOAT
char * GPU_material_split_sub_function(GPUMaterial *material, GPUType return_type, GPUNodeLink **link)
GPUNodeLink * GPU_differentiate_float_function(const char *function_name, const float filter_width)
bool GPU_link(GPUMaterial *mat, const char *name,...)
@ PROP_PIXEL
Definition RNA_types.hh:248
@ PROP_FACTOR
Definition RNA_types.hh:251
@ UI_ITEM_R_SPLIT_EMPTY_NAME
#define in
#define out
float distance(VecOp< float, D >, VecOp< float, D >) RET
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
static int gpu_shader_bump(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_buts_bump(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
#define SOCK_NORMAL_ID
#define SOCK_HEIGHT_ID
#define SOCK_FILTER_WIDTH_ID
void register_node_type_sh_bump()
void sh_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
#define min(a, b)
Definition sort.cc:36
int16_t custom1
Defines a node type.
Definition BKE_node.hh:238
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:344
std::string ui_description
Definition BKE_node.hh:244
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:342
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
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)
PointerRNA * ptr
Definition wm_files.cc:4238