Blender V5.0
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_constants.h"
11#include "BLI_math_vector.hh"
12
13#include "NOD_multi_function.hh"
14
16#include "UI_resources.hh"
17
19
21{
22 b.is_function_node();
23 b.add_input<decl::Vector>("Vector").hide_value().implicit_field(
25 b.add_output<decl::Color>("Color").no_muted_links();
26 b.add_output<decl::Float>("Factor", "Fac").no_muted_links();
27}
28
30{
31 layout->prop(ptr, "gradient_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
32}
33
43
45 bNode *node,
46 bNodeExecData * /*execdata*/,
49{
50 node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
52
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
58class GradientFunction : public mf::MultiFunction {
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 = []() {
66 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(
89 [&](const int64_t i) { fac[i] = math::clamp(vector[i].x, 0.0f, 1.0f); });
90 break;
91 }
93 mask.foreach_index([&](const int64_t i) {
94 const float r = std::max(vector[i].x, 0.0f);
95 fac[i] = math::clamp(r * r, 0.0f, 1.0f);
96 });
97 break;
98 }
99 case SHD_BLEND_EASING: {
100 mask.foreach_index([&](const int64_t i) {
101 const float r = std::min(std::max(vector[i].x, 0.0f), 1.0f);
102 const float t = r * r;
103 fac[i] = (3.0f * t - 2.0f * t * r);
104 });
105 break;
106 }
107 case SHD_BLEND_DIAGONAL: {
108 mask.foreach_index([&](const int64_t i) {
109 fac[i] = (vector[i].x + vector[i].y) * 0.5f;
110 fac[i] = math::clamp(fac[i], 0.0f, 1.0f);
111 });
112 break;
113 }
114 case SHD_BLEND_RADIAL: {
115 mask.foreach_index([&](const int64_t i) {
116 fac[i] = atan2f(vector[i].y, vector[i].x) / (M_PI * 2.0f) + 0.5f;
117 });
118 break;
119 }
121 mask.foreach_index([&](const int64_t i) {
122 /* Bias a little bit for the case where input is a unit length vector,
123 * to get exactly zero instead of a small random value depending
124 * on float precision. */
125 const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
126 fac[i] = r * r;
127 });
128 break;
129 }
130 case SHD_BLEND_SPHERICAL: {
131 mask.foreach_index([&](const int64_t i) {
132 /* Bias a little bit for the case where input is a unit length vector,
133 * to get exactly zero instead of a small random value depending
134 * on float precision. */
135 fac[i] = std::max(0.999999f - math::length(vector[i]), 0.0f);
136 });
137 break;
138 }
139 }
140 if (compute_color) {
141 mask.foreach_index(
142 [&](const int64_t i) { r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f); });
143 }
144 }
145};
146
153
155#ifdef WITH_MATERIALX
156{
157 NodeTexGradient *tex = (NodeTexGradient *)node_->storage;
158 const int gradient_type = tex->gradient_type;
159 NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
160 if (!vector) {
161 vector = texcoord_node();
162 }
163 NodeItem res = empty();
164
165 switch (gradient_type) {
166 case SHD_BLEND_LINEAR:
167 res = vector[0];
168 break;
170 res = vector[0];
171 res = res * res;
172 break;
173 case SHD_BLEND_EASING:
174 res = vector[0].clamp();
175 res = res * res * (val(3.0f) - val(2.0f) * res);
176 break;
178 res = (vector[0] + vector[1]) * val(0.5f);
179 break;
180 case SHD_BLEND_RADIAL:
181 res = vector[1].atan2(vector[0]) / val(float(M_PI * 2.0f)) + val(0.5f);
182 break;
184 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
185 res = res * res;
186 break;
188 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
189 break;
190 default:
192 }
193 return res;
194}
195#endif
197
198} // namespace blender::nodes::node_shader_tex_gradient_cc
199
201{
203
204 static blender::bke::bNodeType ntype;
205
206 common_node_type_base(&ntype, "ShaderNodeTexGradient", SH_NODE_TEX_GRADIENT);
207 ntype.ui_name = "Gradient Texture";
208 ntype.ui_description =
209 "Generate interpolated color and intensity values based on the input vector";
210 ntype.enum_name_legacy = "TEX_GRADIENT";
212 ntype.declare = file_ns::sh_node_tex_gradient_declare;
213 ntype.draw_buttons = file_ns::node_shader_buts_tex_gradient;
214 ntype.initfunc = file_ns::node_shader_init_tex_gradient;
216 ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage);
217 ntype.gpu_fn = file_ns::node_shader_gpu_tex_gradient;
218 ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function;
219 ntype.materialx_fn = file_ns::node_shader_materialx;
220
222}
#define NODE_CLASS_TEXTURE
Definition BKE_node.hh:457
#define SH_NODE_TEX_GRADIENT
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition texture.cc:234
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition texture.cc:337
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define M_PI
@ NODE_DEFAULT_INPUT_POSITION_FIELD
@ 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)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
long long int int64_t
void set_signature(const Signature *signature)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
#define in
#define out
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
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))
Definition node.cc:5414
T clamp(const T &a, const T &min, const T &max)
T length(const VecBase< T, Size > &a)
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
VecBase< float, 3 > float3
#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 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)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define atan2f
TexMapping tex_mapping
ColorMapping color_mapping
void * storage
Defines a node type.
Definition BKE_node.hh:238
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:344
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:342
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:351
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
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)
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4238