25 b.add_input<
decl::Vector>(
"Vector").
min(-10000.0f).max(10000.0f).implicit_field(
28 .default_value({0.8f, 0.8f, 0.8f, 1.0f})
29 .description(
"Color of the first reference brick");
31 .default_value({0.2f, 0.2f, 0.2f, 1.0f})
32 .description(
"Color of the second reference brick");
34 .default_value({0.0f, 0.0f, 0.0f, 1.0f})
42 .description(
"Scale of the texture");
49 "Size of the filling between the bricks (known as \"mortar\"). "
57 "Blurs/softens the edge between the mortar and the bricks. "
58 "This can be useful with a texture and displacement textures");
60 "The color variation between Color1 and Color2. "
61 "Values of -1 and 1 only use one of the two colors. "
62 "Values in between mix the colors");
68 .description(
"Ratio of brick's width relative to the texture scale");
74 .description(
"Ratio of brick's row height relative to the texture scale");
132 const int offset_freq_;
134 const int squash_freq_;
138 const int offset_freq,
140 const int squash_freq)
141 : offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq)
143 static const mf::Signature
signature = []() {
145 mf::SignatureBuilder builder{
"BrickTexture",
signature};
146 builder.single_input<
float3>(
"Vector");
150 builder.single_input<
float>(
"Scale");
151 builder.single_input<
float>(
"Mortar Size");
152 builder.single_input<
float>(
"Mortar Smooth");
153 builder.single_input<
float>(
"Bias");
154 builder.single_input<
float>(
"Brick Width");
155 builder.single_input<
float>(
"Row Height");
156 builder.single_output<
ColorGeometry4f>(
"Color", mf::ParamFlag::SupportsUnusedOutput);
157 builder.single_output<
float>(
"Fac", mf::ParamFlag::SupportsUnusedOutput);
166 n = (n + 1013) & 0x7fffffff;
168 const uint nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
169 return 0.5f * (
float(nn) / 1073741824.0f);
174 const float ff = f * f;
175 return (3.0f * ff - 2.0f * ff * f);
185 int offset_frequency,
187 int squash_frequency)
191 const int rownum = int(
floorf(p.y / row_height));
193 if (offset_frequency && squash_frequency) {
194 brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount;
195 offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount);
198 const int bricknum = int(
floorf((p.x + offset) / brick_width));
200 const float x = (p.x + offset) - brick_width * bricknum;
201 const float y = p.y - row_height * rownum;
204 brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias, 0.0f, 1.0f);
205 float min_dist = std::min({
x,
y, brick_width -
x, row_height -
y});
208 if (min_dist >= mortar_size) {
211 else if (mortar_smooth == 0.0f) {
215 min_dist = 1.0f - min_dist / mortar_size;
216 mortar = (min_dist < mortar_smooth) ?
smoothstepf(min_dist / mortar_smooth) : 1.0f;
219 return float2(tint, mortar);
233 const VArray<float> &mortar_smooth =
params.readonly_single_input<
float>(6,
"Mortar Smooth");
242 const bool store_fac = !r_fac.is_empty();
243 const bool store_color = !r_color.is_empty();
257 float4 color_data, color1, color2, mortar;
262 const float tint = f2.x;
263 const float f = f2.y;
266 const float facm = 1.0f - tint;
267 color_data = color1 * facm + color2 * tint;
271 color_data = color_data * (1.0f - f) + mortar * f;
299 ntype.
ui_name =
"Brick Texture";
300 ntype.
ui_description =
"Generate a procedural texture producing bricks";
303 ntype.
declare = file_ns::sh_node_tex_brick_declare;
304 ntype.
draw_buttons = file_ns::node_shader_buts_tex_brick;
306 ntype.
initfunc = file_ns::node_shader_init_tex_brick;
309 ntype.
gpu_fn = file_ns::node_shader_gpu_tex_brick;
constexpr int NODE_DEFAULT_MAX_WIDTH
#define NODE_CLASS_TEXTURE
#define SH_NODE_TEX_BRICK
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v4_v4(float r[4], const float a[4])
@ NODE_DEFAULT_INPUT_POSITION_FIELD
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
GPUNodeLink * GPU_uniform(const float *num)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
const Signature & signature() const
void set_signature(const Signature *signature)
void construct_and_set_matching_fn(Args &&...args)
static float brick_noise(uint n)
BrickFunction(const float offset, const int offset_freq, const float squash, const int squash_freq)
static float smoothstepf(const float f)
void call(const IndexMask &mask, mf::Params params, mf::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)
void * MEM_callocN(size_t len, const char *str)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_type_size(bNodeType &ntype, int width, int minwidth, int maxwidth)
void node_register_type(bNodeType &ntype)
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))
void node_type_size_preset(bNodeType &ntype, eNodeSizePreset size)
static void sh_node_brick_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_buts_tex_brick(uiLayout *layout, bContext *, PointerRNA *ptr)
static void sh_node_tex_brick_declare(NodeDeclarationBuilder &b)
static void node_shader_init_tex_brick(bNodeTree *, bNode *node)
static int node_shader_gpu_tex_brick(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
VecBase< float, 4 > float4
VecBase< float, 2 > float2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
void register_node_type_sh_tex_brick()
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)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
ColorMapping color_mapping
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGPUExecFunction gpu_fn
NodeMultiFunctionBuildFunction build_multi_function
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
uiLayout & column(bool align)