Blender V5.0
node_shader_tex_gabor.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_numbers.hh"
6#include "BLI_noise.hh"
7
8#include "BKE_texture.h"
9
10#include "node_shader_util.hh"
11#include "node_util.hh"
12
13#include "NOD_multi_function.hh"
14
16#include "UI_resources.hh"
17
19
21
23{
24 b.is_function_node();
25 b.add_input<decl::Vector>("Vector")
27 .description(
28 "The coordinates at which Gabor noise will be evaluated. The Z component is ignored in "
29 "the 2D case");
30 b.add_input<decl::Float>("Scale").default_value(5.0f).description(
31 "The scale of the Gabor noise");
32 b.add_input<decl::Float>("Frequency")
33 .default_value(2.0f)
34 .min(0.0f)
35 .description(
36 "The rate at which the Gabor noise changes across space. This is different from the "
37 "Scale input in that it only scales perpendicular to the Gabor noise direction");
38 b.add_input<decl::Float>("Anisotropy")
39 .default_value(1.0f)
40 .min(0.0f)
41 .max(1.0f)
42 .subtype(PROP_FACTOR)
43 .description(
44 "The directionality of Gabor noise. 1 means the noise is completely directional, while "
45 "0 means the noise is omnidirectional");
46 b.add_input<decl::Float>("Orientation", "Orientation 2D")
48 .subtype(PROP_ANGLE)
49 .description("The direction of the anisotropic Gabor noise");
50 b.add_input<decl::Vector>("Orientation", "Orientation 3D")
52 .subtype(PROP_DIRECTION)
53 .description("The direction of the anisotropic Gabor noise");
54 b.add_output<decl::Float>("Value").description(
55 "The Gabor noise value with both random intensity and phase. This is equal to sine the "
56 "phase multiplied by the intensity");
57 b.add_output<decl::Float>("Phase").description(
58 "The phase of the Gabor noise, which has no random intensity");
59 b.add_output<decl::Float>("Intensity")
60 .description("The intensity of the Gabor noise, which has no random phase");
61}
62
64{
65 layout->prop(ptr, "gabor_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
66}
67
68static void node_shader_init_tex_gabor(bNodeTree * /*ntree*/, bNode *node)
69{
70 NodeTexGabor *storage = MEM_callocN<NodeTexGabor>(__func__);
73
74 storage->type = SHD_GABOR_TYPE_2D;
75
76 node->storage = storage;
77}
78
80{
81 const NodeTexGabor &storage = node_storage(*node);
82
83 bNodeSocket *orientation_2d_socket = bke::node_find_socket(*node, SOCK_IN, "Orientation 2D");
85 *ntree, *orientation_2d_socket, storage.type == SHD_GABOR_TYPE_2D);
86
87 bNodeSocket *orientation_3d_socket = bke::node_find_socket(*node, SOCK_IN, "Orientation 3D");
89 *ntree, *orientation_3d_socket, storage.type == SHD_GABOR_TYPE_3D);
90}
91
93 bNode *node,
94 bNodeExecData * /*execdata*/,
97{
98 node_shader_gpu_default_tex_coord(material, node, &in[0].link);
99 node_shader_gpu_tex_mapping(material, node, in, out);
100
101 const float type = float(node_storage(*node).type);
102 return GPU_stack_link(material, node, "node_tex_gabor", in, out, GPU_constant(&type));
103}
104
105class GaborNoiseFunction : public mf::MultiFunction {
106 private:
107 NodeGaborType type_;
108
109 public:
110 GaborNoiseFunction(const NodeGaborType type) : type_(type)
111 {
112 static std::array<mf::Signature, 2> signatures{
115 };
116 this->set_signature(&signatures[type]);
117 }
118
119 static mf::Signature create_signature(const NodeGaborType type)
120 {
121 mf::Signature signature;
122 mf::SignatureBuilder builder{"GaborNoise", signature};
123
124 builder.single_input<float3>("Vector");
125 builder.single_input<float>("Scale");
126 builder.single_input<float>("Frequency");
127 builder.single_input<float>("Anisotropy");
128
129 if (type == SHD_GABOR_TYPE_2D) {
130 builder.single_input<float>("Orientation");
131 }
132 else {
133 builder.single_input<float3>("Orientation");
134 }
135
136 builder.single_output<float>("Value", mf::ParamFlag::SupportsUnusedOutput);
137 builder.single_output<float>("Phase", mf::ParamFlag::SupportsUnusedOutput);
138 builder.single_output<float>("Intensity", mf::ParamFlag::SupportsUnusedOutput);
139
140 return signature;
141 }
142
143 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
144 {
145 const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
146 const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
147 const VArray<float> &frequency = params.readonly_single_input<float>(2, "Frequency");
148 const VArray<float> &anisotropy = params.readonly_single_input<float>(3, "Anisotropy");
149 /* A parameter index of 4 is reserved for Orientation input below. */
150 MutableSpan<float> r_value = params.uninitialized_single_output_if_required<float>(5, "Value");
151 MutableSpan<float> r_phase = params.uninitialized_single_output_if_required<float>(6, "Phase");
152 MutableSpan<float> r_intensity = params.uninitialized_single_output_if_required<float>(
153 7, "Intensity");
154
155 switch (type_) {
156 case SHD_GABOR_TYPE_2D: {
157 const VArray<float> &orientation = params.readonly_single_input<float>(4, "Orientation");
158 mask.foreach_index([&](const int64_t i) {
160 scale[i],
161 frequency[i],
162 anisotropy[i],
163 orientation[i],
164 r_value.is_empty() ? nullptr : &r_value[i],
165 r_phase.is_empty() ? nullptr : &r_phase[i],
166 r_intensity.is_empty() ? nullptr : &r_intensity[i]);
167 });
168 break;
169 }
170 case SHD_GABOR_TYPE_3D: {
171 const VArray<float3> &orientation = params.readonly_single_input<float3>(4, "Orientation");
172 mask.foreach_index([&](const int64_t i) {
174 scale[i],
175 frequency[i],
176 anisotropy[i],
177 orientation[i],
178 r_value.is_empty() ? nullptr : &r_value[i],
179 r_phase.is_empty() ? nullptr : &r_phase[i],
180 r_intensity.is_empty() ? nullptr : &r_intensity[i]);
181 });
182 break;
183 }
184 }
185 }
186
188 {
189 ExecutionHints hints;
190 hints.allocates_array = false;
191 hints.min_grain_size = 100;
192 return hints;
193 }
194};
195
197{
198 const NodeTexGabor &storage = node_storage(builder.node());
200}
201
202} // namespace blender::nodes::node_shader_tex_gabor_cc
203
205{
207
208 static blender::bke::bNodeType ntype;
209
210 common_node_type_base(&ntype, "ShaderNodeTexGabor", SH_NODE_TEX_GABOR);
211 ntype.ui_name = "Gabor Texture";
212 ntype.ui_description = "Generate Gabor noise";
213 ntype.enum_name_legacy = "TEX_GABOR";
215 ntype.declare = file_ns::sh_node_tex_gabor_declare;
216 ntype.draw_buttons = file_ns::node_shader_buts_tex_gabor;
217 ntype.initfunc = file_ns::node_shader_init_tex_gabor;
218 node_type_storage(ntype, "NodeTexGabor", node_free_standard_storage, node_copy_standard_storage);
219 ntype.gpu_fn = file_ns::node_shader_gpu_tex_gabor;
220 ntype.updatefunc = file_ns::node_shader_update_tex_gabor;
221 ntype.build_multi_function = file_ns::build_multi_function;
222
223 node_register_type(ntype);
224}
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define NODE_CLASS_TEXTURE
Definition BKE_node.hh:457
#define SH_NODE_TEX_GABOR
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition texture.cc:234
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition texture.cc:337
@ NODE_DEFAULT_INPUT_POSITION_FIELD
NodeGaborType
@ SHD_GABOR_TYPE_3D
@ SHD_GABOR_TYPE_2D
@ SOCK_IN
@ TEXMAP_TYPE_POINT
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
@ PROP_DIRECTION
Definition RNA_types.hh:262
@ PROP_ANGLE
Definition RNA_types.hh:252
@ PROP_FACTOR
Definition RNA_types.hh:251
@ UI_ITEM_R_SPLIT_EMPTY_NAME
long long int int64_t
void set_signature(const Signature *signature)
static mf::Signature create_signature(const NodeGaborType type)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
nullptr float
#define in
#define out
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2532
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
Definition node.cc:4739
static void build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_init_tex_gabor(bNodeTree *, bNode *node)
static void node_shader_buts_tex_gabor(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_shader_update_tex_gabor(bNodeTree *ntree, bNode *node)
static void sh_node_tex_gabor_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_tex_gabor(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
void gabor(const float2 coordinates, const float scale, const float frequency, const float anisotropy, const float orientation, float *r_value, float *r_phase, float *r_intensity)
Definition noise.cc:2505
VecBase< float, 3 > float3
void register_node_type_sh_tex_gabor()
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *)
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
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)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define min(a, b)
Definition sort.cc:36
TexMapping tex_mapping
ColorMapping color_mapping
NodeTexBase base
void * storage
Defines a node type.
Definition BKE_node.hh:238
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
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:351
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(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:281
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)
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
int xy[2]
Definition wm_draw.cc:178
PointerRNA * ptr
Definition wm_files.cc:4238