Blender  V3.3
node_shader_tex_wave.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
4 #include "node_shader_util.hh"
5 
6 #include "BLI_noise.hh"
7 
8 #include "UI_interface.h"
9 #include "UI_resources.h"
10 
12 
14 {
15  b.is_function_node();
16  b.add_input<decl::Vector>(N_("Vector")).implicit_field();
17  b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
18  b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(0.0f);
19  b.add_input<decl::Float>(N_("Detail")).min(0.0f).max(15.0f).default_value(2.0f);
20  b.add_input<decl::Float>(N_("Detail Scale")).min(-1000.0f).max(1000.0f).default_value(1.0f);
21  b.add_input<decl::Float>(N_("Detail Roughness"))
22  .min(0.0f)
23  .max(1.0f)
24  .default_value(0.5f)
25  .subtype(PROP_FACTOR);
26  b.add_input<decl::Float>(N_("Phase Offset")).min(-1000.0f).max(1000.0f).default_value(0.0f);
27  b.add_output<decl::Color>(N_("Color")).no_muted_links();
28  b.add_output<decl::Float>(N_("Fac")).no_muted_links();
29 }
30 
32 {
33  uiItemR(layout, ptr, "wave_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
34  int type = RNA_enum_get(ptr, "wave_type");
35  if (type == SHD_WAVE_BANDS) {
36  uiItemR(layout, ptr, "bands_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
37  }
38  else { /* SHD_WAVE_RINGS */
39  uiItemR(layout, ptr, "rings_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
40  }
41 
42  uiItemR(layout, ptr, "wave_profile", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
43 }
44 
46 {
47  NodeTexWave *tex = MEM_cnew<NodeTexWave>(__func__);
49  BKE_texture_colormapping_default(&tex->base.color_mapping);
50  tex->wave_type = SHD_WAVE_BANDS;
51  tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_X;
52  tex->rings_direction = SHD_WAVE_RINGS_DIRECTION_X;
53  tex->wave_profile = SHD_WAVE_PROFILE_SIN;
54  node->storage = tex;
55 }
56 
58  bNode *node,
59  bNodeExecData *UNUSED(execdata),
60  GPUNodeStack *in,
62 {
63  node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
65 
66  NodeTexWave *tex = (NodeTexWave *)node->storage;
67  float wave_type = tex->wave_type;
68  float bands_direction = tex->bands_direction;
69  float rings_direction = tex->rings_direction;
70  float wave_profile = tex->wave_profile;
71 
72  return GPU_stack_link(mat,
73  node,
74  "node_tex_wave",
75  in,
76  out,
77  GPU_constant(&wave_type),
78  GPU_constant(&bands_direction),
79  GPU_constant(&rings_direction),
80  GPU_constant(&wave_profile));
81 }
82 
84  private:
85  int wave_type_;
86  int bands_direction_;
87  int rings_direction_;
88  int wave_profile_;
89 
90  public:
91  WaveFunction(int wave_type, int bands_direction, int rings_direction, int wave_profile)
92  : wave_type_(wave_type),
93  bands_direction_(bands_direction),
94  rings_direction_(rings_direction),
95  wave_profile_(wave_profile)
96  {
98  this->set_signature(&signature);
99  }
100 
102  {
103  fn::MFSignatureBuilder signature{"MagicFunction"};
104  signature.single_input<float3>("Vector");
105  signature.single_input<float>("Scale");
106  signature.single_input<float>("Distortion");
107  signature.single_input<float>("Detail");
108  signature.single_input<float>("Detail Scale");
109  signature.single_input<float>("Detail Roughness");
110  signature.single_input<float>("Phase Offset");
111  signature.single_output<ColorGeometry4f>("Color");
112  signature.single_output<float>("Fac");
113  return signature.build();
114  }
115 
117  {
118  const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
119  const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
120  const VArray<float> &distortion = params.readonly_single_input<float>(2, "Distortion");
121  const VArray<float> &detail = params.readonly_single_input<float>(3, "Detail");
122  const VArray<float> &dscale = params.readonly_single_input<float>(4, "Detail Scale");
123  const VArray<float> &droughness = params.readonly_single_input<float>(5, "Detail Roughness");
124  const VArray<float> &phase = params.readonly_single_input<float>(6, "Phase Offset");
125 
127  params.uninitialized_single_output_if_required<ColorGeometry4f>(7, "Color");
128  MutableSpan<float> r_fac = params.uninitialized_single_output<float>(8, "Fac");
129 
130  for (int64_t i : mask) {
131 
132  float3 p = vector[i] * scale[i];
133  /* Prevent precision issues on unit coordinates. */
134  p = (p + 0.000001f) * 0.999999f;
135 
136  float n = 0.0f;
137  float val = 0.0f;
138 
139  switch (wave_type_) {
140  case SHD_WAVE_BANDS:
141  switch (bands_direction_) {
143  n = p.x * 20.0f;
144  break;
146  n = p.y * 20.0f;
147  break;
149  n = p.z * 20.0f;
150  break;
152  n = (p.x + p.y + p.z) * 10.0f;
153  break;
154  }
155  break;
156  case SHD_WAVE_RINGS:
157  float3 rp = p;
158  switch (rings_direction_) {
160  rp *= float3(0.0f, 1.0f, 1.0f);
161  break;
163  rp *= float3(1.0f, 0.0f, 1.0f);
164  break;
166  rp *= float3(1.0f, 1.0f, 0.0f);
167  break;
169  /* Ignore. */
170  break;
171  }
172  n = len_v3(rp) * 20.0f;
173  break;
174  }
175 
176  n += phase[i];
177 
178  if (distortion[i] != 0.0f) {
179  n += distortion[i] *
180  (noise::perlin_fractal(p * dscale[i], detail[i], droughness[i]) * 2.0f - 1.0f);
181  }
182 
183  switch (wave_profile_) {
185  val = 0.5f + 0.5f * sinf(n - M_PI_2);
186  break;
188  n /= M_PI * 2.0f;
189  val = n - floorf(n);
190  break;
192  n /= M_PI * 2.0f;
193  val = fabsf(n - floorf(n + 0.5f)) * 2.0f;
194  break;
195  }
196 
197  r_fac[i] = val;
198  }
199  if (!r_color.is_empty()) {
200  for (int64_t i : mask) {
201  r_color[i] = ColorGeometry4f(r_fac[i], r_fac[i], r_fac[i], 1.0f);
202  }
203  }
204  }
205 };
206 
208 {
209  bNode &node = builder.node();
210  NodeTexWave *tex = (NodeTexWave *)node.storage;
212  tex->wave_type, tex->bands_direction, tex->rings_direction, tex->wave_profile);
213 }
214 
215 } // namespace blender::nodes::node_shader_tex_wave_cc
216 
218 {
219  namespace file_ns = blender::nodes::node_shader_tex_wave_cc;
220 
221  static bNodeType ntype;
222 
223  sh_fn_node_type_base(&ntype, SH_NODE_TEX_WAVE, "Wave Texture", NODE_CLASS_TEXTURE);
231 
232  nodeRegisterType(&ntype);
233 }
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
Definition: node.cc:4408
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:355
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
@ NODE_SIZE_MIDDLE
Definition: BKE_node.h:366
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition: texture.c:238
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition: texture.c:340
#define M_PI_2
Definition: BLI_math_base.h:23
#define M_PI
Definition: BLI_math_base.h:20
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
@ SHD_WAVE_PROFILE_SIN
@ SHD_WAVE_PROFILE_TRI
@ SHD_WAVE_PROFILE_SAW
@ SHD_WAVE_BANDS_DIRECTION_Y
@ SHD_WAVE_BANDS_DIRECTION_X
@ SHD_WAVE_BANDS_DIRECTION_Z
@ SHD_WAVE_BANDS_DIRECTION_DIAGONAL
#define SHD_WAVE_RINGS
#define SHD_WAVE_BANDS
@ SHD_WAVE_RINGS_DIRECTION_Z
@ SHD_WAVE_RINGS_DIRECTION_Y
@ SHD_WAVE_RINGS_DIRECTION_X
@ SHD_WAVE_RINGS_DIRECTION_SPHERICAL
#define TEXMAP_TYPE_POINT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
GPUNodeLink * GPU_constant(const float *num)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise SH_NODE_TEX_WAVE
@ PROP_FACTOR
Definition: RNA_types.h:144
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void set_signature(const MFSignature *signature)
const MFSignature & signature() const
WaveFunction(int wave_type, int bands_direction, int rings_direction, int wave_profile)
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
#define sinf(x)
Definition: cuda/compat.h:102
OperationNode * node
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define floorf(x)
Definition: metal/compat.h:224
#define fabsf(x)
Definition: metal/compat.h:219
static void sh_node_wave_tex_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static int node_shader_gpu_tex_wave(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void sh_node_tex_wave_declare(NodeDeclarationBuilder &b)
static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
float perlin_fractal(float position, float octaves, float roughness)
Definition: noise.cc:560
vec_base< float, 3 > float3
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition: BLI_color.hh:346
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_sh_tex_wave()
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out))
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
#define min(a, b)
Definition: sort.c:35
__int64 int64_t
Definition: stdint.h:89
Defines a node type.
Definition: BKE_node.h:226
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeMultiFunctionBuildFunction build_multi_function
Definition: BKE_node.h:313
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480