Blender V4.3
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
15#include "UI_interface.hh"
16#include "UI_resources.hh"
17
19
21
23{
24 b.is_function_node();
25 b.add_input<decl::Vector>("Vector")
26 .implicit_field(implicit_field_inputs::position)
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)
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)
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")
47 .default_value(math::numbers::pi / 4)
49 .description("The direction of the anisotropic Gabor noise");
50 b.add_input<decl::Vector>("Orientation", "Orientation 3D")
51 .default_value({math::numbers::sqrt2, math::numbers::sqrt2, 0.0f})
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 uiItemR(layout, 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_cnew<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*/,
95 GPUNodeStack *in,
96 GPUNodeStack *out)
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
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
120 {
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>("Anistropy");
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> &anistropy = params.readonly_single_input<float>(3, "Anistropy");
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 anistropy[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 anistropy[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
211 ntype.declare = file_ns::sh_node_tex_gabor_declare;
212 ntype.draw_buttons = file_ns::node_shader_buts_tex_gabor;
213 ntype.initfunc = file_ns::node_shader_init_tex_gabor;
214 node_type_storage(
216 ntype.gpu_fn = file_ns::node_shader_gpu_tex_gabor;
217 ntype.updatefunc = file_ns::node_shader_update_tex_gabor;
218 ntype.build_multi_function = file_ns::build_multi_function;
219
220 node_register_type(&ntype);
221}
#define SH_NODE_TEX_GABOR
Definition BKE_node.hh:998
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
#define NODE_CLASS_TEXTURE
Definition BKE_node.hh:414
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition texture.cc:247
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition texture.cc:350
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:165
@ PROP_ANGLE
Definition RNA_types.hh:155
@ PROP_FACTOR
Definition RNA_types.hh:154
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
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
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_set_socket_availability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
Definition node.cc:3911
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:1829
void position(const bNode &, void *r_value)
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:2353
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 sh_fn_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:46
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:58
__int64 int64_t
Definition stdint.h:89
TexMapping tex_mapping
ColorMapping color_mapping
NodeTexBase base
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:318
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:336
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:257
int xy[2]
Definition wm_draw.cc:170
PointerRNA * ptr
Definition wm_files.cc:4126