Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/shader/nodes')
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c9
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_clamp.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.cc6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc397
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.cc25
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_mixRgb.cc)4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc (renamed from source/blender/nodes/shader/nodes/node_shader_valToRgb.cc)4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.c (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c)0
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc)4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc)4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.c (renamed from source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c)0
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc23
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.cc32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc98
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.c (renamed from source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c)0
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_value.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.cc40
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_transform.c (renamed from source/blender/nodes/shader/nodes/node_shader_vectTransform.c)0
29 files changed, 534 insertions, 157 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
index 89b7164693f..b9f4106c79a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -169,17 +169,16 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sock;
- int distribution = node->custom1;
- int sss_method = node->custom2;
+ const int distribution = node->custom1;
+ const int sss_method = node->custom2;
- for (sock = node->inputs.first; sock; sock = sock->next) {
+ for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
if (STREQ(sock->name, "Transmission Roughness")) {
nodeSetSocketAvailability(ntree, sock, distribution == SHD_GLOSSY_GGX);
}
if (STR_ELEM(sock->name, "Subsurface IOR", "Subsurface Anisotropy")) {
- nodeSetSocketAvailability(ntree, sock, sss_method == SHD_SUBSURFACE_BURLEY);
+ nodeSetSocketAvailability(ntree, sock, sss_method != SHD_SUBSURFACE_BURLEY);
}
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
index 57a992a4275..6c3457151e5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
@@ -75,7 +75,7 @@ static void sh_node_clamp_build_multi_function(blender::nodes::NodeMultiFunction
}
}
-void register_node_type_sh_clamp(void)
+void register_node_type_sh_clamp()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index a1dac05434e..190e0cfad4c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -232,7 +232,7 @@ void register_node_type_sh_group(void)
/* NOTE: cannot use #sh_node_type_base for node group, because it would map the node type
* to the shared #NODE_GROUP integer type id. */
- node_type_base_custom(&ntype, "ShaderNodeGroup", "Group", NODE_CLASS_GROUP, NODE_CONST_OUTPUT);
+ node_type_base_custom(&ntype, "ShaderNodeGroup", "Group", NODE_CLASS_GROUP, 0);
ntype.type = NODE_GROUP;
ntype.poll = sh_node_poll_default;
ntype.poll_instance = node_group_poll_instance;
@@ -243,7 +243,7 @@ void register_node_type_sh_group(void)
node_type_socket_templates(&ntype, NULL, NULL);
node_type_size(&ntype, 140, 60, 400);
- node_type_label(&ntype, node_group_label);
+ ntype.labelfunc = node_group_label;
node_type_group_update(&ntype, node_group_update);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
node_type_gpu(&ntype, gpu_group_execute);
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc
index 7ce5150bf85..09bbf3d851c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc
@@ -152,7 +152,7 @@ static void sh_node_curve_vec_build_multi_function(
builder.construct_and_set_matching_fn<CurveVecFunction>(*cumap);
}
-void register_node_type_sh_curve_vec(void)
+void register_node_type_sh_curve_vec()
{
static bNodeType ntype;
@@ -329,7 +329,7 @@ static void sh_node_curve_rgb_build_multi_function(
builder.construct_and_set_matching_fn<CurveRGBFunction>(*cumap);
}
-void register_node_type_sh_curve_rgb(void)
+void register_node_type_sh_curve_rgb()
{
static bNodeType ntype;
@@ -473,7 +473,7 @@ static void sh_node_curve_float_build_multi_function(
builder.construct_and_set_matching_fn<CurveFloatFunction>(*cumap);
}
-void register_node_type_sh_curve_float(void)
+void register_node_type_sh_curve_float()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
index e55963eb500..615ae276eb4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -21,10 +21,14 @@
* \ingroup shdnodes
*/
+#include <algorithm>
+
#include "node_shader_util.h"
#include "BLI_math_base_safe.h"
+NODE_STORAGE_FUNCS(NodeMapRange)
+
namespace blender::nodes {
static void sh_node_map_range_declare(NodeDeclarationBuilder &b)
@@ -36,34 +40,80 @@ static void sh_node_map_range_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("To Min")).min(-10000.0f).max(10000.0f);
b.add_input<decl::Float>(N_("To Max")).min(-10000.0f).max(10000.0f).default_value(1.0f);
b.add_input<decl::Float>(N_("Steps")).min(-10000.0f).max(10000.0f).default_value(4.0f);
+ b.add_input<decl::Vector>(N_("Vector")).min(0.0f).max(1.0f).hide_value();
+ b.add_input<decl::Vector>(N_("From Min"), "From_Min_FLOAT3");
+ b.add_input<decl::Vector>(N_("From Max"), "From_Max_FLOAT3").default_value(float3(1.0f));
+ b.add_input<decl::Vector>(N_("To Min"), "To_Min_FLOAT3");
+ b.add_input<decl::Vector>(N_("To Max"), "To_Max_FLOAT3").default_value(float3(1.0f));
+ b.add_input<decl::Vector>(N_("Steps"), "Steps_FLOAT3").default_value(float3(4.0f));
b.add_output<decl::Float>(N_("Result"));
+ b.add_output<decl::Vector>(N_("Vector"));
};
} // namespace blender::nodes
static void node_shader_update_map_range(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sockSteps = nodeFindSocket(node, SOCK_IN, "Steps");
- nodeSetSocketAvailability(ntree, sockSteps, node->custom2 == NODE_MAP_RANGE_STEPPED);
+ const NodeMapRange &storage = node_storage(*node);
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const int type = (data_type == CD_PROP_FLOAT) ? SOCK_FLOAT : SOCK_VECTOR;
+
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ nodeSetSocketAvailability(ntree, socket, socket->type == type);
+ }
+
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
+ nodeSetSocketAvailability(ntree, socket, socket->type == type);
+ }
+
+ if (storage.interpolation_type != NODE_MAP_RANGE_STEPPED) {
+ if (type == SOCK_FLOAT) {
+ bNodeSocket *sockSteps = (bNodeSocket *)BLI_findlink(&node->inputs, 5);
+ nodeSetSocketAvailability(ntree, sockSteps, false);
+ }
+ else {
+ bNodeSocket *sockSteps = (bNodeSocket *)BLI_findlink(&node->inputs, 11);
+ nodeSetSocketAvailability(ntree, sockSteps, false);
+ }
+ }
}
static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node)
{
+ NodeMapRange *data = (NodeMapRange *)MEM_callocN(sizeof(NodeMapRange), __func__);
+ data->clamp = 1;
+ data->data_type = CD_PROP_FLOAT;
+ data->interpolation_type = NODE_MAP_RANGE_LINEAR;
node->custom1 = true; /* use_clamp */
node->custom2 = NODE_MAP_RANGE_LINEAR; /* interpolation */
+ node->storage = data;
}
-static const char *gpu_shader_get_name(int mode)
+static const char *gpu_shader_get_name(int mode, bool use_vector)
{
- switch (mode) {
- case NODE_MAP_RANGE_LINEAR:
- return "map_range_linear";
- case NODE_MAP_RANGE_STEPPED:
- return "map_range_stepped";
- case NODE_MAP_RANGE_SMOOTHSTEP:
- return "map_range_smoothstep";
- case NODE_MAP_RANGE_SMOOTHERSTEP:
- return "map_range_smootherstep";
+ if (use_vector) {
+ switch (mode) {
+ case NODE_MAP_RANGE_LINEAR:
+ return "vector_map_range_linear";
+ case NODE_MAP_RANGE_STEPPED:
+ return "vector_map_range_stepped";
+ case NODE_MAP_RANGE_SMOOTHSTEP:
+ return "vector_map_range_smoothstep";
+ case NODE_MAP_RANGE_SMOOTHERSTEP:
+ return "vector_map_range_smootherstep";
+ }
+ }
+ else {
+ switch (mode) {
+ case NODE_MAP_RANGE_LINEAR:
+ return "map_range_linear";
+ case NODE_MAP_RANGE_STEPPED:
+ return "map_range_stepped";
+ case NODE_MAP_RANGE_SMOOTHSTEP:
+ return "map_range_smoothstep";
+ case NODE_MAP_RANGE_SMOOTHERSTEP:
+ return "map_range_smootherstep";
+ }
}
return nullptr;
@@ -75,22 +125,207 @@ static int gpu_shader_map_range(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- const char *name = gpu_shader_get_name(node->custom2);
-
+ const NodeMapRange &storage = node_storage(*node);
+ bool use_vector = (storage.data_type == CD_PROP_FLOAT3);
+ const char *name = gpu_shader_get_name(storage.interpolation_type, use_vector);
+ float clamp = storage.clamp ? 1.0f : 0.0f;
int ret = 0;
if (name != nullptr) {
- ret = GPU_stack_link(mat, node, name, in, out);
+ ret = GPU_stack_link(mat, node, name, in, out, GPU_constant(&clamp));
}
else {
- ret = GPU_stack_link(mat, node, "map_range_linear", in, out);
+ ret = GPU_stack_link(mat, node, "map_range_linear", in, out, GPU_constant(&clamp));
}
- if (ret && node->custom1 &&
- !ELEM(node->custom2, NODE_MAP_RANGE_SMOOTHSTEP, NODE_MAP_RANGE_SMOOTHERSTEP)) {
+ if (ret && storage.clamp && !use_vector &&
+ !ELEM(storage.interpolation_type, NODE_MAP_RANGE_SMOOTHSTEP, NODE_MAP_RANGE_SMOOTHERSTEP)) {
GPU_link(mat, "clamp_range", out[0].link, in[3].link, in[4].link, &out[0].link);
}
return ret;
}
+namespace blender::nodes {
+
+static inline float clamp_range(const float value, const float min, const float max)
+{
+ return (min > max) ? std::clamp(value, max, min) : std::clamp(value, min, max);
+}
+
+static float3 clamp_range(const float3 value, const float3 min, const float3 max)
+{
+ return float3(clamp_range(value.x, min.x, max.x),
+ clamp_range(value.y, min.y, max.y),
+ clamp_range(value.z, min.z, max.z));
+}
+
+static void map_range_vector_signature(blender::fn::MFSignatureBuilder *signature, bool use_steps)
+{
+ signature->single_input<float3>("Vector");
+ signature->single_input<float3>("From Min");
+ signature->single_input<float3>("From Max");
+ signature->single_input<float3>("To Min");
+ signature->single_input<float3>("To Max");
+ if (use_steps) {
+ signature->single_input<float3>("Steps");
+ }
+ signature->single_output<float3>("Vector");
+}
+
+class MapRangeVectorFunction : public blender::fn::MultiFunction {
+ private:
+ bool clamp_;
+
+ public:
+ MapRangeVectorFunction(bool clamp) : clamp_(clamp)
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Vector Map Range"};
+ map_range_vector_signature(&signature, false);
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float3> &values = params.readonly_single_input<float3>(0, "Vector");
+ const blender::VArray<float3> &from_min = params.readonly_single_input<float3>(1, "From Min");
+ const blender::VArray<float3> &from_max = params.readonly_single_input<float3>(2, "From Max");
+ const blender::VArray<float3> &to_min = params.readonly_single_input<float3>(3, "To Min");
+ const blender::VArray<float3> &to_max = params.readonly_single_input<float3>(4, "To Max");
+ blender::MutableSpan<float3> results = params.uninitialized_single_output<float3>(5, "Vector");
+
+ for (int64_t i : mask) {
+ float3 factor = float3::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ results[i] = factor * (to_max[i] - to_min[i]) + to_min[i];
+ }
+
+ if (clamp_) {
+ for (int64_t i : mask) {
+ results[i] = clamp_range(results[i], to_min[i], to_max[i]);
+ }
+ }
+ }
+};
+
+class MapRangeSteppedVectorFunction : public blender::fn::MultiFunction {
+ private:
+ bool clamp_;
+
+ public:
+ MapRangeSteppedVectorFunction(bool clamp) : clamp_(clamp)
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Vector Map Range Stepped"};
+ map_range_vector_signature(&signature, true);
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float3> &values = params.readonly_single_input<float3>(0, "Vector");
+ const blender::VArray<float3> &from_min = params.readonly_single_input<float3>(1, "From Min");
+ const blender::VArray<float3> &from_max = params.readonly_single_input<float3>(2, "From Max");
+ const blender::VArray<float3> &to_min = params.readonly_single_input<float3>(3, "To Min");
+ const blender::VArray<float3> &to_max = params.readonly_single_input<float3>(4, "To Max");
+ const blender::VArray<float3> &steps = params.readonly_single_input<float3>(5, "Steps");
+ blender::MutableSpan<float3> results = params.uninitialized_single_output<float3>(6, "Vector");
+
+ for (int64_t i : mask) {
+ float3 factor = float3::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ factor = float3::safe_divide(float3::floor(factor * (steps[i] + 1.0f)), steps[i]);
+ results[i] = factor * (to_max[i] - to_min[i]) + to_min[i];
+ }
+
+ if (clamp_) {
+ for (int64_t i : mask) {
+ results[i] = clamp_range(results[i], to_min[i], to_max[i]);
+ }
+ }
+ }
+};
+
+class MapRangeSmoothstepVectorFunction : public blender::fn::MultiFunction {
+ public:
+ MapRangeSmoothstepVectorFunction()
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Vector Map Range Smoothstep"};
+ map_range_vector_signature(&signature, false);
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float3> &values = params.readonly_single_input<float3>(0, "Vector");
+ const blender::VArray<float3> &from_min = params.readonly_single_input<float3>(1, "From Min");
+ const blender::VArray<float3> &from_max = params.readonly_single_input<float3>(2, "From Max");
+ const blender::VArray<float3> &to_min = params.readonly_single_input<float3>(3, "To Min");
+ const blender::VArray<float3> &to_max = params.readonly_single_input<float3>(4, "To Max");
+ blender::MutableSpan<float3> results = params.uninitialized_single_output<float3>(5, "Vector");
+
+ for (int64_t i : mask) {
+ float3 factor = float3::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ clamp_v3(factor, 0.0f, 1.0f);
+ factor = (float3(3.0f) - 2.0f * factor) * (factor * factor);
+ results[i] = factor * (to_max[i] - to_min[i]) + to_min[i];
+ }
+ }
+};
+
+class MapRangeSmootherstepVectorFunction : public blender::fn::MultiFunction {
+ public:
+ MapRangeSmootherstepVectorFunction()
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Vector Map Range Smoothstep"};
+ map_range_vector_signature(&signature, false);
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float3> &values = params.readonly_single_input<float3>(0, "Vector");
+ const blender::VArray<float3> &from_min = params.readonly_single_input<float3>(1, "From Min");
+ const blender::VArray<float3> &from_max = params.readonly_single_input<float3>(2, "From Max");
+ const blender::VArray<float3> &to_min = params.readonly_single_input<float3>(3, "To Min");
+ const blender::VArray<float3> &to_max = params.readonly_single_input<float3>(4, "To Max");
+ blender::MutableSpan<float3> results = params.uninitialized_single_output<float3>(5, "Vector");
+
+ for (int64_t i : mask) {
+ float3 factor = float3::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ clamp_v3(factor, 0.0f, 1.0f);
+ factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
+ results[i] = factor * (to_max[i] - to_min[i]) + to_min[i];
+ }
+ }
+};
+
static void map_range_signature(blender::fn::MFSignatureBuilder *signature, bool use_steps)
{
signature->single_input<float>("Value");
@@ -140,8 +375,7 @@ class MapRangeFunction : public blender::fn::MultiFunction {
if (clamp_) {
for (int64_t i : mask) {
- results[i] = (to_min[i] > to_max[i]) ? clamp_f(results[i], to_max[i], to_min[i]) :
- clamp_f(results[i], to_min[i], to_max[i]);
+ results[i] = clamp_range(results[i], to_min[i], to_max[i]);
}
}
}
@@ -185,8 +419,7 @@ class MapRangeSteppedFunction : public blender::fn::MultiFunction {
if (clamp_) {
for (int64_t i : mask) {
- results[i] = (to_min[i] > to_max[i]) ? clamp_f(results[i], to_max[i], to_min[i]) :
- clamp_f(results[i], to_min[i], to_max[i]);
+ results[i] = clamp_range(results[i], to_min[i], to_max[i]);
}
}
}
@@ -265,58 +498,104 @@ class MapRangeSmootherstepFunction : public blender::fn::MultiFunction {
static void sh_node_map_range_build_multi_function(
blender::nodes::NodeMultiFunctionBuilder &builder)
{
- bNode &bnode = builder.node();
- bool clamp = bnode.custom1 != 0;
- int interpolation_type = bnode.custom2;
-
- switch (interpolation_type) {
- case NODE_MAP_RANGE_LINEAR: {
- if (clamp) {
- static MapRangeFunction fn_with_clamp{true};
- builder.set_matching_fn(fn_with_clamp);
- }
- else {
- static MapRangeFunction fn_without_clamp{false};
- builder.set_matching_fn(fn_without_clamp);
+ const NodeMapRange &storage = node_storage(builder.node());
+ bool clamp = storage.clamp != 0;
+ int interpolation_type = storage.interpolation_type;
+
+ switch (storage.data_type) {
+ case CD_PROP_FLOAT3:
+ switch (interpolation_type) {
+ case NODE_MAP_RANGE_LINEAR: {
+ if (clamp) {
+ static MapRangeVectorFunction fn_with_clamp{true};
+ builder.set_matching_fn(fn_with_clamp);
+ }
+ else {
+ static MapRangeVectorFunction fn_without_clamp{false};
+ builder.set_matching_fn(fn_without_clamp);
+ }
+ break;
+ }
+ case NODE_MAP_RANGE_STEPPED: {
+ if (clamp) {
+ static MapRangeSteppedVectorFunction fn_stepped_with_clamp{true};
+ builder.set_matching_fn(fn_stepped_with_clamp);
+ }
+ else {
+ static MapRangeSteppedVectorFunction fn_stepped_without_clamp{false};
+ builder.set_matching_fn(fn_stepped_without_clamp);
+ }
+ break;
+ }
+ case NODE_MAP_RANGE_SMOOTHSTEP: {
+ static MapRangeSmoothstepVectorFunction smoothstep;
+ builder.set_matching_fn(smoothstep);
+ break;
+ }
+ case NODE_MAP_RANGE_SMOOTHERSTEP: {
+ static MapRangeSmootherstepVectorFunction smootherstep;
+ builder.set_matching_fn(smootherstep);
+ break;
+ }
+ default:
+ break;
}
break;
- }
- case NODE_MAP_RANGE_STEPPED: {
- if (clamp) {
- static MapRangeSteppedFunction fn_stepped_with_clamp{true};
- builder.set_matching_fn(fn_stepped_with_clamp);
- }
- else {
- static MapRangeSteppedFunction fn_stepped_without_clamp{false};
- builder.set_matching_fn(fn_stepped_without_clamp);
+ case CD_PROP_FLOAT:
+ switch (interpolation_type) {
+ case NODE_MAP_RANGE_LINEAR: {
+ if (clamp) {
+ static MapRangeFunction fn_with_clamp{true};
+ builder.set_matching_fn(fn_with_clamp);
+ }
+ else {
+ static MapRangeFunction fn_without_clamp{false};
+ builder.set_matching_fn(fn_without_clamp);
+ }
+ break;
+ }
+ case NODE_MAP_RANGE_STEPPED: {
+ if (clamp) {
+ static MapRangeSteppedFunction fn_stepped_with_clamp{true};
+ builder.set_matching_fn(fn_stepped_with_clamp);
+ }
+ else {
+ static MapRangeSteppedFunction fn_stepped_without_clamp{false};
+ builder.set_matching_fn(fn_stepped_without_clamp);
+ }
+ break;
+ }
+ case NODE_MAP_RANGE_SMOOTHSTEP: {
+ static MapRangeSmoothstepFunction smoothstep;
+ builder.set_matching_fn(smoothstep);
+ break;
+ }
+ case NODE_MAP_RANGE_SMOOTHERSTEP: {
+ static MapRangeSmootherstepFunction smootherstep;
+ builder.set_matching_fn(smootherstep);
+ break;
+ }
+ default:
+ break;
}
break;
- }
- case NODE_MAP_RANGE_SMOOTHSTEP: {
- static MapRangeSmoothstepFunction smoothstep;
- builder.set_matching_fn(smoothstep);
- break;
- }
- case NODE_MAP_RANGE_SMOOTHERSTEP: {
- static MapRangeSmootherstepFunction smootherstep;
- builder.set_matching_fn(smootherstep);
- break;
- }
- default:
- break;
}
}
-void register_node_type_sh_map_range(void)
+} // namespace blender::nodes
+
+void register_node_type_sh_map_range()
{
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_MAP_RANGE, "Map Range", NODE_CLASS_CONVERTER, 0);
ntype.declare = blender::nodes::sh_node_map_range_declare;
node_type_init(&ntype, node_shader_init_map_range);
+ node_type_storage(
+ &ntype, "NodeMapRange", node_free_standard_storage, node_copy_standard_storage);
node_type_update(&ntype, node_shader_update_map_range);
node_type_gpu(&ntype, gpu_shader_map_range);
- ntype.build_multi_function = sh_node_map_range_build_multi_function;
+ ntype.build_multi_function = blender::nodes::sh_node_map_range_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc
index 284a5f1189f..da237be273f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_math.cc
@@ -24,6 +24,7 @@
#include "node_shader_util.h"
#include "NOD_math_functions.hh"
+#include "NOD_socket_search_link.hh"
/* **************** SCALAR MATH ******************** */
@@ -44,6 +45,18 @@ static void sh_node_math_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
};
+static void sh_node_math_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ /* For now, do something very basic (only exposing "Add", and a single "Value" socket). */
+ if (params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ params.add_item(IFACE_("Value"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("ShaderNodeMath");
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
+}
+
} // namespace blender::nodes
static const char *gpu_shader_get_name(int mode)
@@ -88,7 +101,8 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl_to_fl(
mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SO<float, float> fn{info.title_case_name, function};
+ static blender::fn::CustomMF_SI_SO<float, float> fn{info.title_case_name.c_str(),
+ function};
base_fn = &fn;
});
if (base_fn != nullptr) {
@@ -97,7 +111,7 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl_fl_to_fl(
mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{info.title_case_name,
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{info.title_case_name.c_str(),
function};
base_fn = &fn;
});
@@ -108,7 +122,7 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl_fl_fl_to_fl(
mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> fn{
- info.title_case_name, function};
+ info.title_case_name.c_str(), function};
base_fn = &fn;
});
if (base_fn != nullptr) {
@@ -160,16 +174,17 @@ static void sh_node_math_build_multi_function(blender::nodes::NodeMultiFunctionB
}
}
-void register_node_type_sh_math(void)
+void register_node_type_sh_math()
{
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTER, 0);
ntype.declare = blender::nodes::sh_node_math_declare;
- node_type_label(&ntype, node_math_label);
+ ntype.labelfunc = node_math_label;
node_type_gpu(&ntype, gpu_shader_math);
node_type_update(&ntype, node_math_update);
ntype.build_multi_function = sh_node_math_build_multi_function;
+ ntype.gather_link_search_ops = blender::nodes::sh_node_math_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
index 06fafff578e..b89e0527eed 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
@@ -183,13 +183,13 @@ static void sh_node_mix_rgb_build_multi_function(blender::nodes::NodeMultiFuncti
builder.construct_and_set_matching_fn<MixRGBFunction>(clamp, mix_type);
}
-void register_node_type_sh_mix_rgb(void)
+void register_node_type_sh_mix_rgb()
{
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, 0);
ntype.declare = blender::nodes::sh_node_mix_rgb_declare;
- node_type_label(&ntype, node_blend_label);
+ ntype.labelfunc = node_blend_label;
node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_mix_rgb);
node_type_gpu(&ntype, gpu_shader_mix_rgb);
ntype.build_multi_function = sh_node_mix_rgb_build_multi_function;
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
index e4f1b2c76f0..e3808985c0e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
@@ -172,7 +172,7 @@ static void sh_node_valtorgb_build_multi_function(
builder.construct_and_set_matching_fn<ColorBandFunction>(*color_band);
}
-void register_node_type_sh_valtorgb(void)
+void register_node_type_sh_valtorgb()
{
static bNodeType ntype;
@@ -222,7 +222,7 @@ static int gpu_shader_rgbtobw(GPUMaterial *mat,
return GPU_stack_link(mat, node, "rgbtobw", in, out);
}
-void register_node_type_sh_rgbtobw(void)
+void register_node_type_sh_rgbtobw()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.c
index dfecb830b35..dfecb830b35 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.c
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
index 08a9e01786e..4984a530d8b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
@@ -103,7 +103,7 @@ static void sh_node_seprgb_build_multi_function(blender::nodes::NodeMultiFunctio
builder.set_matching_fn(fn);
}
-void register_node_type_sh_seprgb(void)
+void register_node_type_sh_seprgb()
{
static bNodeType ntype;
@@ -163,7 +163,7 @@ static void sh_node_combrgb_build_multi_function(blender::nodes::NodeMultiFuncti
builder.set_matching_fn(fn);
}
-void register_node_type_sh_combrgb(void)
+void register_node_type_sh_combrgb()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
index 1bbfa629462..a414630829e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
@@ -88,7 +88,7 @@ static void sh_node_sepxyz_build_multi_function(blender::nodes::NodeMultiFunctio
builder.set_matching_fn(separate_fn);
}
-void register_node_type_sh_sepxyz(void)
+void register_node_type_sh_sepxyz()
{
static bNodeType ntype;
@@ -129,7 +129,7 @@ static void sh_node_combxyz_build_multi_function(blender::nodes::NodeMultiFuncti
builder.set_matching_fn(fn);
}
-void register_node_type_sh_combxyz(void)
+void register_node_type_sh_combxyz()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.c
index 25c30aa4081..25c30aa4081 100644
--- a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.c
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index e917858e0f2..85a4a6aa425 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -67,6 +67,17 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
mat, node, "node_subsurface_scattering", in, out, GPU_constant(&node->sss_id));
}
+static void node_shader_update_subsurface_scattering(bNodeTree *ntree, bNode *node)
+{
+ const int sss_method = node->custom1;
+
+ for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
+ if (STR_ELEM(sock->name, "IOR", "Anisotropy")) {
+ nodeSetSocketAvailability(ntree, sock, sss_method != SHD_SUBSURFACE_BURLEY);
+ }
+ }
+}
+
/* node type definition */
void register_node_type_sh_subsurface_scattering(void)
{
@@ -80,6 +91,7 @@ void register_node_type_sh_subsurface_scattering(void)
node_type_init(&ntype, node_shader_init_subsurface_scattering);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_subsurface_scattering);
+ node_type_update(&ntype, node_shader_update_subsurface_scattering);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
index b840bd75e42..7925c96db3d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
@@ -268,7 +268,7 @@ static void sh_node_brick_build_multi_function(blender::nodes::NodeMultiFunction
} // namespace blender::nodes
-void register_node_type_sh_tex_brick(void)
+void register_node_type_sh_tex_brick()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
index 7c1223a6a32..6d2d199aec8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
@@ -123,7 +123,7 @@ static void sh_node_tex_checker_build_multi_function(
} // namespace blender::nodes
-void register_node_type_sh_tex_checker(void)
+void register_node_type_sh_tex_checker()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 26a1db1f3a6..ff08961b3e9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -143,7 +143,7 @@ void register_node_type_sh_tex_environment(void)
node_type_storage(
&ntype, "NodeTexEnvironment", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_environment);
- node_type_label(&ntype, node_image_label);
+ ntype.labelfunc = node_image_label;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
index 33832c42b3c..48199968547 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
@@ -160,7 +160,7 @@ static void sh_node_gradient_tex_build_multi_function(
} // namespace blender::nodes
-void register_node_type_sh_tex_gradient(void)
+void register_node_type_sh_tex_gradient()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
index f20fc85cbe0..d139707c6d7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
@@ -174,7 +174,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
}
/* node type definition */
-void register_node_type_sh_tex_image(void)
+void register_node_type_sh_tex_image()
{
static bNodeType ntype;
@@ -184,7 +184,7 @@ void register_node_type_sh_tex_image(void)
node_type_storage(
&ntype, "NodeTexImage", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_image);
- node_type_label(&ntype, node_image_label);
+ ntype.labelfunc = node_image_label;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
index 62e68d53d03..9bd5c335cee 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
@@ -181,7 +181,7 @@ static void sh_node_magic_tex_build_multi_function(
} // namespace blender::nodes
-void register_node_type_sh_tex_magic(void)
+void register_node_type_sh_tex_magic()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
index e426d9cc49c..97ac199bc03 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
@@ -21,13 +21,18 @@
#include "BLI_noise.hh"
+NODE_STORAGE_FUNCS(NodeTexMusgrave)
+
namespace blender::nodes {
static void sh_node_tex_musgrave_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
- b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
+ /* Default to 1 instead of 4, because it is much faster. */
+ node_storage(node).dimensions = 1;
+ });
b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>(N_("Detail")).min(0.0f).max(15.0f).default_value(2.0f);
b.add_input<decl::Float>(N_("Dimension")).min(0.0f).max(1000.0f).default_value(2.0f);
@@ -106,23 +111,23 @@ static int node_shader_gpu_tex_musgrave(GPUMaterial *mat,
static void node_shader_update_tex_musgrave(bNodeTree *ntree, bNode *node)
{
- NodeTexMusgrave *tex = (NodeTexMusgrave *)node->storage;
+ const NodeTexMusgrave &storage = node_storage(*node);
bNodeSocket *inVectorSock = nodeFindSocket(node, SOCK_IN, "Vector");
bNodeSocket *inWSock = nodeFindSocket(node, SOCK_IN, "W");
bNodeSocket *inOffsetSock = nodeFindSocket(node, SOCK_IN, "Offset");
bNodeSocket *inGainSock = nodeFindSocket(node, SOCK_IN, "Gain");
- nodeSetSocketAvailability(ntree, inVectorSock, tex->dimensions != 1);
- nodeSetSocketAvailability(ntree, inWSock, tex->dimensions == 1 || tex->dimensions == 4);
+ nodeSetSocketAvailability(ntree, inVectorSock, storage.dimensions != 1);
+ nodeSetSocketAvailability(ntree, inWSock, storage.dimensions == 1 || storage.dimensions == 4);
nodeSetSocketAvailability(ntree,
inOffsetSock,
- tex->musgrave_type != SHD_MUSGRAVE_MULTIFRACTAL &&
- tex->musgrave_type != SHD_MUSGRAVE_FBM);
+ storage.musgrave_type != SHD_MUSGRAVE_MULTIFRACTAL &&
+ storage.musgrave_type != SHD_MUSGRAVE_FBM);
nodeSetSocketAvailability(ntree,
inGainSock,
- tex->musgrave_type == SHD_MUSGRAVE_HYBRID_MULTIFRACTAL ||
- tex->musgrave_type == SHD_MUSGRAVE_RIDGED_MULTIFRACTAL);
+ storage.musgrave_type == SHD_MUSGRAVE_HYBRID_MULTIFRACTAL ||
+ storage.musgrave_type == SHD_MUSGRAVE_RIDGED_MULTIFRACTAL);
bNodeSocket *outFacSock = nodeFindSocket(node, SOCK_OUT, "Fac");
node_sock_label(outFacSock, "Height");
@@ -531,7 +536,7 @@ static void sh_node_musgrave_build_multi_function(
} // namespace blender::nodes
-void register_node_type_sh_tex_musgrave(void)
+void register_node_type_sh_tex_musgrave()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
index 7dd2695ecf7..d7f21853a01 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
@@ -21,13 +21,18 @@
#include "BLI_noise.hh"
+NODE_STORAGE_FUNCS(NodeTexNoise)
+
namespace blender::nodes {
static void sh_node_tex_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Vector")).implicit_field();
- b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
+ /* Default to 1 instead of 4, because it is much faster. */
+ node_storage(node).dimensions = 1;
+ });
b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>(N_("Detail")).min(0.0f).max(15.0f).default_value(2.0f);
b.add_input<decl::Float>(N_("Roughness"))
@@ -71,8 +76,8 @@ static int node_shader_gpu_tex_noise(GPUMaterial *mat,
node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
node_shader_gpu_tex_mapping(mat, node, in, out);
- NodeTexNoise *tex = (NodeTexNoise *)node->storage;
- const char *name = gpu_shader_get_name(tex->dimensions);
+ const NodeTexNoise &storage = node_storage(*node);
+ const char *name = gpu_shader_get_name(storage.dimensions);
return GPU_stack_link(mat, node, name, in, out);
}
@@ -81,9 +86,9 @@ static void node_shader_update_tex_noise(bNodeTree *ntree, bNode *node)
bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
bNodeSocket *sockW = nodeFindSocket(node, SOCK_IN, "W");
- NodeTexNoise *tex = (NodeTexNoise *)node->storage;
- nodeSetSocketAvailability(ntree, sockVector, tex->dimensions != 1);
- nodeSetSocketAvailability(ntree, sockW, tex->dimensions == 1 || tex->dimensions == 4);
+ const NodeTexNoise &storage = node_storage(*node);
+ nodeSetSocketAvailability(ntree, sockVector, storage.dimensions != 1);
+ nodeSetSocketAvailability(ntree, sockW, storage.dimensions == 1 || storage.dimensions == 4);
}
namespace blender::nodes {
@@ -229,19 +234,26 @@ class NoiseFunction : public fn::MultiFunction {
}
}
}
+
+ ExecutionHints get_execution_hints() const override
+ {
+ ExecutionHints hints;
+ hints.allocates_array = false;
+ hints.min_grain_size = 100;
+ return hints;
+ }
};
static void sh_node_noise_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
{
- bNode &node = builder.node();
- NodeTexNoise *tex = (NodeTexNoise *)node.storage;
- builder.construct_and_set_matching_fn<NoiseFunction>(tex->dimensions);
+ const NodeTexNoise &storage = node_storage(builder.node());
+ builder.construct_and_set_matching_fn<NoiseFunction>(storage.dimensions);
}
} // namespace blender::nodes
/* node type definition */
-void register_node_type_sh_tex_noise(void)
+void register_node_type_sh_tex_noise()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
index 1bc3741d27c..8a1170de304 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
@@ -21,20 +21,30 @@
#include "BLI_noise.hh"
+NODE_STORAGE_FUNCS(NodeTexVoronoi)
+
namespace blender::nodes {
static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
- b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
+ /* Default to 1 instead of 4, because it is much faster. */
+ node_storage(node).dimensions = 1;
+ });
b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>(N_("Smoothness"))
.min(0.0f)
.max(1.0f)
.default_value(1.0f)
- .subtype(PROP_FACTOR);
- b.add_input<decl::Float>(N_("Exponent")).min(0.0f).max(32.0f).default_value(0.5f);
+ .subtype(PROP_FACTOR)
+ .make_available([](bNode &node) { node_storage(node).feature = SHD_VORONOI_SMOOTH_F1; });
+ b.add_input<decl::Float>(N_("Exponent"))
+ .min(0.0f)
+ .max(32.0f)
+ .default_value(0.5f)
+ .make_available([](bNode &node) { node_storage(node).distance = SHD_VORONOI_MINKOWSKI; });
b.add_input<decl::Float>(N_("Randomness"))
.min(0.0f)
.max(1.0f)
@@ -43,8 +53,13 @@ static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Distance")).no_muted_links();
b.add_output<decl::Color>(N_("Color")).no_muted_links();
b.add_output<decl::Vector>(N_("Position")).no_muted_links();
- b.add_output<decl::Float>(N_("W")).no_muted_links();
- b.add_output<decl::Float>(N_("Radius")).no_muted_links();
+ b.add_output<decl::Float>(N_("W")).no_muted_links().make_available([](bNode &node) {
+ /* Default to 1 instead of 4, because it is much faster. */
+ node_storage(node).dimensions = 1;
+ });
+ b.add_output<decl::Float>(N_("Radius")).no_muted_links().make_available([](bNode &node) {
+ node_storage(node).feature = SHD_VORONOI_N_SPHERE_RADIUS;
+ });
};
} // namespace blender::nodes
@@ -136,37 +151,40 @@ static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
bNodeSocket *outWSock = nodeFindSocket(node, SOCK_OUT, "W");
bNodeSocket *outRadiusSock = nodeFindSocket(node, SOCK_OUT, "Radius");
- NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage;
+ const NodeTexVoronoi &storage = node_storage(*node);
- nodeSetSocketAvailability(ntree, inWSock, tex->dimensions == 1 || tex->dimensions == 4);
- nodeSetSocketAvailability(ntree, inVectorSock, tex->dimensions != 1);
+ nodeSetSocketAvailability(ntree, inWSock, storage.dimensions == 1 || storage.dimensions == 4);
+ nodeSetSocketAvailability(ntree, inVectorSock, storage.dimensions != 1);
nodeSetSocketAvailability(
ntree,
inExponentSock,
- tex->distance == SHD_VORONOI_MINKOWSKI && tex->dimensions != 1 &&
- !ELEM(tex->feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
- nodeSetSocketAvailability(ntree, inSmoothnessSock, tex->feature == SHD_VORONOI_SMOOTH_F1);
+ storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
+ !ELEM(storage.feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
+ nodeSetSocketAvailability(ntree, inSmoothnessSock, storage.feature == SHD_VORONOI_SMOOTH_F1);
- nodeSetSocketAvailability(ntree, outDistanceSock, tex->feature != SHD_VORONOI_N_SPHERE_RADIUS);
+ nodeSetSocketAvailability(
+ ntree, outDistanceSock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
nodeSetSocketAvailability(ntree,
outColorSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS);
+ storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
+ storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
nodeSetSocketAvailability(ntree,
outPositionSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS &&
- tex->dimensions != 1);
+ storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
+ storage.feature != SHD_VORONOI_N_SPHERE_RADIUS &&
+ storage.dimensions != 1);
nodeSetSocketAvailability(ntree,
outWSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS &&
- (ELEM(tex->dimensions, 1, 4)));
- nodeSetSocketAvailability(ntree, outRadiusSock, tex->feature == SHD_VORONOI_N_SPHERE_RADIUS);
+ storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
+ storage.feature != SHD_VORONOI_N_SPHERE_RADIUS &&
+ (ELEM(storage.dimensions, 1, 4)));
+ nodeSetSocketAvailability(ntree, outRadiusSock, storage.feature == SHD_VORONOI_N_SPHERE_RADIUS);
}
namespace blender::nodes {
+static MultiFunction::ExecutionHints voronoi_execution_hints{50, false};
+
class VoronoiMinowskiFunction : public fn::MultiFunction {
private:
int dimensions_;
@@ -592,6 +610,11 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
}
}
}
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
};
class VoronoiMetricFunction : public fn::MultiFunction {
@@ -1106,6 +1129,11 @@ class VoronoiMetricFunction : public fn::MultiFunction {
}
}
}
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
};
class VoronoiEdgeFunction : public fn::MultiFunction {
@@ -1282,31 +1310,39 @@ class VoronoiEdgeFunction : public fn::MultiFunction {
break;
}
}
- };
+ }
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
};
static void sh_node_voronoi_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
{
- bNode &node = builder.node();
- NodeTexVoronoi *tex = (NodeTexVoronoi *)node.storage;
- bool minowski = (tex->distance == SHD_VORONOI_MINKOWSKI && tex->dimensions != 1 &&
- !ELEM(tex->feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
- bool dist_radius = ELEM(tex->feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS);
+ const NodeTexVoronoi &storage = node_storage(builder.node());
+ bool minowski =
+ (storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
+ !ELEM(storage.feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
+ bool dist_radius = ELEM(
+ storage.feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS);
if (dist_radius) {
- builder.construct_and_set_matching_fn<VoronoiEdgeFunction>(tex->dimensions, tex->feature);
+ builder.construct_and_set_matching_fn<VoronoiEdgeFunction>(storage.dimensions,
+ storage.feature);
}
else if (minowski) {
- builder.construct_and_set_matching_fn<VoronoiMinowskiFunction>(tex->dimensions, tex->feature);
+ builder.construct_and_set_matching_fn<VoronoiMinowskiFunction>(storage.dimensions,
+ storage.feature);
}
else {
builder.construct_and_set_matching_fn<VoronoiMetricFunction>(
- tex->dimensions, tex->feature, tex->distance);
+ storage.dimensions, storage.feature, storage.distance);
}
}
} // namespace blender::nodes
-void register_node_type_sh_tex_voronoi(void)
+void register_node_type_sh_tex_voronoi()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
index fe534c605e9..d3e25b533e5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
@@ -218,7 +218,7 @@ static void sh_node_wave_tex_build_multi_function(
} // namespace blender::nodes
-void register_node_type_sh_tex_wave(void)
+void register_node_type_sh_tex_wave()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
index 7b4ff7fec5c..0e72cee38e7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc
@@ -27,7 +27,10 @@ static void sh_node_tex_white_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f).implicit_field();
- b.add_input<decl::Float>(N_("W")).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("W")).min(-10000.0f).max(10000.0f).make_available([](bNode &node) {
+ /* Default to 1 instead of 4, because it is faster. */
+ node.custom1 = 1;
+ });
b.add_output<decl::Float>(N_("Value"));
b.add_output<decl::Color>(N_("Color"));
};
@@ -191,7 +194,7 @@ static void sh_node_noise_build_multi_function(blender::nodes::NodeMultiFunction
} // namespace blender::nodes
-void register_node_type_sh_tex_white_noise(void)
+void register_node_type_sh_tex_white_noise()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.c
index 05c3248af65..05c3248af65 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.c
diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc
index b0f152d8526..f0eb3ea9bee 100644
--- a/source/blender/nodes/shader/nodes/node_shader_value.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_value.cc
@@ -49,7 +49,7 @@ static void sh_node_value_build_multi_function(blender::nodes::NodeMultiFunction
builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<float>>(value->value);
}
-void register_node_type_sh_value(void)
+void register_node_type_sh_value()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
index fad93962708..5f5969de78c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
@@ -24,6 +24,7 @@
#include "node_shader_util.h"
#include "NOD_math_functions.hh"
+#include "NOD_socket_search_link.hh"
namespace blender::nodes {
@@ -38,6 +39,18 @@ static void sh_node_vector_math_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Value"));
};
+static void sh_node_vector_math_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ /* For now, do something very basic (only exposing "Add", and a single "Vector" socket). */
+ if (params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_VECTOR)) {
+ params.add_item(IFACE_("Vector"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("ShaderNodeVectorMath");
+ params.update_and_connect_available_socket(node, "Vector");
+ });
+ }
+}
+
} // namespace blender::nodes
static const char *gpu_shader_get_name(int mode)
@@ -201,8 +214,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_fl3_to_fl3(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{info.title_case_name,
- function};
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ info.title_case_name.c_str(), function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -212,7 +225,7 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_fl3_fl3_to_fl3(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{
- info.title_case_name, function};
+ info.title_case_name.c_str(), function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -222,7 +235,7 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_fl3_fl_to_fl3(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
- info.title_case_name, function};
+ info.title_case_name.c_str(), function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -231,8 +244,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_fl3_to_fl(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{info.title_case_name,
- function};
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{
+ info.title_case_name.c_str(), function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -241,8 +254,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_fl_to_fl3(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SI_SO<float3, float, float3> fn{info.title_case_name,
- function};
+ static blender::fn::CustomMF_SI_SI_SO<float3, float, float3> fn{
+ info.title_case_name.c_str(), function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -251,7 +264,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_to_fl3(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SO<float3, float3> fn{info.title_case_name, function};
+ static blender::fn::CustomMF_SI_SO<float3, float3> fn{info.title_case_name.c_str(),
+ function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -260,7 +274,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node)
blender::nodes::try_dispatch_float_math_fl3_to_fl(
operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
- static blender::fn::CustomMF_SI_SO<float3, float> fn{info.title_case_name, function};
+ static blender::fn::CustomMF_SI_SO<float3, float> fn{info.title_case_name.c_str(),
+ function};
multi_fn = &fn;
});
if (multi_fn != nullptr) {
@@ -277,16 +292,17 @@ static void sh_node_vector_math_build_multi_function(
builder.set_matching_fn(fn);
}
-void register_node_type_sh_vect_math(void)
+void register_node_type_sh_vect_math()
{
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_OP_VECTOR, 0);
ntype.declare = blender::nodes::sh_node_vector_math_declare;
- node_type_label(&ntype, node_vector_math_label);
+ ntype.labelfunc = node_vector_math_label;
node_type_gpu(&ntype, gpu_shader_vector_math);
node_type_update(&ntype, node_shader_update_vector_math);
ntype.build_multi_function = sh_node_vector_math_build_multi_function;
+ ntype.gather_link_search_ops = blender::nodes::sh_node_vector_math_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
index 3c1f1ed8d39..a3cb82f3245 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
@@ -205,7 +205,7 @@ static void node_shader_update_vector_rotate(bNodeTree *ntree, bNode *node)
ntree, sock_angle, !ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
}
-void register_node_type_sh_vector_rotate(void)
+void register_node_type_sh_vector_rotate()
{
static bNodeType ntype;
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vector_transform.c
index 7b08178f874..7b08178f874 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_transform.c