Blender V5.0
node_shader_normal_map.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
5#include "DNA_node_types.h"
6#include "node_shader_util.hh"
7#include "node_util.hh"
8
9#include "BKE_context.hh"
10#include "BKE_node_runtime.hh"
11
13
14#include "RNA_access.hh"
15
17#include "UI_resources.hh"
18
20
22{
23 b.add_input<decl::Float>("Strength")
24 .default_value(1.0f)
25 .min(0.0f)
26 .max(10.0f)
27 .description("Strength of the normal mapping effect")
28 .translation_context(BLT_I18NCONTEXT_AMOUNT);
29 b.add_input<decl::Color>("Color")
30 .default_value({0.5f, 0.5f, 1.0f, 1.0f})
31 .description("Color that encodes the normal map in the specified space");
32 b.add_output<decl::Vector>("Normal");
33}
34
36{
37 layout->prop(ptr, "space", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
38
39 if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) {
40 PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
41 Object *object = static_cast<Object *>(obptr.data);
42
43 if (object && object->type == OB_MESH) {
45
46 if (depsgraph) {
47 Object *object_eval = DEG_get_evaluated(depsgraph, object);
48 PointerRNA dataptr = RNA_id_pointer_create(static_cast<ID *>(object_eval->data));
49 layout->prop_search(ptr, "uv_map", &dataptr, "uv_layers", "", ICON_GROUP_UVS);
50 return;
51 }
52 }
53
54 layout->prop(ptr, "uv_map", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
55 }
56}
57
58static void node_shader_init_normal_map(bNodeTree * /*ntree*/, bNode *node)
59{
60 NodeShaderNormalMap *attr = MEM_callocN<NodeShaderNormalMap>("NodeShaderNormalMap");
61 node->storage = attr;
62}
63
65 bNode *node,
66 bNodeExecData * /*execdata*/,
69{
70 NodeShaderNormalMap *nm = static_cast<NodeShaderNormalMap *>(node->storage);
71
72 GPUNodeLink *strength;
73 if (in[0].link) {
74 strength = in[0].link;
75 }
76 else if (node->runtime->original) {
77 bNodeSocket *socket = static_cast<bNodeSocket *>(
78 BLI_findlink(&node->runtime->original->inputs, 0));
79 bNodeSocketValueFloat *socket_data = static_cast<bNodeSocketValueFloat *>(
80 socket->default_value);
81 strength = GPU_uniform(&socket_data->value);
82 }
83 else {
84 strength = GPU_constant(in[0].vec);
85 }
86
87 GPUNodeLink *newnormal;
88 if (in[1].link) {
89 newnormal = in[1].link;
90 }
91 else if (node->runtime->original) {
92 bNodeSocket *socket = static_cast<bNodeSocket *>(
93 BLI_findlink(&node->runtime->original->inputs, 1));
94 bNodeSocketValueRGBA *socket_data = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
95 newnormal = GPU_uniform(socket_data->value);
96 }
97 else {
98 newnormal = GPU_constant(in[1].vec);
99 }
100
101 const char *color_to_normal_fnc_name = "color_to_normal_new_shading";
103 color_to_normal_fnc_name = "color_to_blender_normal_new_shading";
104 }
105
106 GPU_link(mat, color_to_normal_fnc_name, newnormal, &newnormal);
107 switch (nm->space) {
110 /* We return directly from the node_normal_map as strength
111 * has already been applied for the tangent case */
112 GPU_link(mat,
113 "node_normal_map",
115 strength,
116 newnormal,
117 &out[0].link);
118 return true;
119 case SHD_SPACE_OBJECT:
121 GPU_link(mat, "normal_transform_object_to_world", newnormal, &newnormal);
122 break;
123 case SHD_SPACE_WORLD:
125 /* Nothing to do. */
126 break;
127 }
128
129 /* Final step - mix and apply strength for all other than tangent space. */
130 GPU_link(mat, "node_normal_map_mix", strength, newnormal, &out[0].link);
131
132 return true;
133}
134
136#ifdef WITH_MATERIALX
137{
138 NodeShaderNormalMap *normal_map_node = static_cast<NodeShaderNormalMap *>(node_->storage);
139 NodeItem color = get_input_value("Color", NodeItem::Type::Vector3);
140 NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
141
142# if MATERIALX_MAJOR_VERSION <= 1 && MATERIALX_MINOR_VERSION <= 38
143 std::string space;
144 switch (normal_map_node->space) {
146 space = "tangent";
147 break;
148 case SHD_SPACE_OBJECT:
150 space = "object";
151 break;
152 case SHD_SPACE_WORLD:
154 /* World isn't supported, tangent space will be used */
155 space = "tangent";
156 break;
157 default:
159 }
160
161 return create_node("normalmap",
162 NodeItem::Type::Vector3,
163 {{"in", color}, {"scale", strength}, {"space", val(space)}});
164# else
165 if (normal_map_node->space == SHD_SPACE_TANGENT) {
166 return create_node("normalmap", NodeItem::Type::Vector3, {{"in", color}, {"scale", strength}});
167 }
168
169 /* Object space not supported yet. Despite the 1.38 implementation accepting
170 * object space argument, that seems to work either. */
171 NodeItem tangent = val(MaterialX::Vector3(1.0f, 0.0f, 0.0f));
172 NodeItem bitangent = val(MaterialX::Vector3(0.0f, 1.0f, 0.0f));
173 NodeItem normal = val(MaterialX::Vector3(0.0f, 0.0f, 1.0f));
174
175 return create_node("normalmap",
176 NodeItem::Type::Vector3,
177 {{"in", color},
178 {"scale", strength},
179 {"tangent", tangent},
180 {"bitangent", bitangent},
181 {"normal", normal}});
182# endif
183}
184#endif
186
187} // namespace blender::nodes::node_shader_normal_map_cc
188
189/* node type definition */
191{
193
194 static blender::bke::bNodeType ntype;
195
196 sh_node_type_base(&ntype, "ShaderNodeNormalMap", SH_NODE_NORMAL_MAP);
197 ntype.ui_name = "Normal Map";
198 ntype.ui_description =
199 "Generate a perturbed normal from an RGB normal map image. Typically used for faking highly "
200 "detailed surfaces";
201 ntype.enum_name_legacy = "NORMAL_MAP";
203 ntype.declare = file_ns::node_declare;
204 ntype.draw_buttons = file_ns::node_shader_buts_normal_map;
206 ntype.initfunc = file_ns::node_shader_init_normal_map;
208 ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage);
209 ntype.gpu_fn = file_ns::gpu_shader_normal_map;
210 ntype.materialx_fn = file_ns::node_shader_materialx;
211
213}
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
#define NODE_CLASS_OP_VECTOR
Definition BKE_node.hh:450
#define SH_NODE_NORMAL_MAP
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define ELEM(...)
#define BLT_I18NCONTEXT_AMOUNT
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ SHD_SPACE_BLENDER_OBJECT
@ SHD_SPACE_OBJECT
@ SHD_SPACE_TANGENT
@ SHD_SPACE_WORLD
@ SHD_SPACE_BLENDER_WORLD
@ OB_MESH
GPUNodeLink * GPU_constant(const float *num)
@ GPU_MATFLAG_OBJECT_INFO
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUNodeLink * GPU_uniform(const float *num)
#define C
Definition RandGen.cpp:29
@ UI_ITEM_R_SPLIT_EMPTY_NAME
BPy_StructRNA * depsgraph
#define in
#define out
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
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))
Definition node.cc:5414
void node_type_size_preset(bNodeType &ntype, eNodeSizePreset size)
Definition node.cc:5396
static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_init_normal_map(bNodeTree *, bNode *node)
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_normal_map()
void sh_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
Definition DNA_ID.h:414
void * data
Definition RNA_types.hh:53
void * default_value
bNodeRuntimeHandle * runtime
void * storage
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
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
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_search(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop, PropertyRNA *item_searchpropname, std::optional< blender::StringRefNull > name, int icon, bool results_are_suggestions)
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