27 "Overall texture scale");
32 .description(
"Amount of distortion of the wave");
34 "Amount of distortion noise detail");
39 .description(
"Scale of distortion noise");
45 .description(
"Blend between a smoother noise pattern, and rougher with sharper peaks");
51 "Position of the wave along the Bands Direction.\n"
52 "This can be used as an input for more control over the distortion");
54 b.add_output<
decl::Float>(
"Factor",
"Fac").no_muted_links();
112 int bands_direction_;
113 int rings_direction_;
117 WaveFunction(
int wave_type,
int bands_direction,
int rings_direction,
int wave_profile)
118 : wave_type_(wave_type),
119 bands_direction_(bands_direction),
120 rings_direction_(rings_direction),
121 wave_profile_(wave_profile)
123 static const mf::Signature
signature = []() {
125 mf::SignatureBuilder builder{
"MagicFunction",
signature};
126 builder.single_input<
float3>(
"Vector");
127 builder.single_input<
float>(
"Scale");
128 builder.single_input<
float>(
"Distortion");
129 builder.single_input<
float>(
"Detail");
130 builder.single_input<
float>(
"Detail Scale");
131 builder.single_input<
float>(
"Detail Roughness");
132 builder.single_input<
float>(
"Phase Offset");
133 builder.single_output<
ColorGeometry4f>(
"Color", mf::ParamFlag::SupportsUnusedOutput);
134 builder.single_output<
float>(
"Fac");
147 const VArray<float> &droughness =
params.readonly_single_input<
float>(5,
"Detail Roughness");
157 p = (p + 0.000001f) * 0.999999f;
162 switch (wave_type_) {
164 switch (bands_direction_) {
175 n = (p.x + p.y + p.z) * 10.0f;
181 switch (rings_direction_) {
183 rp *=
float3(0.0f, 1.0f, 1.0f);
186 rp *=
float3(1.0f, 0.0f, 1.0f);
189 rp *=
float3(1.0f, 1.0f, 0.0f);
201 if (distortion[
i] != 0.0f) {
208 switch (wave_profile_) {
224 if (!r_color.is_empty()) {
245 NodeItem scale = get_input_value(
"Scale", NodeItem::Type::Float);
246 NodeItem distortion = get_input_value(
"Distortion", NodeItem::Type::Float);
247 NodeItem
detail = get_input_default(
"Detail", NodeItem::Type::Float);
248 NodeItem detail_scale = get_input_value(
"Detail Scale", NodeItem::Type::Float);
249 NodeItem detail_rough = get_input_value(
"Detail Roughness", NodeItem::Type::Float);
250 NodeItem phase_offset = get_input_value(
"Phase Offset", NodeItem::Type::Float);
251 NodeItem
vector = get_input_link(
"Vector", NodeItem::Type::Vector3);
253 vector = texcoord_node(NodeItem::Type::Vector3);
257 distortion = distortion * val(10.0f);
258 detail_scale = detail_scale * val(10.0f);
261 NodeItem fractal = create_node(
"fractal3d",
262 NodeItem::Type::Float,
264 {
"octaves", val(
int(detail.value->asA<
float>()))},
265 {
"lacunarity", val(2.0f)}});
266 NodeItem value = val(0.0f);
267 switch (tex->wave_type) {
269 switch (tex->bands_direction) {
271 value =
pos[0] * val(20.0f);
274 value =
pos[1] * val(20.0f);
277 value =
pos[2] * val(20.0f);
280 value = (
pos[0] +
pos[1] +
pos[2]) * val(10.0f);
288 switch (tex->rings_direction) {
290 rpos =
pos * val(MaterialX::Vector3(0.0f, 1.0f, 1.0f));
293 rpos =
pos * val(MaterialX::Vector3(1.0f, 0.0f, 1.0f));
296 rpos =
pos * val(MaterialX::Vector3(1.0f, 1.0f, 0.0f));
304 value = rpos.length() * val(20.0f);
307 value = value + phase_offset + distortion * detail_scale * fractal;
309 NodeItem res = empty();
310 switch (tex->wave_profile) {
312 res = val(0.5f) + val(0.5f) * (value - val(
float(
M_PI_2))).
sin();
315 value = value / val(
float(
M_PI * 2.0f));
316 res = value - value.floor();
319 value = value / val(
float(
M_PI * 2.0f));
320 res = (value - (value + val(0.5f)).floor()).abs() * val(2.0f);
339 ntype.
ui_name =
"Wave Texture";
340 ntype.
ui_description =
"Generate procedural bands or rings with noise";
343 ntype.
declare = file_ns::sh_node_tex_wave_declare;
344 ntype.
draw_buttons = file_ns::node_shader_buts_tex_wave;
346 ntype.
initfunc = file_ns::node_shader_init_tex_wave;
349 ntype.
gpu_fn = file_ns::node_shader_gpu_tex_wave;
constexpr int NODE_DEFAULT_MAX_WIDTH
#define NODE_CLASS_TEXTURE
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
#define BLI_assert_unreachable()
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
@ NODE_DEFAULT_INPUT_POSITION_FIELD
@ SHD_WAVE_BANDS_DIRECTION_Y
@ SHD_WAVE_BANDS_DIRECTION_X
@ SHD_WAVE_BANDS_DIRECTION_Z
@ SHD_WAVE_BANDS_DIRECTION_DIAGONAL
@ SHD_WAVE_RINGS_DIRECTION_Z
@ SHD_WAVE_RINGS_DIRECTION_Y
@ SHD_WAVE_RINGS_DIRECTION_X
@ SHD_WAVE_RINGS_DIRECTION_SPHERICAL
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(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)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
WaveFunction(int wave_type, int bands_direction, int rings_direction, int wave_profile)
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_wave_tex_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_init_tex_wave(bNodeTree *, bNode *node)
static void node_shader_buts_tex_wave(uiLayout *layout, bContext *, PointerRNA *ptr)
static void sh_node_tex_wave_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_tex_wave(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
template float perlin_fbm< float3 >(float3 p, const float detail, const float roughness, const float lacunarity, const bool normalize)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_tex_wave()
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)
int RNA_enum_get(PointerRNA *ptr, const char *name)
ColorMapping color_mapping
NodeMaterialXFunction materialx_fn
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
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)