Blender  V3.3
node_shader_tex_brick.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_math_vec_types.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")).min(-10000.0f).max(10000.0f).implicit_field();
17  b.add_input<decl::Color>(N_("Color1")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
18  b.add_input<decl::Color>(N_("Color2")).default_value({0.2f, 0.2f, 0.2f, 1.0f});
19  b.add_input<decl::Color>(N_("Mortar")).default_value({0.0f, 0.0f, 0.0f, 1.0f}).no_muted_links();
20  b.add_input<decl::Float>(N_("Scale"))
21  .min(-1000.0f)
22  .max(1000.0f)
23  .default_value(5.0f)
24  .no_muted_links();
25  b.add_input<decl::Float>(N_("Mortar Size"))
26  .min(0.0f)
27  .max(0.125f)
28  .default_value(0.02f)
29  .no_muted_links();
30  b.add_input<decl::Float>(N_("Mortar Smooth")).min(0.0f).max(1.0f).no_muted_links();
31  b.add_input<decl::Float>(N_("Bias")).min(-1.0f).max(1.0f).no_muted_links();
32  b.add_input<decl::Float>(N_("Brick Width"))
33  .min(0.01f)
34  .max(100.0f)
35  .default_value(0.5f)
36  .no_muted_links();
37  b.add_input<decl::Float>(N_("Row Height"))
38  .min(0.01f)
39  .max(100.0f)
40  .default_value(0.25f)
41  .no_muted_links();
42  b.add_output<decl::Color>(N_("Color"));
43  b.add_output<decl::Float>(N_("Fac"));
44 }
45 
47 {
48  uiLayout *col;
49 
50  col = uiLayoutColumn(layout, true);
51  uiItemR(col,
52  ptr,
53  "offset",
55  IFACE_("Offset"),
56  ICON_NONE);
57  uiItemR(
58  col, ptr, "offset_frequency", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Frequency"), ICON_NONE);
59 
60  col = uiLayoutColumn(layout, true);
61  uiItemR(col, ptr, "squash", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Squash"), ICON_NONE);
62  uiItemR(
63  col, ptr, "squash_frequency", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Frequency"), ICON_NONE);
64 }
65 
67 {
68  NodeTexBrick *tex = MEM_cnew<NodeTexBrick>(__func__);
70  BKE_texture_colormapping_default(&tex->base.color_mapping);
71 
72  tex->offset = 0.5f;
73  tex->squash = 1.0f;
74  tex->offset_freq = 2;
75  tex->squash_freq = 2;
76 
77  node->storage = tex;
78 
79  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
80  if (STREQ(sock->name, "Mortar Smooth")) {
81  ((bNodeSocketValueFloat *)sock->default_value)->value = 0.1f;
82  }
83  }
84 }
85 
87  bNode *node,
88  bNodeExecData *UNUSED(execdata),
89  GPUNodeStack *in,
91 {
92  node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
94  NodeTexBrick *tex = (NodeTexBrick *)node->storage;
95  float offset_freq = tex->offset_freq;
96  float squash_freq = tex->squash_freq;
97  return GPU_stack_link(mat,
98  node,
99  "node_tex_brick",
100  in,
101  out,
103  GPU_constant(&offset_freq),
104  GPU_uniform(&tex->squash),
105  GPU_constant(&squash_freq));
106 }
107 
109  private:
110  const float offset_;
111  const int offset_freq_;
112  const float squash_;
113  const int squash_freq_;
114 
115  public:
116  BrickFunction(const float offset,
117  const int offset_freq,
118  const float squash,
119  const int squash_freq)
120  : offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq)
121  {
123  this->set_signature(&signature);
124  }
125 
127  {
128  fn::MFSignatureBuilder signature{"BrickTexture"};
129  signature.single_input<float3>("Vector");
130  signature.single_input<ColorGeometry4f>("Color1");
131  signature.single_input<ColorGeometry4f>("Color2");
132  signature.single_input<ColorGeometry4f>("Mortar");
133  signature.single_input<float>("Scale");
134  signature.single_input<float>("Mortar Size");
135  signature.single_input<float>("Mortar Smooth");
136  signature.single_input<float>("Bias");
137  signature.single_input<float>("Brick Width");
138  signature.single_input<float>("Row Height");
139  signature.single_output<ColorGeometry4f>("Color");
140  signature.single_output<float>("Fac");
141  return signature.build();
142  }
143 
144  /* Fast integer noise. */
145  static float brick_noise(uint n)
146  {
147  n = (n + 1013) & 0x7fffffff;
148  n = (n >> 13) ^ n;
149  const uint nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
150  return 0.5f * ((float)nn / 1073741824.0f);
151  }
152 
153  static float smoothstepf(const float f)
154  {
155  const float ff = f * f;
156  return (3.0f * ff - 2.0f * ff * f);
157  }
158 
159  static float2 brick(float3 p,
160  float mortar_size,
161  float mortar_smooth,
162  float bias,
163  float brick_width,
164  float row_height,
165  float offset_amount,
166  int offset_frequency,
167  float squash_amount,
168  int squash_frequency)
169  {
170  float offset = 0.0f;
171 
172  const int rownum = (int)floorf(p.y / row_height);
173 
174  if (offset_frequency && squash_frequency) {
175  brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount;
176  offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount);
177  }
178 
179  const int bricknum = (int)floorf((p.x + offset) / brick_width);
180 
181  const float x = (p.x + offset) - brick_width * bricknum;
182  const float y = p.y - row_height * rownum;
183 
184  const float tint = clamp_f(
185  brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias, 0.0f, 1.0f);
186  float min_dist = std::min(std::min(x, y), std::min(brick_width - x, row_height - y));
187 
188  float mortar;
189  if (min_dist >= mortar_size) {
190  mortar = 0.0f;
191  }
192  else if (mortar_smooth == 0.0f) {
193  mortar = 1.0f;
194  }
195  else {
196  min_dist = 1.0f - min_dist / mortar_size;
197  mortar = (min_dist < mortar_smooth) ? smoothstepf(min_dist / mortar_smooth) : 1.0f;
198  }
199 
200  return float2(tint, mortar);
201  }
202 
204  {
205  const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
206  const VArray<ColorGeometry4f> &color1_values = params.readonly_single_input<ColorGeometry4f>(
207  1, "Color1");
208  const VArray<ColorGeometry4f> &color2_values = params.readonly_single_input<ColorGeometry4f>(
209  2, "Color2");
210  const VArray<ColorGeometry4f> &mortar_values = params.readonly_single_input<ColorGeometry4f>(
211  3, "Mortar");
212  const VArray<float> &scale = params.readonly_single_input<float>(4, "Scale");
213  const VArray<float> &mortar_size = params.readonly_single_input<float>(5, "Mortar Size");
214  const VArray<float> &mortar_smooth = params.readonly_single_input<float>(6, "Mortar Smooth");
215  const VArray<float> &bias = params.readonly_single_input<float>(7, "Bias");
216  const VArray<float> &brick_width = params.readonly_single_input<float>(8, "Brick Width");
217  const VArray<float> &row_height = params.readonly_single_input<float>(9, "Row Height");
218 
220  params.uninitialized_single_output_if_required<ColorGeometry4f>(10, "Color");
221  MutableSpan<float> r_fac = params.uninitialized_single_output_if_required<float>(11, "Fac");
222 
223  const bool store_fac = !r_fac.is_empty();
224  const bool store_color = !r_color.is_empty();
225 
226  for (int64_t i : mask) {
227  const float2 f2 = brick(vector[i] * scale[i],
228  mortar_size[i],
229  mortar_smooth[i],
230  bias[i],
231  brick_width[i],
232  row_height[i],
233  offset_,
234  offset_freq_,
235  squash_,
236  squash_freq_);
237 
238  float4 color_data, color1, color2, mortar;
239  copy_v4_v4(color_data, color1_values[i]);
240  copy_v4_v4(color1, color1_values[i]);
241  copy_v4_v4(color2, color2_values[i]);
242  copy_v4_v4(mortar, mortar_values[i]);
243  const float tint = f2.x;
244  const float f = f2.y;
245 
246  if (f != 1.0f) {
247  const float facm = 1.0f - tint;
248  color_data = color1 * facm + color2 * tint;
249  }
250 
251  if (store_color) {
252  color_data = color_data * (1.0f - f) + mortar * f;
253  copy_v4_v4(r_color[i], color_data);
254  }
255  if (store_fac) {
256  r_fac[i] = f;
257  }
258  }
259  }
260 };
261 
263 {
264  bNode &node = builder.node();
265  NodeTexBrick *tex = (NodeTexBrick *)node.storage;
266 
268  tex->offset, tex->offset_freq, tex->squash, tex->squash_freq);
269 }
270 
271 } // namespace blender::nodes::node_shader_tex_brick_cc
272 
274 {
275  namespace file_ns = blender::nodes::node_shader_tex_brick_cc;
276 
277  static bNodeType ntype;
278 
279  sh_fn_node_type_base(&ntype, SH_NODE_TEX_BRICK, "Brick Texture", NODE_CLASS_TEXTURE);
285  &ntype, "NodeTexBrick", node_free_standard_storage, node_copy_standard_storage);
288 
289  nodeRegisterType(&ntype);
290 }
typedef float(TangentPoint)[2]
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 LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v4_v4(float r[4], const float a[4])
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define STREQ(a, b)
#define IFACE_(msgid)
#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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
GPUNodeLink * GPU_constant(const float *num)
GPUNodeLink * GPU_uniform(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 Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells SH_NODE_TEX_BRICK
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
@ UI_ITEM_R_SLIDER
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
BrickFunction(const float offset, const int offset_freq, const float squash, const int squash_freq)
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
static float2 brick(float3 p, float mortar_size, float mortar_smooth, float bias, float brick_width, float row_height, float offset_amount, int offset_frequency, float squash_amount, int squash_frequency)
OperationNode * node
bNodeTree * ntree
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define floorf(x)
Definition: metal/compat.h:224
static int node_shader_gpu_tex_brick(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void sh_node_brick_build_multi_function(NodeMultiFunctionBuilder &builder)
static void sh_node_tex_brick_declare(NodeDeclarationBuilder &b)
vec_base< float, 2 > float2
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_sh_tex_brick()
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
#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