Blender V4.5
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
12#include "NOD_multi_function.hh"
13
14#include "UI_interface.hh"
15#include "UI_resources.hh"
16
18
20{
21 b.is_function_node();
22 b.add_input<decl::Vector>("Vector").hide_value().implicit_field(
24 b.add_output<decl::Color>("Color").no_muted_links();
25 b.add_output<decl::Float>("Fac").no_muted_links();
26}
27
29{
30 layout->prop(ptr, "gradient_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
31}
32
42
44 bNode *node,
45 bNodeExecData * /*execdata*/,
48{
49 node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
51
53 float gradient_type = tex->gradient_type;
54 return GPU_stack_link(mat, node, "node_tex_gradient", in, out, GPU_constant(&gradient_type));
55}
56
57class GradientFunction : public mf::MultiFunction {
58 private:
59 int gradient_type_;
60
61 public:
62 GradientFunction(int gradient_type) : gradient_type_(gradient_type)
63 {
64 static const mf::Signature signature = []() {
65 mf::Signature signature;
66 mf::SignatureBuilder builder{"GradientFunction", signature};
67 builder.single_input<float3>("Vector");
68 builder.single_output<ColorGeometry4f>("Color", mf::ParamFlag::SupportsUnusedOutput);
69 builder.single_output<float>("Fac");
70 return signature;
71 }();
72 this->set_signature(&signature);
73 }
74
75 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
76 {
77 const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
78
80 params.uninitialized_single_output_if_required<ColorGeometry4f>(1, "Color");
81 MutableSpan<float> fac = params.uninitialized_single_output<float>(2, "Fac");
82
83 const bool compute_color = !r_color.is_empty();
84
85 switch (gradient_type_) {
86 case SHD_BLEND_LINEAR: {
87 mask.foreach_index([&](const int64_t i) { fac[i] = vector[i].x; });
88 break;
89 }
91 mask.foreach_index([&](const int64_t i) {
92 const float r = std::max(vector[i].x, 0.0f);
93 fac[i] = r * r;
94 });
95 break;
96 }
97 case SHD_BLEND_EASING: {
98 mask.foreach_index([&](const int64_t i) {
99 const float r = std::min(std::max(vector[i].x, 0.0f), 1.0f);
100 const float t = r * r;
101 fac[i] = (3.0f * t - 2.0f * t * r);
102 });
103 break;
104 }
105 case SHD_BLEND_DIAGONAL: {
106 mask.foreach_index([&](const int64_t i) { fac[i] = (vector[i].x + vector[i].y) * 0.5f; });
107 break;
108 }
109 case SHD_BLEND_RADIAL: {
110 mask.foreach_index([&](const int64_t i) {
111 fac[i] = atan2f(vector[i].y, vector[i].x) / (M_PI * 2.0f) + 0.5f;
112 });
113 break;
114 }
116 mask.foreach_index([&](const int64_t i) {
117 /* Bias a little bit for the case where input is a unit length vector,
118 * to get exactly zero instead of a small random value depending
119 * on float precision. */
120 const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
121 fac[i] = r * r;
122 });
123 break;
124 }
125 case SHD_BLEND_SPHERICAL: {
126 mask.foreach_index([&](const int64_t i) {
127 /* Bias a little bit for the case where input is a unit length vector,
128 * to get exactly zero instead of a small random value depending
129 * on float precision. */
130 fac[i] = std::max(0.999999f - math::length(vector[i]), 0.0f);
131 });
132 break;
133 }
134 }
135 if (compute_color) {
136 mask.foreach_index(
137 [&](const int64_t i) { r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f); });
138 }
139 }
140};
141
148
150#ifdef WITH_MATERIALX
151{
152 NodeTexGradient *tex = (NodeTexGradient *)node_->storage;
153 const int gradient_type = tex->gradient_type;
154 NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
155 if (!vector) {
156 vector = texcoord_node();
157 }
158 NodeItem res = empty();
159
160 switch (gradient_type) {
161 case SHD_BLEND_LINEAR:
162 res = vector[0];
163 break;
165 res = vector[0];
166 res = res * res;
167 break;
168 case SHD_BLEND_EASING:
169 res = vector[0].clamp();
170 res = res * res * (val(3.0f) - val(2.0f) * res);
171 break;
173 res = (vector[0] + vector[1]) * val(0.5f);
174 break;
175 case SHD_BLEND_RADIAL:
176 res = vector[1].atan2(vector[0]) / val(float(M_PI * 2.0f)) + val(0.5f);
177 break;
179 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
180 res = res * res;
181 break;
183 res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f));
184 break;
185 default:
187 }
188 return res;
189}
190#endif
192
193} // namespace blender::nodes::node_shader_tex_gradient_cc
194
196{
198
199 static blender::bke::bNodeType ntype;
200
201 common_node_type_base(&ntype, "ShaderNodeTexGradient", SH_NODE_TEX_GRADIENT);
202 ntype.ui_name = "Gradient Texture";
203 ntype.ui_description =
204 "Generate interpolated color and intensity values based on the input vector";
205 ntype.enum_name_legacy = "TEX_GRADIENT";
207 ntype.declare = file_ns::sh_node_tex_gradient_declare;
208 ntype.draw_buttons = file_ns::node_shader_buts_tex_gradient;
209 ntype.initfunc = file_ns::node_shader_init_tex_gradient;
211 ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage);
212 ntype.gpu_fn = file_ns::node_shader_gpu_tex_gradient;
213 ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function;
214 ntype.materialx_fn = file_ns::node_shader_materialx;
215
217}
#define NODE_CLASS_TEXTURE
Definition BKE_node.hh:443
#define SH_NODE_TEX_GRADIENT
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition texture.cc:238
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition texture.cc:341
#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 atan2f(x, y)
#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:2748
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:5603
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
Definition BLI_color.hh:342
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
TexMapping tex_mapping
ColorMapping color_mapping
void * storage
Defines a node type.
Definition BKE_node.hh:226
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:332
std::string ui_description
Definition BKE_node.hh:232
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:330
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:344
const char * enum_name_legacy
Definition BKE_node.hh:235
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:355
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:4226