Blender V4.3
node_shader_tex_gradient.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Foundation. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "node_shader_util.hh"
6#include "node_util.hh"
7
8#include "BKE_texture.h"
9
10#include "BLI_math_vector.hh"
11
13
14#include "NOD_multi_function.hh"
15
16#include "UI_interface.hh"
17#include "UI_resources.hh"
18
20
22{
23 b.is_function_node();
24 b.add_input<decl::Vector>("Vector").hide_value().implicit_field(implicit_field_inputs::position);
25 b.add_output<decl::Color>("Color").no_muted_links();
26 b.add_output<decl::Float>("Fac").no_muted_links();
27}
28
30{
31 uiItemR(layout, ptr, "gradient_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
32}
33
34static void node_shader_init_tex_gradient(bNodeTree * /*ntree*/, bNode *node)
35{
36 NodeTexGradient *tex = MEM_cnew<NodeTexGradient>(__func__);
38 BKE_texture_colormapping_default(&tex->base.color_mapping);
39 tex->gradient_type = SHD_BLEND_LINEAR;
40
41 node->storage = tex;
42}
43
45 bNode *node,
46 bNodeExecData * /*execdata*/,
47 GPUNodeStack *in,
48 GPUNodeStack *out)
49{
50 node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
51 node_shader_gpu_tex_mapping(mat, node, in, out);
52
53 NodeTexGradient *tex = (NodeTexGradient *)node->storage;
54 float gradient_type = tex->gradient_type;
55 return GPU_stack_link(mat, node, "node_tex_gradient", in, out, GPU_constant(&gradient_type));
56}
57
59 private:
60 int gradient_type_;
61
62 public:
63 GradientFunction(int gradient_type) : gradient_type_(gradient_type)
64 {
65 static const mf::Signature signature = []() {
67 mf::SignatureBuilder builder{"GradientFunction", signature};
68 builder.single_input<float3>("Vector");
69 builder.single_output<ColorGeometry4f>("Color", mf::ParamFlag::SupportsUnusedOutput);
70 builder.single_output<float>("Fac");
71 return signature;
72 }();
73 this->set_signature(&signature);
74 }
75
76 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
77 {
78 const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
79
81 params.uninitialized_single_output_if_required<ColorGeometry4f>(1, "Color");
82 MutableSpan<float> fac = params.uninitialized_single_output<float>(2, "Fac");
83
84 const bool compute_color = !r_color.is_empty();
85
86 switch (gradient_type_) {
87 case SHD_BLEND_LINEAR: {
88 mask.foreach_index([&](const int64_t i) { fac[i] = vector[i].x; });
89 break;
90 }
92 mask.foreach_index([&](const int64_t i) {
93 const float r = std::max(vector[i].x, 0.0f);
94 fac[i] = r * r;
95 });
96 break;
97 }
98 case SHD_BLEND_EASING: {
99 mask.foreach_index([&](const int64_t i) {
100 const float r = std::min(std::max(vector[i].x, 0.0f), 1.0f);
101 const float t = r * r;
102 fac[i] = (3.0f * t - 2.0f * t * r);
103 });
104 break;
105 }
106 case SHD_BLEND_DIAGONAL: {
107 mask.foreach_index([&](const int64_t i) { fac[i] = (vector[i].x + vector[i].y) * 0.5f; });
108 break;
109 }
110 case SHD_BLEND_RADIAL: {
111 mask.foreach_index([&](const int64_t i) {
112 fac[i] = atan2f(vector[i].y, vector[i].x) / (M_PI * 2.0f) + 0.5f;
113 });
114 break;
115 }
117 mask.foreach_index([&](const int64_t i) {
118 /* Bias a little bit for the case where input is a unit length vector,
119 * to get exactly zero instead of a small random value depending
120 * on float precision. */
121 const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
122 fac[i] = r * r;
123 });
124 break;
125 }
126 case SHD_BLEND_SPHERICAL: {
127 mask.foreach_index([&](const int64_t i) {
128 /* Bias a little bit for the case where input is a unit length vector,
129 * to get exactly zero instead of a small random value depending
130 * on float precision. */
131 fac[i] = std::max(0.999999f - math::length(vector[i]), 0.0f);
132 });
133 break;
134 }
135 }
136 if (compute_color) {
137 mask.foreach_index(
138 [&](const int64_t i) { r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f); });
139 }
140 }
141};
142
144{
145 const bNode &node = builder.node();
146 NodeTexGradient *tex = (NodeTexGradient *)node.storage;
147 builder.construct_and_set_matching_fn<GradientFunction>(tex->gradient_type);
148}
149
151#ifdef WITH_MATERIALX
152{
153 NodeTexGradient *tex = (NodeTexGradient *)node_->storage;
154 const int gradient_type = tex->gradient_type;
155 NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
156 if (!vector) {
157 vector = texcoord_node();
158 }
159 NodeItem res = empty();
160
161 switch (gradient_type) {
162 case SHD_BLEND_LINEAR:
163 res = vector[0];
164 break;
166 res = vector[0];
167 res = res * res;
168 break;
169 case SHD_BLEND_EASING:
170 res = vector[0].clamp();
171 res = res * res * (val(3.0f) - val(2.0f) * res);
172 break;
174 res = (vector[0] + vector[1]) * val(0.5f);
175 break;
176 case SHD_BLEND_RADIAL:
177 res = vector[1].atan2(vector[0]) / val(float(M_PI * 2.0f)) + val(0.5f);
178 break;
180 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
181 res = res * res;
182 break;
184 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
185 break;
186 default:
188 }
189 return res;
190}
191#endif
193
194} // namespace blender::nodes::node_shader_tex_gradient_cc
195
197{
199
200 static blender::bke::bNodeType ntype;
201
203 ntype.declare = file_ns::sh_node_tex_gradient_declare;
204 ntype.draw_buttons = file_ns::node_shader_buts_tex_gradient;
205 ntype.initfunc = file_ns::node_shader_init_tex_gradient;
207 &ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage);
208 ntype.gpu_fn = file_ns::node_shader_gpu_tex_gradient;
209 ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function;
210 ntype.materialx_fn = file_ns::node_shader_materialx;
211
213}
#define SH_NODE_TEX_GRADIENT
Definition BKE_node.hh:932
#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
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define M_PI
@ SHD_BLEND_DIAGONAL
@ SHD_BLEND_EASING
@ SHD_BLEND_LINEAR
@ SHD_BLEND_RADIAL
@ SHD_BLEND_QUADRATIC_SPHERE
@ SHD_BLEND_SPHERICAL
@ SHD_BLEND_QUADRATIC
@ 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)
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)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
local_group_size(16, 16) .push_constant(Type b
#define atan2f(x, y)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
T length(const VecBase< T, Size > &a)
void position(const bNode &, void *r_value)
static void node_shader_init_tex_gradient(bNodeTree *, bNode *node)
static void sh_node_tex_gradient_declare(NodeDeclarationBuilder &b)
static int node_shader_gpu_tex_gradient(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *, PointerRNA *ptr)
static void sh_node_gradient_tex_build_multi_function(NodeMultiFunctionBuilder &builder)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition BLI_color.hh:337
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_tex_gradient()
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
Defines a node type.
Definition BKE_node.hh:218
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:320
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
float max
PointerRNA * ptr
Definition wm_files.cc:4126