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')
-rw-r--r--source/blender/nodes/shader/CMakeLists.txt174
-rw-r--r--source/blender/nodes/shader/node_shader_tree.cc (renamed from source/blender/nodes/shader/node_shader_tree.c)282
-rw-r--r--source/blender/nodes/shader/node_shader_util.cc (renamed from source/blender/nodes/shader/node_shader_util.c)62
-rw-r--r--source/blender/nodes/shader/node_shader_util.hh (renamed from source/blender/nodes/shader/node_shader_util.h)77
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_add_shader.cc (renamed from source/blender/nodes/shader/nodes/node_shader_add_shader.c)34
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc (renamed from source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c)50
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.cc (renamed from source/blender/nodes/shader/nodes/node_shader_attribute.c)50
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_background.cc (renamed from source/blender/nodes/shader/nodes/node_shader_background.c)35
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bevel.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bevel.c)42
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.cc (renamed from source/blender/nodes/shader/nodes/node_shader_blackbody.c)33
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_brightness.cc (renamed from source/blender/nodes/shader/nodes/node_shader_brightness.c)36
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c80
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc96
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c)44
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c96
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc85
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c)52
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_hair.c)60
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c135
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc145
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c195
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc259
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c)47
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c)57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c)38
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c)36
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c)44
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.cc (renamed from source/blender/nodes/shader/nodes/node_shader_bump.c)56
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_camera.cc (renamed from source/blender/nodes/shader/nodes/node_shader_camera.c)30
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_clamp.cc39
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_color_ramp.cc (renamed from source/blender/nodes/shader/nodes/node_shader_valToRgb.cc)96
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c270
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.cc130
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.cc219
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_displacement.cc (renamed from source/blender/nodes/shader/nodes/node_shader_displacement.c)39
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_specular.c103
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc97
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_emission.cc (renamed from source/blender/nodes/shader/nodes/node_shader_emission.c)38
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.cc (renamed from source/blender/nodes/shader/nodes/node_shader_fresnel.c)41
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c73
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.cc57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.cc (renamed from source/blender/nodes/shader/nodes/node_shader_geometry.c)48
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hair_info.cc (renamed from source/blender/nodes/shader/nodes/node_shader_hair_info.c)39
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_holdout.cc (renamed from source/blender/nodes/shader/nodes/node_shader_holdout.c)32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.c99
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc61
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ies_light.c53
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ies_light.cc74
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.c78
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.cc57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_layer_weight.cc (renamed from source/blender/nodes/shader/nodes/node_shader_layer_weight.c)44
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_falloff.cc (renamed from source/blender/nodes/shader/nodes/node_shader_light_falloff.c)40
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_path.c62
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_path.cc64
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc508
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c77
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.cc110
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.cc81
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_mixRgb.cc)57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mix_shader.cc (renamed from source/blender/nodes/shader/nodes/node_shader_mix_shader.c)36
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.cc (renamed from source/blender/nodes/shader/nodes/node_shader_normal.c)55
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.cc (renamed from source/blender/nodes/shader/nodes/node_shader_normal_map.c)76
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.cc (renamed from source/blender/nodes/shader/nodes/node_shader_object_info.c)32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_aov.cc (renamed from source/blender/nodes/shader/nodes/node_shader_output_aov.c)42
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_light.cc (renamed from source/blender/nodes/shader/nodes/node_shader_output_light.c)28
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_linestyle.c45
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc72
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_material.c85
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_material.cc83
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.cc (renamed from source/blender/nodes/shader/nodes/node_shader_output_world.c)31
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_particle_info.cc (renamed from source/blender/nodes/shader/nodes/node_shader_particle_info.c)48
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_point_info.cc54
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_rgb.c)25
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc58
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_script.c70
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_script.cc112
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c118
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc96
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc)88
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc)58
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c)34
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.c71
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.cc58
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c76
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc113
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.cc (renamed from source/blender/nodes/shader/nodes/node_shader_tangent.c)62
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c181
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.cc306
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.c90
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.cc137
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.cc (renamed from source/blender/nodes/shader/nodes/node_shader_tex_coord.c)70
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.cc (renamed from source/blender/nodes/shader/nodes/node_shader_tex_environment.c)40
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc141
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.cc (renamed from source/blender/nodes/shader/nodes/node_shader_tex_image.c)61
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.c84
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.cc204
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc482
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.cc88
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c82
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc131
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.cc (renamed from source/blender/nodes/shader/nodes/node_shader_tex_sky.c)91
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc1284
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.c101
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.cc250
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc171
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc (renamed from source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c)32
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvmap.cc (renamed from source/blender/nodes/shader/nodes/node_shader_uvmap.c)50
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_value.cc24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc (renamed from source/blender/nodes/shader/nodes/node_shader_vector_displacement.c)38
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.cc128
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc54
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_transform.cc (renamed from source/blender/nodes/shader/nodes/node_shader_vectTransform.c)100
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.cc (renamed from source/blender/nodes/shader/nodes/node_shader_vertex_color.c)57
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc (renamed from source/blender/nodes/shader/nodes/node_shader_volume_absorption.c)35
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_info.cc (renamed from source/blender/nodes/shader/nodes/node_shader_volume_info.c)30
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_principled.cc (renamed from source/blender/nodes/shader/nodes/node_shader_volume_principled.c)76
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc (renamed from source/blender/nodes/shader/nodes/node_shader_volume_scatter.c)41
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wavelength.cc (renamed from source/blender/nodes/shader/nodes/node_shader_wavelength.c)33
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wireframe.cc (renamed from source/blender/nodes/shader/nodes/node_shader_wireframe.c)40
119 files changed, 7500 insertions, 4174 deletions
diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt
new file mode 100644
index 00000000000..c8eb0b8d570
--- /dev/null
+++ b/source/blender/nodes/shader/CMakeLists.txt
@@ -0,0 +1,174 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2021, Blender Foundation
+# All rights reserved.
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ..
+ ../intern
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../depsgraph
+ ../../editors/include
+ ../../functions
+ ../../gpu
+ ../../imbuf
+ ../../makesdna
+ ../../makesrna
+ ../../render
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/sky/include
+)
+
+
+set(SRC
+ nodes/node_shader_add_shader.cc
+ nodes/node_shader_ambient_occlusion.cc
+ nodes/node_shader_attribute.cc
+ nodes/node_shader_background.cc
+ nodes/node_shader_bevel.cc
+ nodes/node_shader_blackbody.cc
+ nodes/node_shader_brightness.cc
+ nodes/node_shader_bsdf_anisotropic.cc
+ nodes/node_shader_bsdf_diffuse.cc
+ nodes/node_shader_bsdf_glass.cc
+ nodes/node_shader_bsdf_glossy.cc
+ nodes/node_shader_bsdf_hair.cc
+ nodes/node_shader_bsdf_hair_principled.cc
+ nodes/node_shader_bsdf_principled.cc
+ nodes/node_shader_bsdf_refraction.cc
+ nodes/node_shader_bsdf_toon.cc
+ nodes/node_shader_bsdf_translucent.cc
+ nodes/node_shader_bsdf_transparent.cc
+ nodes/node_shader_bsdf_velvet.cc
+ nodes/node_shader_bump.cc
+ nodes/node_shader_camera.cc
+ nodes/node_shader_clamp.cc
+ nodes/node_shader_color_ramp.cc
+ nodes/node_shader_common.cc
+ nodes/node_shader_curves.cc
+ nodes/node_shader_displacement.cc
+ nodes/node_shader_eevee_specular.cc
+ nodes/node_shader_emission.cc
+ nodes/node_shader_fresnel.cc
+ nodes/node_shader_gamma.cc
+ nodes/node_shader_geometry.cc
+ nodes/node_shader_hair_info.cc
+ nodes/node_shader_holdout.cc
+ nodes/node_shader_hueSatVal.cc
+ nodes/node_shader_ies_light.cc
+ nodes/node_shader_invert.cc
+ nodes/node_shader_layer_weight.cc
+ nodes/node_shader_light_falloff.cc
+ nodes/node_shader_light_path.cc
+ nodes/node_shader_map_range.cc
+ nodes/node_shader_mapping.cc
+ nodes/node_shader_math.cc
+ nodes/node_shader_mix_rgb.cc
+ nodes/node_shader_mix_shader.cc
+ nodes/node_shader_normal.cc
+ nodes/node_shader_normal_map.cc
+ nodes/node_shader_object_info.cc
+ nodes/node_shader_output_aov.cc
+ nodes/node_shader_output_light.cc
+ nodes/node_shader_output_linestyle.cc
+ nodes/node_shader_output_material.cc
+ nodes/node_shader_output_world.cc
+ nodes/node_shader_particle_info.cc
+ nodes/node_shader_point_info.cc
+ nodes/node_shader_rgb.cc
+ nodes/node_shader_rgb_to_bw.cc
+ nodes/node_shader_script.cc
+ nodes/node_shader_sepcomb_hsv.cc
+ nodes/node_shader_sepcomb_rgb.cc
+ nodes/node_shader_sepcomb_xyz.cc
+ nodes/node_shader_shader_to_rgb.cc
+ nodes/node_shader_squeeze.cc
+ nodes/node_shader_subsurface_scattering.cc
+ nodes/node_shader_tangent.cc
+ nodes/node_shader_tex_brick.cc
+ nodes/node_shader_tex_checker.cc
+ nodes/node_shader_tex_coord.cc
+ nodes/node_shader_tex_environment.cc
+ nodes/node_shader_tex_gradient.cc
+ nodes/node_shader_tex_image.cc
+ nodes/node_shader_tex_magic.cc
+ nodes/node_shader_tex_musgrave.cc
+ nodes/node_shader_tex_noise.cc
+ nodes/node_shader_tex_pointdensity.cc
+ nodes/node_shader_tex_sky.cc
+ nodes/node_shader_tex_voronoi.cc
+ nodes/node_shader_tex_wave.cc
+ nodes/node_shader_tex_white_noise.cc
+ nodes/node_shader_uv_along_stroke.cc
+ nodes/node_shader_uvmap.cc
+ nodes/node_shader_value.cc
+ nodes/node_shader_vector_displacement.cc
+ nodes/node_shader_vector_math.cc
+ nodes/node_shader_vector_rotate.cc
+ nodes/node_shader_vector_transform.cc
+ nodes/node_shader_vertex_color.cc
+ nodes/node_shader_volume_absorption.cc
+ nodes/node_shader_volume_info.cc
+ nodes/node_shader_volume_principled.cc
+ nodes/node_shader_volume_scatter.cc
+ nodes/node_shader_wavelength.cc
+ nodes/node_shader_wireframe.cc
+
+ node_shader_tree.cc
+ node_shader_util.cc
+
+ node_shader_util.hh
+)
+
+set(LIB
+ bf_functions
+ bf_intern_sky
+)
+
+if(WITH_PYTHON)
+ list(APPEND INC
+ ../../python
+ )
+ list(APPEND INC_SYS
+ ${PYTHON_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${PYTHON_LINKFLAGS}
+ ${PYTHON_LIBRARIES}
+ )
+ add_definitions(-DWITH_PYTHON)
+endif()
+
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
+if(WITH_FREESTYLE)
+ add_definitions(-DWITH_FREESTYLE)
+endif()
+
+blender_add_lib(bf_nodes_shader "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_UNITY_BUILD)
+ set_target_properties(bf_nodes_shader PROPERTIES UNITY_BUILD ON)
+ set_target_properties(bf_nodes_shader PROPERTIES UNITY_BUILD_BATCH_SIZE 10)
+endif()
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.cc
index 46a2f7f1968..1cb1ee3163d 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.cc
@@ -21,7 +21,7 @@
* \ingroup nodes
*/
-#include <string.h>
+#include <cstring>
#include "DNA_light_types.h"
#include "DNA_linestyle_types.h"
@@ -44,6 +44,7 @@
#include "BKE_lib_id.h"
#include "BKE_linestyle.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_scene.h"
#include "RNA_access.h"
@@ -52,11 +53,13 @@
#include "RE_texture.h"
+#include "UI_resources.h"
+
#include "NOD_common.h"
#include "node_common.h"
#include "node_exec.h"
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
#include "node_util.h"
static bool shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
@@ -85,7 +88,7 @@ static void shader_get_from_context(const bContext *C,
if (ob) {
*r_from = &ob->id;
if (ob->type == OB_LAMP) {
- *r_id = ob->data;
+ *r_id = static_cast<ID *>(ob->data);
*r_ntree = ((Light *)ob->data)->nodetree;
}
else {
@@ -101,7 +104,7 @@ static void shader_get_from_context(const bContext *C,
else if (snode->shaderfrom == SNODE_SHADER_LINESTYLE) {
FreestyleLineStyle *linestyle = BKE_linestyle_active_from_view_layer(view_layer);
if (linestyle) {
- *r_from = NULL;
+ *r_from = nullptr;
*r_id = &linestyle->id;
*r_ntree = linestyle->nodetree;
}
@@ -109,7 +112,7 @@ static void shader_get_from_context(const bContext *C,
#endif
else { /* SNODE_SHADER_WORLD */
if (scene->world) {
- *r_from = NULL;
+ *r_from = nullptr;
*r_id = &scene->world->id;
*r_ntree = scene->world->nodetree;
}
@@ -133,12 +136,8 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
- bNode *node, *node_next;
-
/* replace muted nodes and reroute nodes by internal links */
- for (node = localtree->nodes.first; node; node = node_next) {
- node_next = node->next;
-
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &localtree->nodes) {
if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
nodeInternalRelink(localtree, node);
ntreeFreeLocalNode(localtree, node);
@@ -146,34 +145,19 @@ static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
}
}
-static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
-{
- BKE_node_preview_sync_tree(ntree, localtree);
-}
-
-static void local_merge(Main *UNUSED(bmain), bNodeTree *localtree, bNodeTree *ntree)
-{
- BKE_node_preview_merge_tree(ntree, localtree, true);
-}
-
static void update(bNodeTree *ntree)
{
ntreeSetOutput(ntree);
ntree_update_reroute_nodes(ntree);
-
- if (ntree->update & NTREE_UPDATE_NODES) {
- /* clean up preview cache, in case nodes have been removed */
- BKE_node_preview_remove_unused(ntree);
- }
}
-static bool shader_validate_link(bNodeTree *UNUSED(ntree), bNodeLink *link)
+static bool shader_validate_link(eNodeSocketDatatype from, eNodeSocketDatatype to)
{
/* Can't connect shader into other socket types, other way around is fine
* since it will be interpreted as emission. */
- if (link->fromsock->type == SOCK_SHADER) {
- return (link->tosock->type == SOCK_SHADER);
+ if (from == SOCK_SHADER) {
+ return to == SOCK_SHADER;
}
return true;
}
@@ -187,21 +171,18 @@ static bool shader_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
bNodeTreeType *ntreeType_Shader;
-void register_node_tree_type_sh(void)
+void register_node_tree_type_sh()
{
- bNodeTreeType *tt = ntreeType_Shader = MEM_callocN(sizeof(bNodeTreeType),
- "shader node tree type");
+ bNodeTreeType *tt = ntreeType_Shader = MEM_cnew<bNodeTreeType>("shader node tree type");
tt->type = NTREE_SHADER;
strcpy(tt->idname, "ShaderNodeTree");
strcpy(tt->ui_name, N_("Shader Editor"));
- tt->ui_icon = 0; /* defined in drawnode.c */
+ tt->ui_icon = ICON_NODE_MATERIAL;
strcpy(tt->ui_description, N_("Shader nodes"));
tt->foreach_nodeclass = foreach_nodeclass;
tt->localize = localize;
- tt->local_sync = local_sync;
- tt->local_merge = local_merge;
tt->update = update;
tt->poll = shader_tree_poll;
tt->get_from_context = shader_get_from_context;
@@ -215,13 +196,6 @@ void register_node_tree_type_sh(void)
/* GPU material from shader nodes */
-/* Find an output node of the shader tree.
- *
- * NOTE: it will only return output which is NOT in the group, which isn't how
- * render engines works but it's how the GPU shader compilation works. This we
- * can change in the future and make it a generic function, but for now it stays
- * private here.
- */
bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
{
/* Make sure we only have single node tagged as output. */
@@ -229,7 +203,7 @@ bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
/* Find output node that matches type and target. If there are
* multiple, we prefer exact target match and active nodes. */
- bNode *output_node = NULL;
+ bNode *output_node = nullptr;
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (!ELEM(node->type, SH_NODE_OUTPUT_MATERIAL, SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LIGHT)) {
@@ -237,7 +211,7 @@ bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
}
if (node->custom1 == SHD_OUTPUT_ALL) {
- if (output_node == NULL) {
+ if (output_node == nullptr) {
output_node = node;
}
else if (output_node->custom1 == SHD_OUTPUT_ALL) {
@@ -247,7 +221,7 @@ bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
}
}
else if (node->custom1 == target) {
- if (output_node == NULL) {
+ if (output_node == nullptr) {
output_node = node;
}
else if (output_node->custom1 == SHD_OUTPUT_ALL) {
@@ -265,12 +239,12 @@ bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
/* Find socket with a specified identifier. */
static bNodeSocket *ntree_shader_node_find_socket(ListBase *sockets, const char *identifier)
{
- for (bNodeSocket *sock = sockets->first; sock != NULL; sock = sock->next) {
+ LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
if (STREQ(sock->identifier, identifier)) {
return sock;
}
}
- return NULL;
+ return nullptr;
}
/* Find input socket with a specified identifier. */
@@ -311,37 +285,37 @@ static bool ntree_shader_expand_socket_default(bNodeTree *localtree,
switch (socket->type) {
case SOCK_VECTOR:
- value_node = nodeAddStaticNode(NULL, localtree, SH_NODE_RGB);
+ value_node = nodeAddStaticNode(nullptr, localtree, SH_NODE_RGB);
value_socket = ntree_shader_node_find_output(value_node, "Color");
- BLI_assert(value_socket != NULL);
- src_vector = socket->default_value;
- dst_rgba = value_socket->default_value;
+ BLI_assert(value_socket != nullptr);
+ src_vector = static_cast<bNodeSocketValueVector *>(socket->default_value);
+ dst_rgba = static_cast<bNodeSocketValueRGBA *>(value_socket->default_value);
copy_v3_v3(dst_rgba->value, src_vector->value);
dst_rgba->value[3] = 1.0f; /* should never be read */
break;
case SOCK_RGBA:
- value_node = nodeAddStaticNode(NULL, localtree, SH_NODE_RGB);
+ value_node = nodeAddStaticNode(nullptr, localtree, SH_NODE_RGB);
value_socket = ntree_shader_node_find_output(value_node, "Color");
- BLI_assert(value_socket != NULL);
- src_rgba = socket->default_value;
- dst_rgba = value_socket->default_value;
+ BLI_assert(value_socket != nullptr);
+ src_rgba = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
+ dst_rgba = static_cast<bNodeSocketValueRGBA *>(value_socket->default_value);
copy_v4_v4(dst_rgba->value, src_rgba->value);
break;
case SOCK_INT:
/* HACK: Support as float. */
- value_node = nodeAddStaticNode(NULL, localtree, SH_NODE_VALUE);
+ value_node = nodeAddStaticNode(nullptr, localtree, SH_NODE_VALUE);
value_socket = ntree_shader_node_find_output(value_node, "Value");
- BLI_assert(value_socket != NULL);
- src_int = socket->default_value;
- dst_float = value_socket->default_value;
+ BLI_assert(value_socket != nullptr);
+ src_int = static_cast<bNodeSocketValueInt *>(socket->default_value);
+ dst_float = static_cast<bNodeSocketValueFloat *>(value_socket->default_value);
dst_float->value = (float)(src_int->value);
break;
case SOCK_FLOAT:
- value_node = nodeAddStaticNode(NULL, localtree, SH_NODE_VALUE);
+ value_node = nodeAddStaticNode(nullptr, localtree, SH_NODE_VALUE);
value_socket = ntree_shader_node_find_output(value_node, "Value");
- BLI_assert(value_socket != NULL);
- src_float = socket->default_value;
- dst_float = value_socket->default_value;
+ BLI_assert(value_socket != nullptr);
+ src_float = static_cast<bNodeSocketValueFloat *>(socket->default_value);
+ dst_float = static_cast<bNodeSocketValueFloat *>(value_socket->default_value);
dst_float->value = src_float->value;
break;
default:
@@ -354,11 +328,10 @@ static bool ntree_shader_expand_socket_default(bNodeTree *localtree,
static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSocket *isock)
{
bNodeTree *group_ntree = (bNodeTree *)group_node->id;
- bNode *node;
bool removed_link = false;
- for (node = group_ntree->nodes.first; node; node = node->next) {
- const bool is_group = ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && (node->id != NULL);
+ LISTBASE_FOREACH (bNode *, node, &group_ntree->nodes) {
+ const bool is_group = ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && (node->id != nullptr);
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (!is_group && (sock->flag & SOCK_HIDE_VALUE) == 0) {
@@ -381,7 +354,7 @@ static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSoc
}
if (removed_link) {
- ntreeUpdateTree(G.main, group_ntree);
+ BKE_ntree_update_main_tree(G.main, group_ntree, nullptr);
}
}
@@ -392,7 +365,7 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
bool link_added = false;
LISTBASE_FOREACH (bNode *, node, &localtree->nodes) {
- const bool is_group = ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && (node->id != NULL);
+ const bool is_group = ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && (node->id != nullptr);
const bool is_group_output = node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT);
if (is_group) {
@@ -402,25 +375,32 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
if (is_group || is_group_output) {
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
- if (socket->link != NULL && !(socket->link->flag & NODE_LINK_MUTED)) {
+ if (socket->link != nullptr && !(socket->link->flag & NODE_LINK_MUTED)) {
bNodeLink *link = socket->link;
/* Fix the case where the socket is actually converting the data. (see T71374)
* We only do the case of lossy conversion to float. */
if ((socket->type == SOCK_FLOAT) && (link->fromsock->type != link->tosock->type)) {
if (link->fromsock->type == SOCK_RGBA) {
- bNode *tmp = nodeAddStaticNode(NULL, localtree, SH_NODE_RGBTOBW);
- nodeAddLink(localtree, link->fromnode, link->fromsock, tmp, tmp->inputs.first);
- nodeAddLink(localtree, tmp, tmp->outputs.first, node, socket);
+ bNode *tmp = nodeAddStaticNode(nullptr, localtree, SH_NODE_RGBTOBW);
+ nodeAddLink(localtree,
+ link->fromnode,
+ link->fromsock,
+ tmp,
+ static_cast<bNodeSocket *>(tmp->inputs.first));
+ nodeAddLink(
+ localtree, tmp, static_cast<bNodeSocket *>(tmp->outputs.first), node, socket);
}
else if (link->fromsock->type == SOCK_VECTOR) {
- bNode *tmp = nodeAddStaticNode(NULL, localtree, SH_NODE_VECTOR_MATH);
+ bNode *tmp = nodeAddStaticNode(nullptr, localtree, SH_NODE_VECTOR_MATH);
tmp->custom1 = NODE_VECTOR_MATH_DOT_PRODUCT;
- bNodeSocket *dot_input1 = tmp->inputs.first;
- bNodeSocket *dot_input2 = dot_input1->next;
- bNodeSocketValueVector *input2_socket_value = dot_input2->default_value;
+ bNodeSocket *dot_input1 = static_cast<bNodeSocket *>(tmp->inputs.first);
+ bNodeSocket *dot_input2 = static_cast<bNodeSocket *>(dot_input1->next);
+ bNodeSocketValueVector *input2_socket_value = static_cast<bNodeSocketValueVector *>(
+ dot_input2->default_value);
copy_v3_fl(input2_socket_value->value, 1.0f / 3.0f);
nodeAddLink(localtree, link->fromnode, link->fromsock, tmp, dot_input1);
- nodeAddLink(localtree, tmp, tmp->outputs.last, node, socket);
+ nodeAddLink(
+ localtree, tmp, static_cast<bNodeSocket *>(tmp->outputs.last), node, socket);
}
}
continue;
@@ -440,22 +420,33 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
}
if (link_added) {
- ntreeUpdateTree(G.main, localtree);
+ BKE_ntree_update_main_tree(G.main, localtree, nullptr);
}
}
-static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
+static void ntree_shader_groups_remove_muted_links(bNodeTree *ntree)
{
- bNodeLink *link, *linkn, *tlink;
- bNode *node, *nextnode;
- bNodeTree *ngroup;
- LinkNode *group_interface_nodes = NULL;
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == NODE_GROUP) {
+ if (node->id != nullptr) {
+ ntree_shader_groups_remove_muted_links(reinterpret_cast<bNodeTree *>(node->id));
+ }
+ }
+ }
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
+ if (link->flag & NODE_LINK_MUTED) {
+ nodeRemLink(ntree, link);
+ }
+ }
+}
- ngroup = (bNodeTree *)gnode->id;
+static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
+{
+ LinkNode *group_interface_nodes = nullptr;
+ bNodeTree *ngroup = (bNodeTree *)gnode->id;
/* Add the nodes into the ntree */
- for (node = ngroup->nodes.first; node; node = nextnode) {
- nextnode = node->next;
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ngroup->nodes) {
/* Remove interface nodes.
* This also removes remaining links to and from interface nodes.
* We must delay removal since sockets will reference this node. see: T52092 */
@@ -471,25 +462,26 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
}
/* Save first and last link to iterate over flattened group links. */
- bNodeLink *glinks_first = ntree->links.last;
+ bNodeLink *glinks_first = static_cast<bNodeLink *>(ntree->links.last);
/* Add internal links to the ntree */
- for (link = ngroup->links.first; link; link = linkn) {
- linkn = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ngroup->links) {
BLI_remlink(&ngroup->links, link);
BLI_addtail(&ntree->links, link);
}
- bNodeLink *glinks_last = ntree->links.last;
+ bNodeLink *glinks_last = static_cast<bNodeLink *>(ntree->links.last);
/* restore external links to and from the gnode */
- if (glinks_first != NULL) {
+ if (glinks_first != nullptr) {
/* input links */
- for (link = glinks_first->next; link != glinks_last->next; link = link->next) {
+ for (bNodeLink *link = glinks_first->next; link != glinks_last->next; link = link->next) {
if (link->fromnode->type == NODE_GROUP_INPUT) {
const char *identifier = link->fromsock->identifier;
/* find external links to this input */
- for (tlink = ntree->links.first; tlink != glinks_first->next; tlink = tlink->next) {
+ for (bNodeLink *tlink = static_cast<bNodeLink *>(ntree->links.first);
+ tlink != glinks_first->next;
+ tlink = tlink->next) {
if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode, link->tosock);
}
@@ -497,13 +489,15 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
}
}
/* Also iterate over the new links to cover passthrough links. */
- glinks_last = ntree->links.last;
+ glinks_last = static_cast<bNodeLink *>(ntree->links.last);
/* output links */
- for (tlink = ntree->links.first; tlink != glinks_first->next; tlink = tlink->next) {
+ for (bNodeLink *tlink = static_cast<bNodeLink *>(ntree->links.first);
+ tlink != glinks_first->next;
+ tlink = tlink->next) {
if (tlink->fromnode == gnode) {
const char *identifier = tlink->fromsock->identifier;
/* find internal links to this output */
- for (link = glinks_first->next; link != glinks_last->next; link = link->next) {
+ for (bNodeLink *link = glinks_first->next; link != glinks_last->next; link = link->next) {
/* only use active output node */
if (link->tonode->type == NODE_GROUP_OUTPUT && (link->tonode->flag & NODE_DO_OUTPUT)) {
if (STREQ(link->tosock->identifier, identifier)) {
@@ -516,11 +510,11 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
}
while (group_interface_nodes) {
- node = BLI_linklist_pop(&group_interface_nodes);
+ bNode *node = static_cast<bNode *>(BLI_linklist_pop(&group_interface_nodes));
ntreeFreeLocalNode(ntree, node);
}
- ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_ntree_update_tag_all(ntree);
}
/* Flatten group to only have a simple single tree */
@@ -528,8 +522,9 @@ static void ntree_shader_groups_flatten(bNodeTree *localtree)
{
/* This is effectively recursive as the flattened groups will add
* nodes at the end of the list, which will also get evaluated. */
- for (bNode *node = localtree->nodes.first, *node_next; node; node = node_next) {
- if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id != NULL) {
+ for (bNode *node = static_cast<bNode *>(localtree->nodes.first), *node_next; node;
+ node = node_next) {
+ if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id != nullptr) {
flatten_group_do(localtree, node);
/* Continue even on new flattened nodes. */
node_next = node->next;
@@ -545,7 +540,7 @@ static void ntree_shader_groups_flatten(bNodeTree *localtree)
}
}
- ntreeUpdateTree(G.main, localtree);
+ BKE_ntree_update_main_tree(G.main, localtree, nullptr);
}
/* Check whether shader has a displacement.
@@ -560,20 +555,20 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
bNodeSocket **r_socket,
bNodeLink **r_link)
{
- if (output_node == NULL) {
+ if (output_node == nullptr) {
/* We can't have displacement without output node, apparently. */
return false;
}
/* Make sure sockets links pointers are correct. */
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
bNodeSocket *displacement = ntree_shader_node_find_input(output_node, "Displacement");
- if (displacement == NULL) {
+ if (displacement == nullptr) {
/* Non-cycles node is used as an output. */
return false;
}
- if ((displacement->link != NULL) && !(displacement->link->flag & NODE_LINK_MUTED)) {
+ if ((displacement->link != nullptr) && !(displacement->link->flag & NODE_LINK_MUTED)) {
*r_node = displacement->link->fromnode;
*r_socket = displacement->link->fromsock;
*r_link = displacement->link;
@@ -591,7 +586,7 @@ static void ntree_shader_relink_node_normal(bNodeTree *ntree,
* matching?
*/
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if (STREQ(sock->identifier, "Normal") && sock->link == NULL) {
+ if (STREQ(sock->identifier, "Normal") && sock->link == nullptr) {
/* It's a normal input and nothing is connected to it. */
nodeAddLink(ntree, node_from, socket_from, node, sock);
}
@@ -611,7 +606,7 @@ static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
bNode *node_from,
bNodeSocket *socket_from)
{
- for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node == node_from) {
/* Don't connect node itself! */
continue;
@@ -636,7 +631,7 @@ static void ntree_shader_bypass_bump_link(bNodeTree *ntree, bNode *bump_node, bN
fromnode = bump_normal_input->link->fromnode;
}
else {
- fromnode = nodeAddStaticNode(NULL, ntree, SH_NODE_NEW_GEOMETRY);
+ fromnode = nodeAddStaticNode(nullptr, ntree, SH_NODE_NEW_GEOMETRY);
fromsock = ntree_shader_node_find_output(fromnode, "Normal");
}
/* Bypass the bump node by creating a link between the previous and next node. */
@@ -654,7 +649,7 @@ static void ntree_shader_bypass_tagged_bump_nodes(bNodeTree *ntree)
ntree_shader_bypass_bump_link(ntree, node, link);
}
}
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
}
static bool ntree_branch_count_and_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
@@ -688,19 +683,19 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
int node_count = 1;
nodeChainIterBackwards(ntree, start_node, ntree_branch_count_and_tag_nodes, &node_count, 1);
/* Make a full copy of the branch */
- bNode **nodes_copy = MEM_mallocN(sizeof(bNode *) * node_count, __func__);
+ bNode **nodes_copy = static_cast<bNode **>(MEM_mallocN(sizeof(bNode *) * node_count, __func__));
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->tmp_flag >= 0) {
int id = node->tmp_flag;
- nodes_copy[id] = BKE_node_copy_ex(
- ntree, node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN, false);
+ nodes_copy[id] = blender::bke::node_copy(
+ ntree, *node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN, false);
nodes_copy[id]->tmp_flag = -2; /* Copy */
/* Make sure to clear all sockets links as they are invalid. */
LISTBASE_FOREACH (bNodeSocket *, sock, &nodes_copy[id]->inputs) {
- sock->link = NULL;
+ sock->link = nullptr;
}
LISTBASE_FOREACH (bNodeSocket *, sock, &nodes_copy[id]->outputs) {
- sock->link = NULL;
+ sock->link = nullptr;
}
}
}
@@ -733,13 +728,13 @@ static void ntree_shader_copy_branch_displacement(bNodeTree *ntree,
/* Replace displacement socket/node/link. */
bNode *tonode = displacement_link->tonode;
bNodeSocket *tosock = displacement_link->tosock;
- displacement_node = ntree_shader_copy_branch(ntree, displacement_node, NULL, 0);
+ displacement_node = ntree_shader_copy_branch(ntree, displacement_node, nullptr, 0);
displacement_socket = ntree_shader_node_find_output(displacement_node,
displacement_socket->identifier);
nodeRemLink(ntree, displacement_link);
nodeAddLink(ntree, displacement_node, displacement_socket, tonode, tosock);
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
}
/* Re-link displacement output to unconnected normal sockets via bump node.
@@ -773,11 +768,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
nodeRemLink(ntree, displacement_link);
/* Convert displacement vector to bump height. */
- bNode *dot_node = nodeAddStaticNode(NULL, ntree, SH_NODE_VECTOR_MATH);
- bNode *geo_node = nodeAddStaticNode(NULL, ntree, SH_NODE_NEW_GEOMETRY);
+ bNode *dot_node = nodeAddStaticNode(nullptr, ntree, SH_NODE_VECTOR_MATH);
+ bNode *geo_node = nodeAddStaticNode(nullptr, ntree, SH_NODE_NEW_GEOMETRY);
bNodeSocket *normal_socket = ntree_shader_node_find_output(geo_node, "Normal");
- bNodeSocket *dot_input1 = dot_node->inputs.first;
- bNodeSocket *dot_input2 = dot_input1->next;
+ bNodeSocket *dot_input1 = static_cast<bNodeSocket *>(dot_node->inputs.first);
+ bNodeSocket *dot_input2 = static_cast<bNodeSocket *>(dot_input1->next);
dot_node->custom1 = NODE_VECTOR_MATH_DOT_PRODUCT;
nodeAddLink(ntree, displacement_node, displacement_socket, dot_node, dot_input1);
@@ -788,11 +783,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
/* We can't connect displacement to normal directly, use bump node for that
* and hope that it gives good enough approximation.
*/
- bNode *bump_node = nodeAddStaticNode(NULL, ntree, SH_NODE_BUMP);
+ bNode *bump_node = nodeAddStaticNode(nullptr, ntree, SH_NODE_BUMP);
bNodeSocket *bump_input_socket = ntree_shader_node_find_input(bump_node, "Height");
bNodeSocket *bump_output_socket = ntree_shader_node_find_output(bump_node, "Normal");
- BLI_assert(bump_input_socket != NULL);
- BLI_assert(bump_output_socket != NULL);
+ BLI_assert(bump_input_socket != nullptr);
+ BLI_assert(bump_output_socket != nullptr);
/* Connect bump node to where displacement output was originally
* connected to.
*/
@@ -803,12 +798,12 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
geo_node->tmp_flag = -2;
bump_node->tmp_flag = -2;
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
/* Connect all free-standing Normal inputs and relink geometry/coordinate nodes. */
ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
/* We modified the tree, it needs to be updated now. */
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
}
static void node_tag_branch_as_derivative(bNode *node, int dx)
@@ -868,12 +863,12 @@ static bool ntree_shader_implicit_closure_cast(bNodeTree *ntree)
else if ((link->fromsock->type == SOCK_SHADER) && (link->tosock->type != SOCK_SHADER)) {
/* Meh. Not directly visible to the user. But better than nothing. */
fprintf(stderr, "Shader Nodetree Error: Invalid implicit socket conversion\n");
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
return false;
}
}
if (modified) {
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
}
return true;
}
@@ -1129,7 +1124,8 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
break;
}
- /* Manually add the link to the socket to avoid calling ntreeUpdateTree in the loop. */
+ /* Manually add the link to the socket to avoid calling
+ * BKE_ntree_update_main_tree(G.main, oop, nullptr. */
fromsock->link = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
BLI_assert(fromsock->link);
}
@@ -1145,23 +1141,23 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
nodeAddLink(
ntree, thickness_link->fromnode, thickness_link->fromsock, output_node, thickness_output);
}
- ntreeUpdateTree(G.main, ntree);
+ BKE_ntree_update_main_tree(G.main, ntree, nullptr);
MEM_freeN(nodes_copy);
}
-/* This one needs to work on a local tree. */
void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat)
{
bNodeTreeExec *exec;
bNode *output = ntreeShaderOutputNode(localtree, SHD_OUTPUT_EEVEE);
+ ntree_shader_groups_remove_muted_links(localtree);
ntree_shader_groups_expand_inputs(localtree);
ntree_shader_groups_flatten(localtree);
- if (output == NULL) {
+ if (output == nullptr) {
/* Search again, now including flattened nodes. */
output = ntreeShaderOutputNode(localtree, SHD_OUTPUT_EEVEE);
}
@@ -1186,7 +1182,6 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat)
nodeChainIterBackwards(localtree, node, ntree_shader_bump_branches, localtree, 0);
}
}
-
exec = ntreeShaderBeginExecTree(localtree);
ntreeExecGPUNodes(exec, mat, output);
LISTBASE_FOREACH (bNode *, node, &localtree->nodes) {
@@ -1201,19 +1196,17 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context,
bNodeTree *ntree,
bNodeInstanceKey parent_key)
{
- bNodeTreeExec *exec;
- bNode *node;
-
/* ensures only a single output node is enabled */
ntreeSetOutput(ntree);
/* common base initialization */
- exec = ntree_exec_begin(context, ntree, parent_key);
+ bNodeTreeExec *exec = ntree_exec_begin(context, ntree, parent_key);
/* allocate the thread stack listbase array */
- exec->threadstack = MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array");
+ exec->threadstack = static_cast<ListBase *>(
+ MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array"));
- for (node = exec->nodetree->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &exec->nodetree->nodes) {
node->need_exec = 1;
}
@@ -1236,8 +1229,8 @@ bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
exec = ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
- /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
- * which only store the ntree pointer. Should be fixed at some point!
+ /* XXX: this should not be necessary, but is still used for compositor/shader/texture nodes,
+ * which only store the `ntree` pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
@@ -1246,12 +1239,9 @@ bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
{
- bNodeThreadStack *nts;
- int a;
-
if (exec->threadstack) {
- for (a = 0; a < BLENDER_MAX_THREADS; a++) {
- for (nts = exec->threadstack[a].first; nts; nts = nts->next) {
+ for (int a = 0; a < BLENDER_MAX_THREADS; a++) {
+ LISTBASE_FOREACH (bNodeThreadStack *, nts, &exec->threadstack[a]) {
if (nts->stack) {
MEM_freeN(nts->stack);
}
@@ -1260,7 +1250,7 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
}
MEM_freeN(exec->threadstack);
- exec->threadstack = NULL;
+ exec->threadstack = nullptr;
}
ntree_exec_end(exec);
@@ -1274,6 +1264,6 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec)
ntreeShaderEndExecTree_internal(exec);
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
- ntree->execdata = NULL;
+ ntree->execdata = nullptr;
}
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.cc
index 1804bbcd22a..8ea690a426f 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.cc
@@ -23,14 +23,16 @@
#include "DNA_node_types.h"
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
+
+#include "NOD_socket_search_link.hh"
#include "node_exec.h"
bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "ShaderNodeTree")) {
- *r_disabled_hint = "Not a shader node tree";
+ *r_disabled_hint = TIP_("Not a shader node tree");
return false;
}
return true;
@@ -40,32 +42,32 @@ static bool sh_fn_poll_default(bNodeType *UNUSED(ntype),
bNodeTree *ntree,
const char **r_disabled_hint)
{
- if (!STREQ(ntree->idname, "ShaderNodeTree") && !STREQ(ntree->idname, "GeometryNodeTree")) {
- *r_disabled_hint = "Not a shader or geometry node tree";
+ if (!STR_ELEM(ntree->idname, "ShaderNodeTree", "GeometryNodeTree")) {
+ *r_disabled_hint = TIP_("Not a shader or geometry node tree");
return false;
}
return true;
}
-void sh_node_type_base(
- struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
+void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
{
- node_type_base(ntype, type, name, nclass, flag);
+ node_type_base(ntype, type, name, nclass);
ntype->poll = sh_node_poll_default;
ntype->insert_link = node_insert_link_default;
- ntype->update_internal_links = node_update_internal_links_default;
+ ntype->gather_link_search_ops = blender::nodes::search_link_ops_for_basic_node;
}
-void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
+void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
{
- sh_node_type_base(ntype, type, name, nclass, flag);
+ sh_node_type_base(ntype, type, name, nclass);
ntype->poll = sh_fn_poll_default;
+ ntype->gather_link_search_ops = blender::nodes::search_link_ops_for_basic_node;
}
/* ****** */
-void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
+static void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
{
const float *from = ns->vec;
@@ -108,11 +110,11 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
{
memset(gs, 0, sizeof(*gs));
- if (ns == NULL) {
- /* node_get_stack() will generate NULL bNodeStack pointers
+ if (ns == nullptr) {
+ /* node_get_stack() will generate nullptr bNodeStack pointers
* for unknown/unsupported types of sockets. */
zero_v4(gs->vec);
- gs->link = NULL;
+ gs->link = nullptr;
gs->type = GPU_NONE;
gs->hasinput = false;
gs->hasoutput = false;
@@ -120,7 +122,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
}
else {
nodestack_get_vec(gs->vec, type, ns);
- gs->link = ns->data;
+ gs->link = (GPUNodeLink *)ns->data;
if (type == SOCK_FLOAT) {
gs->type = GPU_FLOAT;
@@ -160,11 +162,9 @@ void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs)
static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeStack **ns)
{
- bNodeSocket *sock;
int i;
-
- for (sock = sockets->first, i = 0; sock; sock = sock->next, i++) {
- node_gpu_stack_from_data(&gs[i], sock->type, ns[i]);
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, i) {
+ node_gpu_stack_from_data(&gs[i], socket->type, ns[i]);
}
gs[i].end = true;
@@ -172,10 +172,8 @@ static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeS
static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
{
- bNodeSocket *sock;
int i;
-
- for (sock = sockets->first, i = 0; sock; sock = sock->next, i++) {
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, i) {
node_data_from_gpu_stack(ns[i], &gs[i]);
}
}
@@ -183,14 +181,14 @@ static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNode
bNode *nodeGetActiveTexture(bNodeTree *ntree)
{
/* this is the node we texture paint and draw in textured draw */
- bNode *node, *tnode, *inactivenode = NULL, *activetexnode = NULL, *activegroup = NULL;
+ bNode *inactivenode = nullptr, *activetexnode = nullptr, *activegroup = nullptr;
bool hasgroup = false;
if (!ntree) {
- return NULL;
+ return nullptr;
}
- for (node = ntree->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_ACTIVE_TEXTURE) {
activetexnode = node;
/* if active we can return immediately */
@@ -213,7 +211,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
/* first, check active group for textures */
if (activegroup) {
- tnode = nodeGetActiveTexture((bNodeTree *)activegroup->id);
+ bNode *tnode = nodeGetActiveTexture((bNodeTree *)activegroup->id);
/* active node takes priority, so ignore any other possible nodes here */
if (tnode) {
return tnode;
@@ -226,9 +224,9 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
if (hasgroup) {
/* node active texture node in this tree, look inside groups */
- for (node = ntree->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == NODE_GROUP) {
- tnode = nodeGetActiveTexture((bNodeTree *)node->id);
+ bNode *tnode = nodeGetActiveTexture((bNodeTree *)node->id);
if (tnode && ((tnode->flag & NODE_ACTIVE_TEXTURE) || !inactivenode)) {
return tnode;
}
@@ -258,7 +256,7 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node
do_it = false;
/* for groups, only execute outputs for edited group */
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
- if ((output_node != NULL) && (node == output_node)) {
+ if ((output_node != nullptr) && (node == output_node)) {
do_it = true;
}
}
@@ -282,11 +280,11 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node
void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
{
if (node->branch_tag == 1) {
- /* Add one time the value fo derivative to the input vector. */
+ /* Add one time the value for derivative to the input vector. */
GPU_link(mat, "dfdx_v3", *link, link);
}
else if (node->branch_tag == 2) {
- /* Add one time the value fo derivative to the input vector. */
+ /* Add one time the value for derivative to the input vector. */
GPU_link(mat, "dfdy_v3", *link, link);
}
else {
@@ -308,7 +306,7 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *UNUSED(out))
{
- NodeTexBase *base = node->storage;
+ NodeTexBase *base = (NodeTexBase *)node->storage;
TexMapping *texmap = &base->tex_mapping;
float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0;
float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0;
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.hh
index c647b86a19a..5a5b4f613f3 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.hh
@@ -23,29 +23,21 @@
#pragma once
-#include <float.h>
-#include <math.h>
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_ID.h"
-#include "DNA_color_types.h"
-#include "DNA_customdata_types.h"
-#include "DNA_image_types.h"
-#include "DNA_material_types.h"
-#include "DNA_node_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
+#include <cfloat>
+#include <cmath>
+#include <cstring>
#include "BLI_blenlib.h"
+#include "BLI_color.hh"
#include "BLI_math.h"
#include "BLI_math_base_safe.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLT_translation.h"
+
#include "BKE_colorband.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
@@ -55,53 +47,46 @@
#include "BKE_node.h"
#include "BKE_texture.h"
-#include "NOD_shader.h"
-#include "node_util.h"
-
-#include "BLT_translation.h"
-
-#include "IMB_colormanagement.h"
+#include "DNA_ID.h"
+#include "DNA_color_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
-#include "RE_pipeline.h"
-#include "RE_texture.h"
+#include "FN_multi_function_builder.hh"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "GPU_uniform_buffer.h"
-#ifdef __cplusplus
-# include "FN_multi_function_builder.hh"
+#include "IMB_colormanagement.h"
-# include "NOD_multi_function.hh"
-# include "NOD_socket_declarations.hh"
+#include "MEM_guardedalloc.h"
-# include "BLI_color.hh"
-# include "BLI_float3.hh"
+#include "NOD_multi_function.hh"
+#include "NOD_shader.h"
+#include "NOD_socket_declarations.hh"
+#include "node_util.h"
-extern "C" {
-#endif
+#include "RE_pipeline.h"
+#include "RE_texture.h"
bool sh_node_poll_default(struct bNodeType *ntype,
struct bNodeTree *ntree,
const char **r_disabled_hint);
-void sh_node_type_base(
- struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
-void sh_fn_node_type_base(
- struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
+void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass);
+void sh_fn_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass);
/* ********* exec data struct, remains internal *********** */
-typedef struct ShaderCallData {
- /* Empty for now, may be reused if we convert shader to texture nodes. */
- int dummy;
-} ShaderCallData;
-
-typedef struct XYZ_to_RGB /* Transposed #imbuf_xyz_to_rgb, passed as 3x vec3. */
+struct XYZ_to_RGB /* Transposed #imbuf_xyz_to_rgb, passed as 3x vec3. */
{
float r[3], g[3], b[3];
-} XYZ_to_RGB;
-
-void nodestack_get_vec(float *in, short type_in, bNodeStack *ns);
+};
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, struct bNodeStack *ns);
void node_data_from_gpu_stack(struct bNodeStack *ns, struct GPUNodeStack *gs);
@@ -120,7 +105,3 @@ void ntreeExecGPUNodes(struct bNodeTreeExec *exec,
struct GPUMaterial *mat,
struct bNode *output_node);
void get_XYZ_to_RGB_for_gpu(XYZ_to_RGB *data);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/nodes/shader/nodes/node_shader_add_shader.c b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc
index 12c138ac9d5..73d5c12ce96 100644
--- a/source/blender/nodes/shader/nodes/node_shader_add_shader.c
+++ b/source/blender/nodes/shader/nodes/node_shader_add_shader.cc
@@ -17,20 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_add_shader_cc {
-static bNodeSocketTemplate sh_node_add_shader_in[] = {
- {SOCK_SHADER, N_("Shader")},
- {SOCK_SHADER, N_("Shader")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_add_shader_out[] = {
- {SOCK_SHADER, N_("Shader")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Shader>(N_("Shader"));
+ b.add_input<decl::Shader>(N_("Shader"), "Shader_001");
+ b.add_output<decl::Shader>(N_("Shader"));
+}
static int node_shader_gpu_add_shader(GPUMaterial *mat,
bNode *node,
@@ -41,16 +37,18 @@ static int node_shader_gpu_add_shader(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_add_shader", in, out);
}
+} // namespace blender::nodes::node_shader_add_shader_cc
+
/* node type definition */
-void register_node_type_sh_add_shader(void)
+void register_node_type_sh_add_shader()
{
+ namespace file_ns = blender::nodes::node_shader_add_shader_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_ADD_SHADER, "Add Shader", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_add_shader_in, sh_node_add_shader_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_add_shader);
+ sh_node_type_base(&ntype, SH_NODE_ADD_SHADER, "Add Shader", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_add_shader);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc
index abe80ebcefb..9c64594aab8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
+++ b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.cc
@@ -17,22 +17,30 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_ambient_occlusion_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_ambient_occlusion_cc {
-static bNodeSocketTemplate sh_node_ambient_occlusion_out[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("AO"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Distance")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).min(-1.0f).max(1.0f).hide_value();
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("AO"));
+}
+
+static void node_shader_buts_ambient_occlusion(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "samples", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "inside", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "only_local", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
static int node_shader_gpu_ambient_occlusion(GPUMaterial *mat,
bNode *node,
@@ -64,16 +72,20 @@ static void node_shader_init_ambient_occlusion(bNodeTree *UNUSED(ntree), bNode *
node->custom2 = 0;
}
+} // namespace blender::nodes::node_shader_ambient_occlusion_cc
+
/* node type definition */
-void register_node_type_sh_ambient_occlusion(void)
+void register_node_type_sh_ambient_occlusion()
{
+ namespace file_ns = blender::nodes::node_shader_ambient_occlusion_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_AMBIENT_OCCLUSION, "Ambient Occlusion", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, sh_node_ambient_occlusion_in, sh_node_ambient_occlusion_out);
- node_type_init(&ntype, node_shader_init_ambient_occlusion);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_ambient_occlusion);
+ sh_node_type_base(&ntype, SH_NODE_AMBIENT_OCCLUSION, "Ambient Occlusion", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_ambient_occlusion;
+ node_type_init(&ntype, file_ns::node_shader_init_ambient_occlusion);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_ambient_occlusion);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.cc
index 9b3122e38e0..cf1b49ba29c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.c
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.cc
@@ -17,21 +17,30 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_attribute_out[] = {
- {SOCK_RGBA, N_("Color")},
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_FACTOR},
- {SOCK_FLOAT, N_("Alpha"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_FACTOR},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_attribute_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Vector>(N_("Vector"));
+ b.add_output<decl::Float>(N_("Fac"));
+ b.add_output<decl::Float>(N_("Alpha"));
+}
+
+static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "attribute_type", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Type"), ICON_NONE);
+ uiItemR(layout, ptr, "attribute_name", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Name"), ICON_NONE);
+}
static void node_shader_init_attribute(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderAttribute *attr = MEM_callocN(sizeof(NodeShaderAttribute), "NodeShaderAttribute");
+ NodeShaderAttribute *attr = MEM_cnew<NodeShaderAttribute>("NodeShaderAttribute");
node->storage = attr;
}
@@ -41,7 +50,7 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- NodeShaderAttribute *attr = node->storage;
+ NodeShaderAttribute *attr = static_cast<NodeShaderAttribute *>(node->storage);
bool is_varying = attr->type == SHD_ATTRIBUTE_GEOMETRY;
if (GPU_material_is_volume_shader(mat) && is_varying) {
@@ -73,25 +82,30 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
- /* for each output. */
- for (int i = 0; sh_node_attribute_out[i].type != -1; i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->outputs, i) {
node_shader_gpu_bump_tex_coord(mat, node, &out[i].link);
}
return 1;
}
+} // namespace blender::nodes::node_shader_attribute_cc
+
/* node type definition */
-void register_node_type_sh_attribute(void)
+void register_node_type_sh_attribute()
{
+ namespace file_ns = blender::nodes::node_shader_attribute_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_ATTRIBUTE, "Attribute", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_attribute_out);
- node_type_init(&ntype, node_shader_init_attribute);
+ sh_node_type_base(&ntype, SH_NODE_ATTRIBUTE, "Attribute", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_attribute;
+ node_type_init(&ntype, file_ns::node_shader_init_attribute);
node_type_storage(
&ntype, "NodeShaderAttribute", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_attribute);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_attribute);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_background.c b/source/blender/nodes/shader/nodes/node_shader_background.cc
index 4301a9f716f..3b9e71cf842 100644
--- a/source/blender/nodes/shader/nodes/node_shader_background.c
+++ b/source/blender/nodes/shader/nodes/node_shader_background.cc
@@ -17,21 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_background_cc {
-static bNodeSocketTemplate sh_node_background_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_background_out[] = {
- {SOCK_SHADER, N_("Background")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Strength")).default_value(1.0f).min(0.0f).max(1000000.0f);
+ b.add_output<decl::Shader>(N_("Background"));
+}
static int node_shader_gpu_background(GPUMaterial *mat,
bNode *node,
@@ -42,16 +37,18 @@ static int node_shader_gpu_background(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_background", in, out);
}
+} // namespace blender::nodes::node_shader_background_cc
+
/* node type definition */
-void register_node_type_sh_background(void)
+void register_node_type_sh_background()
{
+ namespace file_ns = blender::nodes::node_shader_background_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_background_in, sh_node_background_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_background);
+ sh_node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_background);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bevel.c b/source/blender/nodes/shader/nodes/node_shader_bevel.cc
index d6bdda30e94..dfde18d8e2a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bevel.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bevel.cc
@@ -17,20 +17,24 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_bevel_in[] = {
- {SOCK_FLOAT, N_("Radius"), 0.05f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_bevel_cc {
-static bNodeSocketTemplate sh_node_bevel_out[] = {
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Radius")).default_value(0.05f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Vector>(N_("Normal"));
+}
+
+static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "samples", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
static void node_shader_init_bevel(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -50,16 +54,20 @@ static int gpu_shader_bevel(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_bevel", in, out);
}
+} // namespace blender::nodes::node_shader_bevel_cc
+
/* node type definition */
-void register_node_type_sh_bevel(void)
+void register_node_type_sh_bevel()
{
+ namespace file_ns = blender::nodes::node_shader_bevel_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BEVEL, "Bevel", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, sh_node_bevel_in, sh_node_bevel_out);
- node_type_init(&ntype, node_shader_init_bevel);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, gpu_shader_bevel);
+ sh_node_type_base(&ntype, SH_NODE_BEVEL, "Bevel", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_bevel;
+ node_type_init(&ntype, file_ns::node_shader_init_bevel);
+ node_type_gpu(&ntype, file_ns::gpu_shader_bevel);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.cc
index 95c35affc27..85e2ed08403 100644
--- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.cc
@@ -17,18 +17,15 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Blackbody ******************** */
-static bNodeSocketTemplate sh_node_blackbody_in[] = {
- {SOCK_FLOAT, N_("Temperature"), 1500.0f, 0.0f, 0.0f, 0.0f, 800.0f, 12000.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_blackbody_cc {
-static bNodeSocketTemplate sh_node_blackbody_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Temperature")).default_value(1500.0f).min(800.0f).max(12000.0f);
+ b.add_output<decl::Color>(N_("Color"));
+}
static int node_shader_gpu_blackbody(GPUMaterial *mat,
bNode *node,
@@ -37,7 +34,7 @@ static int node_shader_gpu_blackbody(GPUMaterial *mat,
GPUNodeStack *out)
{
const int size = CM_TABLE + 1;
- float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
+ float *data = static_cast<float *>(MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"));
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
@@ -47,17 +44,19 @@ static int node_shader_gpu_blackbody(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_constant(&layer));
}
+} // namespace blender::nodes::node_shader_blackbody_cc
+
/* node type definition */
-void register_node_type_sh_blackbody(void)
+void register_node_type_sh_blackbody()
{
+ namespace file_ns = blender::nodes::node_shader_blackbody_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BLACKBODY, "Blackbody", NODE_CLASS_CONVERTER, 0);
+ sh_node_type_base(&ntype, SH_NODE_BLACKBODY, "Blackbody", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_socket_templates(&ntype, sh_node_blackbody_in, sh_node_blackbody_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_blackbody);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_blackbody);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_brightness.c b/source/blender/nodes/shader/nodes/node_shader_brightness.cc
index 4f375c666de..66bfaba2785 100644
--- a/source/blender/nodes/shader/nodes/node_shader_brightness.c
+++ b/source/blender/nodes/shader/nodes/node_shader_brightness.cc
@@ -17,21 +17,17 @@
* All rights reserved.
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Bright and contrast ******************** */
+namespace blender::nodes::node_shader_brightness_cc {
-static bNodeSocketTemplate sh_node_brightcontrast_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f},
- {SOCK_FLOAT, N_("Bright"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Contrast"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_brightcontrast_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Bright")).default_value(0.0f).min(-100.0f).max(100.0f);
+ b.add_input<decl::Float>(N_("Contrast")).default_value(0.0f).min(-100.0f).max(100.0f);
+ b.add_output<decl::Color>(N_("Color"));
+}
static int gpu_shader_brightcontrast(GPUMaterial *mat,
bNode *node,
@@ -42,15 +38,17 @@ static int gpu_shader_brightcontrast(GPUMaterial *mat,
return GPU_stack_link(mat, node, "brightness_contrast", in, out);
}
-void register_node_type_sh_brightcontrast(void)
+} // namespace blender::nodes::node_shader_brightness_cc
+
+void register_node_type_sh_brightcontrast()
{
+ namespace file_ns = blender::nodes::node_shader_brightness_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
- node_type_socket_templates(&ntype, sh_node_brightcontrast_in, sh_node_brightcontrast_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, gpu_shader_brightcontrast);
+ sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_brightcontrast);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
deleted file mode 100644
index 7c080337838..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Anisotropy"), 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
- {SOCK_FLOAT, N_("Rotation"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_VECTOR, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_anisotropic_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
-
-static void node_shader_init_anisotropic(bNodeTree *UNUSED(ntree), bNode *node)
-{
- node->custom1 = SHD_GLOSSY_GGX;
-}
-
-static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- if (!in[4].link) {
- GPU_link(mat, "world_normals_get", &in[4].link);
- }
-
- GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
-
- float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
-
- GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out);
-
- GPU_stack_eval_link(
- mat, node, "node_bsdf_anisotropic_eval", in, out, GPU_constant(&use_multi_scatter));
-
- return true;
-}
-
-/* node type definition */
-void register_node_type_sh_bsdf_anisotropic(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_anisotropic_in, sh_node_bsdf_anisotropic_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_anisotropic);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_anisotropic);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
new file mode 100644
index 00000000000..3f0749ab2af
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc
@@ -0,0 +1,96 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_bsdf_anisotropic_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Anisotropy")).default_value(0.5f).min(-1.0f).max(1.0f);
+ b.add_input<decl::Float>(N_("Rotation"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Vector>(N_("Tangent")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+static void node_shader_init_anisotropic(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_GLOSSY_GGX;
+}
+
+static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ if (!in[4].link) {
+ GPU_link(mat, "world_normals_get", &in[4].link);
+ }
+
+ GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
+
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
+ return GPU_stack_link(mat,
+ node,
+ "node_bsdf_anisotropic",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ GPU_constant(&node->ssr_id));
+}
+
+} // namespace blender::nodes::node_shader_bsdf_anisotropic_cc
+
+/* node type definition */
+void register_node_type_sh_bsdf_anisotropic()
+{
+ namespace file_ns = blender::nodes::node_shader_bsdf_anisotropic_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_anisotropic;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, file_ns::node_shader_init_anisotropic);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_anisotropic);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
index 3aa3b70025e..5848ca76cdd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.cc
@@ -17,22 +17,21 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_diffuse_cc {
-static bNodeSocketTemplate sh_node_bsdf_diffuse_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_diffuse_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat,
bNode *node,
@@ -46,21 +45,22 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
- return GPU_stack_eval_link(mat, node, "node_bsdf_diffuse_eval", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_diffuse_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_diffuse(void)
+void register_node_type_sh_bsdf_diffuse()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_diffuse_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_diffuse_in, sh_node_bsdf_diffuse_out);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_diffuse);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_diffuse);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
deleted file mode 100644
index e164e32723e..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_bsdf_glass_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_glass_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
-
-static void node_shader_init_glass(bNodeTree *UNUSED(ntree), bNode *node)
-{
- node->custom1 = SHD_GLOSSY_BECKMANN;
-}
-
-static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- if (!in[3].link) {
- GPU_link(mat, "world_normals_get", &in[3].link);
- }
-
- if (node->custom1 == SHD_GLOSSY_SHARP) {
- GPU_link(mat, "set_value_zero", &in[1].link);
- }
-
- GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT);
-
- float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
-
- GPUNodeLink *reflection_weight;
- GPUNodeLink *refraction_weight;
-
- GPU_stack_link(mat,
- node,
- "node_bsdf_glass",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- &reflection_weight,
- &refraction_weight);
-
- return GPU_stack_eval_link(mat,
- node,
- "node_bsdf_glass_eval",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- reflection_weight,
- refraction_weight);
-}
-
-/* node type definition */
-void register_node_type_sh_bsdf_glass(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_glass_in, sh_node_bsdf_glass_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_glass);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_glass);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
new file mode 100644
index 00000000000..47d4b87198b
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc
@@ -0,0 +1,85 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_bsdf_glass_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_init_glass(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_GLOSSY_BECKMANN;
+}
+
+static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ if (!in[3].link) {
+ GPU_link(mat, "world_normals_get", &in[3].link);
+ }
+
+ if (node->custom1 == SHD_GLOSSY_SHARP) {
+ GPU_link(mat, "set_value_zero", &in[1].link);
+ }
+
+ GPU_material_flag_set(mat, (eGPUMatFlag)(GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT));
+
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
+ return GPU_stack_link(mat,
+ node,
+ "node_bsdf_glass",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ GPU_constant(&node->ssr_id));
+}
+
+} // namespace blender::nodes::node_shader_bsdf_glass_cc
+
+/* node type definition */
+void register_node_type_sh_bsdf_glass()
+{
+ namespace file_ns = blender::nodes::node_shader_bsdf_glass_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, file_ns::node_shader_init_glass);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_glass);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
index e234dafb98e..03a3e634f56 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc
@@ -17,22 +17,21 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_glossy_cc {
-static bNodeSocketTemplate sh_node_bsdf_glossy_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_glossy_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static void node_shader_init_glossy(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -57,22 +56,29 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
- GPU_stack_link(mat, node, "node_bsdf_glossy", in, out);
- return GPU_stack_eval_link(
- mat, node, "node_bsdf_glossy_eval", in, out, GPU_constant(&use_multi_scatter));
+ return GPU_stack_link(mat,
+ node,
+ "node_bsdf_glossy",
+ in,
+ out,
+ GPU_constant(&use_multi_scatter),
+ GPU_constant(&node->ssr_id));
}
+} // namespace blender::nodes::node_shader_bsdf_glossy_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_glossy(void)
+void register_node_type_sh_bsdf_glossy()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_glossy_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_glossy_in, sh_node_bsdf_glossy_out);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_glossy);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_glossy);
+ node_type_init(&ntype, file_ns::node_shader_init_glossy);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_glossy);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc
index 1f07cb1d202..3be2bd22f60 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair.cc
@@ -17,24 +17,39 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_bsdf_hair_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Offset"), 0.0f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE},
- {SOCK_FLOAT, N_("RoughnessU"), 0.1f, 0.1f, 0.1f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("RoughnessV"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_bsdf_hair_cc {
-static bNodeSocketTemplate sh_node_bsdf_hair_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Offset"))
+ .default_value(0.0f)
+ .min(-M_PI_2)
+ .max(M_PI_2)
+ .subtype(PROP_ANGLE);
+ b.add_input<decl::Float>(N_("RoughnessU"))
+ .default_value(0.1f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("RoughnessV"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Tangent")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "component", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static int node_shader_gpu_bsdf_hair(GPUMaterial *mat,
bNode *node,
@@ -45,17 +60,20 @@ static int node_shader_gpu_bsdf_hair(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_bsdf_hair", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_hair_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_hair(void)
+void register_node_type_sh_bsdf_hair()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_hair_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR, "Hair BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_hair_in, sh_node_bsdf_hair_out);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR, "Hair BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_hair;
node_type_size(&ntype, 150, 60, 200);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_hair);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_hair);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
deleted file mode 100644
index d9bcbbcd7a4..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2018 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-/* Color, melanin and absorption coefficient default to approximately same brownish hair. */
-static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = {
- {SOCK_RGBA, N_("Color"), 0.017513f, 0.005763f, 0.002059f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Melanin"), 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Melanin Redness"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Absorption Coefficient"), 0.245531f, 0.52f, 1.365f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT,
- N_("Offset"),
- 2.0f * ((float)M_PI) / 180.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- -M_PI_2,
- M_PI_2,
- PROP_ANGLE},
- {SOCK_FLOAT, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_hair_principled_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
-
-/* Initialize the custom Parametrization property to Color. */
-static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
-{
- node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE;
-}
-
-/* Triggers (in)visibility of some sockets when changing Parametrization. */
-static void node_shader_update_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
-{
- bNodeSocket *sock;
- int parametrization = node->custom1;
-
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (STREQ(sock->name, "Color")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_REFLECTANCE) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- else if (STREQ(sock->name, "Melanin")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- else if (STREQ(sock->name, "Melanin Redness")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- else if (STREQ(sock->name, "Tint")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- else if (STREQ(sock->name, "Absorption Coefficient")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- else if (STREQ(sock->name, "Random Color")) {
- if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- }
-}
-
-/* node type definition */
-void register_node_type_sh_bsdf_hair_principled(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(
- &ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(
- &ntype, sh_node_bsdf_hair_principled_in, sh_node_bsdf_hair_principled_out);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, node_shader_init_hair_principled);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_update(&ntype, node_shader_update_hair_principled);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc
new file mode 100644
index 00000000000..7062888b5fb
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.cc
@@ -0,0 +1,145 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_bsdf_hair_principled_cc {
+
+/* Color, melanin and absorption coefficient default to approximately same brownish hair. */
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.017513f, 0.005763f, 0.002059f, 1.0f});
+ b.add_input<decl::Float>(N_("Melanin"))
+ .default_value(0.8f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Melanin Redness"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Tint")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Vector>(N_("Absorption Coefficient"))
+ .default_value({0.245531f, 0.52f, 1.365f})
+ .min(0.0f)
+ .max(1000.0f);
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.3f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Radial Roughness"))
+ .default_value(0.3f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Coat"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.55f).min(0.0f).max(1000.0f).subtype(
+ PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Offset"))
+ .default_value(2.0f * ((float)M_PI) / 180.0f)
+ .min(-M_PI_2)
+ .max(M_PI_2)
+ .subtype(PROP_ANGLE);
+ b.add_input<decl::Float>(N_("Random Color"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Random Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Random")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_buts_principled_hair(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "parametrization", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+/* Initialize the custom Parametrization property to Color. */
+static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE;
+}
+
+/* Triggers (in)visibility of some sockets when changing Parametrization. */
+static void node_shader_update_hair_principled(bNodeTree *ntree, bNode *node)
+{
+ int parametrization = node->custom1;
+
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+ if (STREQ(sock->name, "Color")) {
+ nodeSetSocketAvailability(ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_REFLECTANCE);
+ }
+ else if (STREQ(sock->name, "Melanin")) {
+ nodeSetSocketAvailability(
+ ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
+ }
+ else if (STREQ(sock->name, "Melanin Redness")) {
+ nodeSetSocketAvailability(
+ ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
+ }
+ else if (STREQ(sock->name, "Tint")) {
+ nodeSetSocketAvailability(
+ ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
+ }
+ else if (STREQ(sock->name, "Absorption Coefficient")) {
+ nodeSetSocketAvailability(
+ ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION);
+ }
+ else if (STREQ(sock->name, "Random Color")) {
+ nodeSetSocketAvailability(
+ ntree, sock, parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
+ }
+ }
+}
+
+} // namespace blender::nodes::node_shader_bsdf_hair_principled_cc
+
+/* node type definition */
+void register_node_type_sh_bsdf_hair_principled()
+{
+ namespace file_ns = blender::nodes::node_shader_bsdf_hair_principled_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(
+ &ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_principled_hair;
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_init(&ntype, file_ns::node_shader_init_hair_principled);
+ node_type_update(&ntype, file_ns::node_shader_update_hair_principled);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
deleted file mode 100644
index 5fbf66d5a68..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_bsdf_principled_in[] = {
- {SOCK_RGBA, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Subsurface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR,
- N_("Subsurface Radius"),
- 1.0f,
- 0.2f,
- 0.1f,
- 0.0f,
- 0.0f,
- 100.0f,
- PROP_NONE,
- SOCK_COMPACT},
- {SOCK_RGBA, N_("Subsurface Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Subsurface IOR"), 1.4f, 0.0f, 0.0f, 0.0f, 1.01f, 3.8f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Subsurface Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Specular Tint"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Anisotropic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Anisotropic Rotation"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Sheen"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Sheen Tint"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Clearcoat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Clearcoat Roughness"), 0.03f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Transmission Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Emission"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Emission Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
- {SOCK_FLOAT, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_VECTOR,
- N_("Clearcoat Normal"),
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- -1.0f,
- 1.0f,
- PROP_NONE,
- SOCK_HIDE_VALUE},
- {SOCK_VECTOR, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_principled_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
-
-static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
-{
- node->custom1 = SHD_GLOSSY_GGX;
- node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
-}
-
-#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
-#define socket_not_one(sock) \
- (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f))
-
-static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- /* Normals */
- if (!in[22].link) {
- GPU_link(mat, "world_normals_get", &in[22].link);
- }
-
- /* Clearcoat Normals */
- if (!in[23].link) {
- GPU_link(mat, "world_normals_get", &in[23].link);
- }
-
-#if 0 /* Not used at the moment. */
- /* Tangents */
- if (!in[24].link) {
- GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
- GPU_link(mat, "tangent_orco_z", orco, &in[24].link);
- GPU_link(mat, "node_tangent", in[24].link, &in[24].link);
- }
-#endif
-
- bool use_diffuse = socket_not_one(6) && socket_not_one(17);
- bool use_subsurf = socket_not_zero(1) && use_diffuse;
- bool use_refract = socket_not_one(6) && socket_not_zero(17);
- bool use_transparency = socket_not_one(21);
- // bool use_clear = socket_not_zero(14);
-
- uint flag = GPU_MATFLAG_GLOSSY;
- if (use_diffuse) {
- flag |= GPU_MATFLAG_DIFFUSE;
- }
- if (use_refract) {
- flag |= GPU_MATFLAG_REFRACT;
- }
- if (use_subsurf) {
- flag |= GPU_MATFLAG_SUBSURFACE;
- }
- if (use_transparency) {
- flag |= GPU_MATFLAG_TRANSPARENT;
- }
-
- float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
-
- GPU_material_flag_set(mat, flag);
-
- GPUNodeLink *diffuse_weight, *specular_weight, *glass_reflection_weight,
- *glass_transmission_weight, *clearcoat_weight;
-
- GPU_stack_link(mat,
- node,
- "node_bsdf_principled",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- &diffuse_weight,
- &specular_weight,
- &glass_reflection_weight,
- &glass_transmission_weight,
- &clearcoat_weight);
-
- return GPU_stack_eval_link(mat,
- node,
- "node_bsdf_principled_eval",
- in,
- out,
- GPU_constant(&use_multi_scatter),
- diffuse_weight,
- specular_weight,
- glass_reflection_weight,
- glass_transmission_weight,
- clearcoat_weight);
-}
-
-static void node_shader_update_principled(bNodeTree *UNUSED(ntree), bNode *node)
-{
- bNodeSocket *sock;
- int distribution = node->custom1;
-
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (STREQ(sock->name, "Transmission Roughness")) {
- if (distribution == SHD_GLOSSY_GGX) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- }
-}
-
-/* node type definition */
-void register_node_type_sh_bsdf_principled(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_principled_in, sh_node_bsdf_principled_out);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, node_shader_init_principled);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_principled);
- node_type_update(&ntype, node_shader_update_principled);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
new file mode 100644
index 00000000000..4c378d9bc09
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
@@ -0,0 +1,259 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_bsdf_principled_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Base Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Subsurface"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Subsurface Radius"))
+ .default_value({1.0f, 0.2f, 0.1f})
+ .min(0.0f)
+ .max(100.0f)
+ .compact();
+ b.add_input<decl::Color>(N_("Subsurface Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Subsurface IOR"))
+ .default_value(1.4f)
+ .min(1.01f)
+ .max(3.8f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Subsurface Anisotropy"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Metallic"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Specular"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Specular Tint"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Anisotropic"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Anisotropic Rotation"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Sheen"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Sheen Tint"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Clearcoat"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Clearcoat Roughness"))
+ .default_value(0.03f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Transmission"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Transmission Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Emission")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Emission Strength")).default_value(1.0).min(0.0f).max(1000000.0f);
+ b.add_input<decl::Float>(N_("Alpha"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Vector>(N_("Clearcoat Normal")).hide_value();
+ b.add_input<decl::Vector>(N_("Tangent")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "subsurface_method", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_GLOSSY_GGX;
+ node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
+}
+
+#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
+#define socket_not_one(sock) \
+ (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f))
+
+static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ GPUNodeLink *sss_scale;
+
+ /* Normals */
+ if (!in[22].link) {
+ GPU_link(mat, "world_normals_get", &in[22].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[23].link) {
+ GPU_link(mat, "world_normals_get", &in[23].link);
+ }
+
+#if 0 /* Not used at the moment. */
+ /* Tangents */
+ if (!in[24].link) {
+ GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+ GPU_link(mat, "tangent_orco_z", orco, &in[24].link);
+ GPU_link(mat,
+ "node_tangent",
+ GPU_builtin(GPU_WORLD_NORMAL),
+ in[24].link,
+ GPU_builtin(GPU_OBJECT_MATRIX),
+ &in[24].link);
+ }
+#endif
+
+ bool use_diffuse = socket_not_one(6) && socket_not_one(17);
+ bool use_subsurf = socket_not_zero(1) && use_diffuse && node->sss_id > 0;
+ bool use_refract = socket_not_one(6) && socket_not_zero(17);
+ bool use_clear = socket_not_zero(14);
+
+ /* SSS Profile */
+ if (use_subsurf) {
+ bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
+ bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
+ /* For some reason it seems that the socket value is in ARGB format. */
+ GPU_material_sss_profile_create(mat, &socket_data->value[1]);
+ }
+
+ if (in[2].link) {
+ sss_scale = in[2].link;
+ }
+ else {
+ GPU_link(mat, "set_rgb_one", &sss_scale);
+ }
+
+ uint flag = GPU_MATFLAG_GLOSSY;
+ if (use_diffuse) {
+ flag |= GPU_MATFLAG_DIFFUSE;
+ }
+ if (use_refract) {
+ flag |= GPU_MATFLAG_REFRACT;
+ }
+ if (use_subsurf) {
+ flag |= GPU_MATFLAG_SSS;
+ }
+
+ float f_use_diffuse = use_diffuse ? 1.0f : 0.0f;
+ float f_use_clearcoat = use_clear ? 1.0f : 0.0f;
+ float f_use_refraction = use_refract ? 1.0f : 0.0f;
+ float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
+
+ GPU_material_flag_set(mat, (eGPUMatFlag)flag);
+
+ return GPU_stack_link(mat,
+ node,
+ "node_bsdf_principled",
+ in,
+ out,
+ GPU_constant(&f_use_diffuse),
+ GPU_constant(&f_use_clearcoat),
+ GPU_constant(&f_use_refraction),
+ GPU_constant(&use_multi_scatter),
+ GPU_constant(&node->ssr_id),
+ GPU_constant(&node->sss_id),
+ sss_scale);
+}
+
+static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
+{
+ const int distribution = node->custom1;
+ const int sss_method = node->custom2;
+
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+ 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);
+ }
+ }
+}
+
+} // namespace blender::nodes::node_shader_bsdf_principled_cc
+
+/* node type definition */
+void register_node_type_sh_bsdf_principled()
+{
+ namespace file_ns = blender::nodes::node_shader_bsdf_principled_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_principled;
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_init(&ntype, file_ns::node_shader_init_principled);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_principled);
+ node_type_update(&ntype, file_ns::node_shader_update_principled);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
index f857708c9b6..0d588c82869 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc
@@ -17,23 +17,22 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_refraction_cc {
-static bNodeSocketTemplate sh_node_bsdf_refraction_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_refraction_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static void node_shader_init_refraction(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -56,21 +55,23 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT);
- GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);
- return GPU_stack_eval_link(mat, node, "node_bsdf_refraction_eval", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_refraction_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_refraction(void)
+void register_node_type_sh_bsdf_refraction()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_refraction_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_REFRACTION, "Refraction BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_refraction_in, sh_node_bsdf_refraction_out);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_REFRACTION, "Refraction BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_refraction);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_refraction);
+ node_type_init(&ntype, file_ns::node_shader_init_refraction);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_refraction);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
index e79c65d85d9..5093b896764 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_toon.cc
@@ -17,23 +17,34 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_bsdf_toon_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Size"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Smooth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_bsdf_toon_cc {
-static bNodeSocketTemplate sh_node_bsdf_toon_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Size"))
+ .default_value(0.5f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Smooth"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static void node_shader_buts_toon(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "component", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static int node_shader_gpu_bsdf_toon(GPUMaterial *mat,
bNode *node,
@@ -47,21 +58,23 @@ static int node_shader_gpu_bsdf_toon(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- GPU_stack_link(mat, node, "node_bsdf_toon", in, out);
- return GPU_stack_eval_link(mat, node, "node_bsdf_toon_eval", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_toon", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_toon_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_toon(void)
+void register_node_type_sh_bsdf_toon()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_toon_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_TOON, "Toon BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_toon_in, sh_node_bsdf_toon_out);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_TOON, "Toon BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_toon;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_toon);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_toon);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
index d6c308459f5..22891738299 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.cc
@@ -17,21 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_translucent_cc {
-static bNodeSocketTemplate sh_node_bsdf_translucent_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_translucent_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat,
bNode *node,
@@ -45,20 +40,21 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- GPU_stack_link(mat, node, "node_bsdf_translucent", in, out);
- return GPU_stack_eval_link(mat, node, "node_bsdf_translucent_eval", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_translucent_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_translucent(void)
+void register_node_type_sh_bsdf_translucent()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_translucent_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_translucent_in, sh_node_bsdf_translucent_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_translucent);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_translucent);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
index a1c3b9066c8..d764f4dd76b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_transparent.cc
@@ -17,20 +17,15 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_transparent_cc {
-static bNodeSocketTemplate sh_node_bsdf_transparent_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_transparent_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
bNode *node,
@@ -38,22 +33,21 @@ static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- if (in[0].link || !equals_v3v3(in[0].vec, (float[3]){0.0f, 0.0f, 0.0f})) {
- GPU_material_flag_set(mat, GPU_MATFLAG_TRANSPARENT);
- }
return GPU_stack_link(mat, node, "node_bsdf_transparent", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_transparent_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_transparent(void)
+void register_node_type_sh_bsdf_transparent()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_transparent_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_transparent_in, sh_node_bsdf_transparent_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_transparent);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_transparent);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
index 0a7828f5b9a..dd090236c08 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.cc
@@ -17,22 +17,21 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_bsdf_velvet_cc {
-static bNodeSocketTemplate sh_node_bsdf_velvet_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Sigma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_bsdf_velvet_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Sigma"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat,
bNode *node,
@@ -46,20 +45,21 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat,
GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
- GPU_stack_link(mat, node, "node_bsdf_velvet", in, out);
- return GPU_stack_link(mat, node, "node_bsdf_velvet_eval", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out);
}
+} // namespace blender::nodes::node_shader_bsdf_velvet_cc
+
/* node type definition */
-void register_node_type_sh_bsdf_velvet(void)
+void register_node_type_sh_bsdf_velvet()
{
+ namespace file_ns = blender::nodes::node_shader_bsdf_velvet_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_bsdf_velvet_in, sh_node_bsdf_velvet_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_bsdf_velvet);
+ sh_node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_bsdf_velvet);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.cc
index 5c46e1d3775..f0788c543c2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.cc
@@ -21,22 +21,38 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
/* **************** BUMP ******************** */
-/* clang-format off */
-static bNodeSocketTemplate sh_node_bump_in[] = {
- {SOCK_FLOAT, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Height"), 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Height_dx"), 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_UNAVAIL},
- {SOCK_FLOAT, N_("Height_dy"), 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_UNAVAIL},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""}
-};
-/* clang-format on */
-static bNodeSocketTemplate sh_node_bump_out[] = {{SOCK_VECTOR, "Normal"}, {-1, ""}};
+namespace blender::nodes::node_shader_bump_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Strength"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Distance")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Height"))
+ .default_value(1.0f)
+ .min(-1000.0f)
+ .max(1000.0f)
+ .hide_value();
+ b.add_input<decl::Float>(N_("Height_dx")).default_value(1.0f).unavailable();
+ b.add_input<decl::Float>(N_("Height_dy")).default_value(1.0f).unavailable();
+ b.add_input<decl::Vector>(N_("Normal")).min(-1.0f).max(1.0f).hide_value();
+ b.add_output<decl::Vector>(N_("Normal"));
+}
+
+static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "invert", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+}
static int gpu_shader_bump(GPUMaterial *mat,
bNode *node,
@@ -53,15 +69,19 @@ static int gpu_shader_bump(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_bump", in, out, GPU_constant(&invert));
}
+} // namespace blender::nodes::node_shader_bump_cc
+
/* node type definition */
-void register_node_type_sh_bump(void)
+void register_node_type_sh_bump()
{
+ namespace file_ns = blender::nodes::node_shader_bump_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_bump_in, sh_node_bump_out);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, gpu_shader_bump);
+ sh_node_type_base(&ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_bump;
+ node_type_gpu(&ntype, file_ns::gpu_shader_bump);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.cc
index 9c47db4ea4e..90d2b55b0f7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_camera.c
+++ b/source/blender/nodes/shader/nodes/node_shader_camera.cc
@@ -21,15 +21,16 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** CAMERA INFO ******************** */
-static bNodeSocketTemplate sh_node_camera_out[] = {
- {SOCK_VECTOR, N_("View Vector")},
- {SOCK_FLOAT, N_("View Z Depth")},
- {SOCK_FLOAT, N_("View Distance")},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_camera_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("View Vector"));
+ b.add_output<decl::Float>(N_("View Z Depth"));
+ b.add_output<decl::Float>(N_("View Distance"));
+}
static int gpu_shader_camera(GPUMaterial *mat,
bNode *node,
@@ -40,14 +41,17 @@ static int gpu_shader_camera(GPUMaterial *mat,
return GPU_stack_link(mat, node, "camera", in, out);
}
-void register_node_type_sh_camera(void)
+} // namespace blender::nodes::node_shader_camera_cc
+
+void register_node_type_sh_camera()
{
+ namespace file_ns = blender::nodes::node_shader_camera_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_camera_out);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, gpu_shader_camera);
+ sh_node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_camera);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
index e8d4239937f..cd0f1b3c44d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
@@ -21,20 +21,26 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_clamp_cc {
static void sh_node_clamp_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Value").min(0.0f).max(1.0f).default_value(1.0f);
- b.add_input<decl::Float>("Min").default_value(0.0f).min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Max").default_value(1.0f).min(-10000.0f).max(10000.0f);
- b.add_output<decl::Float>("Result");
-};
+ b.add_input<decl::Float>(N_("Value")).default_value(1.0f);
+ b.add_input<decl::Float>(N_("Min")).default_value(0.0f).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("Max")).default_value(1.0f).min(-10000.0f).max(10000.0f);
+ b.add_output<decl::Float>(N_("Result"));
+}
-} // namespace blender::nodes
+static void node_shader_buts_clamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "clamp_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_clamp(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -75,15 +81,20 @@ static void sh_node_clamp_build_multi_function(blender::nodes::NodeMultiFunction
}
}
-void register_node_type_sh_clamp(void)
+} // namespace blender::nodes::node_shader_clamp_cc
+
+void register_node_type_sh_clamp()
{
+ namespace file_ns = blender::nodes::node_shader_clamp_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_CLAMP, "Clamp", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_clamp_declare;
- node_type_init(&ntype, node_shader_init_clamp);
- node_type_gpu(&ntype, gpu_shader_clamp);
- ntype.build_multi_function = sh_node_clamp_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_CLAMP, "Clamp", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_clamp_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_clamp;
+ node_type_init(&ntype, file_ns::node_shader_init_clamp);
+ node_type_gpu(&ntype, file_ns::gpu_shader_clamp);
+ ntype.build_multi_function = file_ns::sh_node_clamp_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc
index d4d08be5d49..d8c43e1d66b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc
@@ -21,43 +21,20 @@
* \ingroup shdnodes
*/
-#include "IMB_colormanagement.h"
-
#include "DNA_texture_types.h"
#include "BLI_color.hh"
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_color_ramp_cc {
static void sh_node_valtorgb_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Fac").default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
- b.add_output<decl::Color>("Color");
- b.add_output<decl::Float>("Alpha");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_valtorgb(void *UNUSED(data),
- int UNUSED(thread),
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- /* stack order in: fac */
- /* stack order out: col, alpha */
-
- if (node->storage) {
- float fac;
- nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
-
- BKE_colorband_evaluate((ColorBand *)node->storage, fac, out[0]->vec);
- out[1]->vec[0] = out[0]->vec[3];
- }
+ b.add_input<decl::Float>(N_("Fac")).default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Alpha"));
}
static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node)
@@ -172,64 +149,21 @@ static void sh_node_valtorgb_build_multi_function(
builder.construct_and_set_matching_fn<ColorBandFunction>(*color_band);
}
-void register_node_type_sh_valtorgb(void)
-{
- static bNodeType ntype;
+} // namespace blender::nodes::node_shader_color_ramp_cc
- sh_fn_node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_valtorgb_declare;
- node_type_init(&ntype, node_shader_init_valtorgb);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
- node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_valtorgb);
- node_type_gpu(&ntype, gpu_shader_valtorgb);
- ntype.build_multi_function = sh_node_valtorgb_build_multi_function;
-
- nodeRegisterType(&ntype);
-}
-
-namespace blender::nodes {
-
-static void sh_node_rgbtobw_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Color>("Color").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_output<decl::Float>("Val");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_rgbtobw(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- /* stack order out: bw */
- /* stack order in: col */
- float col[3];
- nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
- out[0]->vec[0] = IMB_colormanagement_get_luminance(col);
-}
-
-static int gpu_shader_rgbtobw(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
+void register_node_type_sh_valtorgb()
{
- return GPU_stack_link(mat, node, "rgbtobw", in, out);
-}
+ namespace file_ns = blender::nodes::node_shader_color_ramp_cc;
-void register_node_type_sh_rgbtobw(void)
-{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_rgbtobw_declare;
- node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_rgbtobw);
- node_type_gpu(&ntype, gpu_shader_rgbtobw);
+ sh_fn_node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_valtorgb_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_valtorgb);
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::gpu_shader_valtorgb);
+ ntype.build_multi_function = file_ns::sh_node_valtorgb_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
deleted file mode 100644
index 4df5add7151..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- * Juho Vepsäläinen
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "DNA_node_types.h"
-
-#include "BLI_utildefines.h"
-
-#include "BKE_node.h"
-
-#include "NOD_common.h"
-#include "node_common.h"
-#include "node_exec.h"
-#include "node_shader_util.h"
-
-#include "RNA_access.h"
-
-static void copy_stack(bNodeStack *to, bNodeStack *from)
-{
- if (to != from) {
- copy_v4_v4(to->vec, from->vec);
- to->data = from->data;
- to->datatype = from->datatype;
-
- /* tag as copy to prevent freeing */
- to->is_copy = 1;
- }
-}
-
-static void move_stack(bNodeStack *to, bNodeStack *from)
-{
- if (to != from) {
- copy_v4_v4(to->vec, from->vec);
- to->data = from->data;
- to->datatype = from->datatype;
- to->is_copy = from->is_copy;
-
- from->data = NULL;
- from->is_copy = 0;
- }
-}
-
-/**** GROUP ****/
-
-static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanceKey key)
-{
- bNodeTree *ngroup = (bNodeTree *)node->id;
- bNodeTreeExec *exec;
-
- if (!ngroup) {
- return NULL;
- }
-
- /* initialize the internal node tree execution */
- exec = ntreeShaderBeginExecTree_internal(context, ngroup, key);
-
- return exec;
-}
-
-static void group_freeexec(void *nodedata)
-{
- bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata;
-
- if (gexec) {
- ntreeShaderEndExecTree_internal(gexec);
- }
-}
-
-/* Copy inputs to the internal stack.
- */
-static void group_copy_inputs(bNode *gnode, bNodeStack **in, bNodeStack *gstack)
-{
- bNodeTree *ngroup = (bNodeTree *)gnode->id;
- bNode *node;
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
-
- for (node = ngroup->nodes.first; node; node = node->next) {
- if (node->type == NODE_GROUP_INPUT) {
- for (sock = node->outputs.first, a = 0; sock; sock = sock->next, a++) {
- ns = node_get_socket_stack(gstack, sock);
- if (ns) {
- copy_stack(ns, in[a]);
- }
- }
- }
- }
-}
-
-/* Copy internal results to the external outputs.
- */
-static void group_move_outputs(bNode *gnode, bNodeStack **out, bNodeStack *gstack)
-{
- bNodeTree *ngroup = (bNodeTree *)gnode->id;
- bNode *node;
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
-
- for (node = ngroup->nodes.first; node; node = node->next) {
- if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
- for (sock = node->inputs.first, a = 0; sock; sock = sock->next, a++) {
- ns = node_get_socket_stack(gstack, sock);
- if (ns) {
- move_stack(out[a], ns);
- }
- }
- break; /* only one active output node */
- }
- }
-}
-
-static void group_execute(void *data,
- int thread,
- struct bNode *node,
- bNodeExecData *execdata,
- struct bNodeStack **in,
- struct bNodeStack **out)
-{
- bNodeTreeExec *exec = execdata->data;
- bNodeThreadStack *nts;
-
- if (!exec) {
- return;
- }
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode = exec->nodetree->nodes.first; inode; inode = inode->next) {
- inode->need_exec = 1;
- }
- }
-
- nts = ntreeGetThreadStack(exec, thread);
-
- group_copy_inputs(node, in, nts->stack);
- ntreeExecThreadNodes(exec, nts, data, thread);
- group_move_outputs(node, out, nts->stack);
-
- ntreeReleaseThreadStack(nts);
-}
-
-static void group_gpu_copy_inputs(bNode *gnode, GPUNodeStack *in, bNodeStack *gstack)
-{
- bNodeTree *ngroup = (bNodeTree *)gnode->id;
- bNode *node;
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
-
- for (node = ngroup->nodes.first; node; node = node->next) {
- if (node->type == NODE_GROUP_INPUT) {
- for (sock = node->outputs.first, a = 0; sock; sock = sock->next, a++) {
- ns = node_get_socket_stack(gstack, sock);
- if (ns) {
- /* convert the external gpu stack back to internal node stack data */
- node_data_from_gpu_stack(ns, &in[a]);
- }
- }
- }
- }
-}
-
-/* Copy internal results to the external outputs.
- */
-static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *gstack)
-{
- bNodeTree *ngroup = (bNodeTree *)gnode->id;
- bNode *node;
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
-
- for (node = ngroup->nodes.first; node; node = node->next) {
- if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
- for (sock = node->inputs.first, a = 0; sock; sock = sock->next, a++) {
- ns = node_get_socket_stack(gstack, sock);
- if (ns) {
- /* convert the node stack data result back to gpu stack */
- node_gpu_stack_from_data(&out[a], sock->type, ns);
- }
- }
- break; /* only one active output node */
- }
- }
-}
-
-static int gpu_group_execute(
- GPUMaterial *mat, bNode *node, bNodeExecData *execdata, GPUNodeStack *in, GPUNodeStack *out)
-{
- bNodeTreeExec *exec = execdata->data;
-
- if (!node->id) {
- return 0;
- }
-
- group_gpu_copy_inputs(node, in, exec->stack);
- ntreeExecGPUNodes(exec, mat, NULL);
- group_gpu_move_outputs(node, out, exec->stack);
-
- return 1;
-}
-
-void register_node_type_sh_group(void)
-{
- static bNodeType ntype;
-
- /* 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);
- ntype.type = NODE_GROUP;
- ntype.poll = sh_node_poll_default;
- ntype.poll_instance = node_group_poll_instance;
- ntype.insert_link = node_insert_link_default;
- ntype.update_internal_links = node_update_internal_links_default;
- ntype.rna_ext.srna = RNA_struct_find("ShaderNodeGroup");
- BLI_assert(ntype.rna_ext.srna != NULL);
- RNA_struct_blender_type_set(ntype.rna_ext.srna, &ntype);
-
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 140, 60, 400);
- node_type_label(&ntype, 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);
-
- nodeRegisterType(&ntype);
-}
-
-void register_node_type_sh_custom_group(bNodeType *ntype)
-{
- /* These methods can be overridden but need a default implementation otherwise. */
- if (ntype->poll == NULL) {
- ntype->poll = sh_node_poll_default;
- }
- if (ntype->insert_link == NULL) {
- ntype->insert_link = node_insert_link_default;
- }
- if (ntype->update_internal_links == NULL) {
- ntype->update_internal_links = node_update_internal_links_default;
- }
-
- 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_common.cc b/source/blender/nodes/shader/nodes/node_shader_common.cc
new file mode 100644
index 00000000000..3f0fff34533
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_common.cc
@@ -0,0 +1,130 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ * Juho Vepsäläinen
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "DNA_node_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_node.h"
+
+#include "NOD_common.h"
+#include "node_common.h"
+#include "node_exec.h"
+#include "node_shader_util.hh"
+
+#include "RNA_access.h"
+
+/**** GROUP ****/
+
+static void group_gpu_copy_inputs(bNode *gnode, GPUNodeStack *in, bNodeStack *gstack)
+{
+ bNodeTree *ngroup = (bNodeTree *)gnode->id;
+
+ LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
+ if (node->type == NODE_GROUP_INPUT) {
+ int a;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->outputs, a) {
+ bNodeStack *ns = node_get_socket_stack(gstack, sock);
+ if (ns) {
+ /* convert the external gpu stack back to internal node stack data */
+ node_data_from_gpu_stack(ns, &in[a]);
+ }
+ }
+ }
+ }
+}
+
+/* Copy internal results to the external outputs.
+ */
+static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *gstack)
+{
+ bNodeTree *ngroup = (bNodeTree *)gnode->id;
+
+ LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
+ if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
+ int a;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->inputs, a) {
+ bNodeStack *ns = node_get_socket_stack(gstack, sock);
+ if (ns) {
+ /* convert the node stack data result back to gpu stack */
+ node_gpu_stack_from_data(&out[a], sock->type, ns);
+ }
+ }
+ break; /* only one active output node */
+ }
+ }
+}
+
+static int gpu_group_execute(
+ GPUMaterial *mat, bNode *node, bNodeExecData *execdata, GPUNodeStack *in, GPUNodeStack *out)
+{
+ bNodeTreeExec *exec = static_cast<bNodeTreeExec *>(execdata->data);
+
+ if (!node->id) {
+ return 0;
+ }
+
+ group_gpu_copy_inputs(node, in, exec->stack);
+ ntreeExecGPUNodes(exec, mat, nullptr);
+ group_gpu_move_outputs(node, out, exec->stack);
+
+ return 1;
+}
+
+void register_node_type_sh_group()
+{
+ static bNodeType ntype;
+
+ /* 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);
+ ntype.type = NODE_GROUP;
+ ntype.poll = sh_node_poll_default;
+ ntype.poll_instance = node_group_poll_instance;
+ ntype.insert_link = node_insert_link_default;
+ ntype.rna_ext.srna = RNA_struct_find("ShaderNodeGroup");
+ BLI_assert(ntype.rna_ext.srna != nullptr);
+ RNA_struct_blender_type_set(ntype.rna_ext.srna, &ntype);
+
+ node_type_size(&ntype, 140, 60, 400);
+ ntype.labelfunc = node_group_label;
+ node_type_group_update(&ntype, node_group_update);
+ node_type_gpu(&ntype, gpu_group_execute);
+
+ nodeRegisterType(&ntype);
+}
+
+void register_node_type_sh_custom_group(bNodeType *ntype)
+{
+ /* These methods can be overridden but need a default implementation otherwise. */
+ if (ntype->poll == nullptr) {
+ ntype->poll = sh_node_poll_default;
+ }
+ if (ntype->insert_link == nullptr) {
+ ntype->insert_link = node_insert_link_default;
+ }
+
+ 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 887cc84bb76..bce59a60033 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc
@@ -21,33 +21,16 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_curves_cc {
static void sh_node_curve_vec_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Fac").min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
- b.add_input<decl::Vector>("Vector").min(-1.0f).max(1.0f);
- b.add_output<decl::Vector>("Vector");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_curve_vec(void *UNUSED(data),
- int UNUSED(thread),
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float vec[3];
-
- /* stack order input: vec */
- /* stack order output: vec */
- nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
- BKE_curvemapping_evaluate3F((CurveMapping *)node->storage, out[0]->vec, vec);
+ b.add_input<decl::Float>(N_("Fac")).min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Vector")).min(-1.0f).max(1.0f);
+ b.add_output<decl::Vector>(N_("Vector"));
}
static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
@@ -152,53 +135,35 @@ 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)
+} // namespace blender::nodes::node_shader_curves_cc
+
+void register_node_type_sh_curve_vec()
{
+ namespace file_ns = blender::nodes::node_shader_curves_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, 0);
- ntype.declare = blender::nodes::sh_node_curve_vec_declare;
- node_type_init(&ntype, node_shader_init_curve_vec);
+ sh_fn_node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::sh_node_curve_vec_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_curve_vec);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_vec);
- node_type_gpu(&ntype, gpu_shader_curve_vec);
- ntype.build_multi_function = sh_node_curve_vec_build_multi_function;
+ node_type_gpu(&ntype, file_ns::gpu_shader_curve_vec);
+ ntype.build_multi_function = file_ns::sh_node_curve_vec_build_multi_function;
nodeRegisterType(&ntype);
}
/* **************** CURVE RGB ******************** */
-namespace blender::nodes {
+namespace blender::nodes::node_shader_curves_cc {
static void sh_node_curve_rgb_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Float>("Fac").min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
- b.add_input<decl::Color>("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
- b.add_output<decl::Color>("Color");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_curve_rgb(void *UNUSED(data),
- int UNUSED(thread),
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float vec[3];
- float fac;
-
- /* stack order input: vec */
- /* stack order output: vec */
- nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
- nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
- BKE_curvemapping_evaluateRGBF((CurveMapping *)node->storage, out[0]->vec, vec);
- if (fac != 1.0f) {
- interp_v3_v3v3(out[0]->vec, vec, out[0]->vec, fac);
- }
+ b.is_function_node();
+ b.add_input<decl::Float>(N_("Fac")).min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_output<decl::Color>(N_("Color"));
}
static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node)
@@ -328,18 +293,148 @@ 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)
+} // namespace blender::nodes::node_shader_curves_cc
+
+void register_node_type_sh_curve_rgb()
+{
+ namespace file_ns = blender::nodes::node_shader_curves_cc;
+
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::sh_node_curve_rgb_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_curve_rgb);
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
+ node_type_gpu(&ntype, file_ns::gpu_shader_curve_rgb);
+ ntype.build_multi_function = file_ns::sh_node_curve_rgb_build_multi_function;
+
+ nodeRegisterType(&ntype);
+}
+
+/* **************** CURVE FLOAT ******************** */
+
+namespace blender::nodes::node_shader_curves_cc {
+
+static void sh_node_curve_float_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Float>(N_("Factor"))
+ .min(0.0f)
+ .max(1.0f)
+ .default_value(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Value")).default_value(1.0f).is_default_link_socket();
+ b.add_output<decl::Float>(N_("Value"));
+}
+
+static void node_shader_init_curve_float(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->storage = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+static int gpu_shader_curve_float(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ float *array, layer;
+ int size;
+
+ CurveMapping *cumap = (CurveMapping *)node->storage;
+
+ BKE_curvemapping_table_F(cumap, &array, &size);
+ GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
+
+ float ext_xyz[4];
+ float range_x;
+
+ const CurveMap *cm = &cumap->cm[0];
+ ext_xyz[0] = cm->mintable;
+ ext_xyz[2] = cm->maxtable;
+ range_x = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
+ /* Compute extrapolation gradients. */
+ if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
+ ext_xyz[1] = (cm->ext_in[0] != 0.0f) ? (cm->ext_in[1] / (cm->ext_in[0] * range_x)) : 1e8f;
+ ext_xyz[3] = (cm->ext_out[0] != 0.0f) ? (cm->ext_out[1] / (cm->ext_out[0] * range_x)) : 1e8f;
+ }
+ else {
+ ext_xyz[1] = 0.0f;
+ ext_xyz[3] = 0.0f;
+ }
+ return GPU_stack_link(mat,
+ node,
+ "curve_float",
+ in,
+ out,
+ tex,
+ GPU_constant(&layer),
+ GPU_uniform(&range_x),
+ GPU_uniform(ext_xyz));
+}
+
+class CurveFloatFunction : public blender::fn::MultiFunction {
+ private:
+ const CurveMapping &cumap_;
+
+ public:
+ CurveFloatFunction(const CurveMapping &cumap) : cumap_(cumap)
+ {
+ static blender::fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static blender::fn::MFSignature create_signature()
+ {
+ blender::fn::MFSignatureBuilder signature{"Curve Float"};
+ signature.single_input<float>("Factor");
+ signature.single_input<float>("Value");
+ signature.single_output<float>("Value");
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ const blender::VArray<float> &fac = params.readonly_single_input<float>(0, "Factor");
+ const blender::VArray<float> &val_in = params.readonly_single_input<float>(1, "Value");
+ blender::MutableSpan<float> val_out = params.uninitialized_single_output<float>(2, "Value");
+
+ for (int64_t i : mask) {
+ val_out[i] = BKE_curvemapping_evaluateF(&cumap_, 0, val_in[i]);
+ if (fac[i] != 1.0f) {
+ val_out[i] = (1.0f - fac[i]) * val_in[i] + fac[i] * val_out[i];
+ }
+ }
+ }
+};
+
+static void sh_node_curve_float_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &bnode = builder.node();
+ CurveMapping *cumap = (CurveMapping *)bnode.storage;
+ BKE_curvemapping_init(cumap);
+ builder.construct_and_set_matching_fn<CurveFloatFunction>(*cumap);
+}
+
+} // namespace blender::nodes::node_shader_curves_cc
+
+void register_node_type_sh_curve_float()
{
+ namespace file_ns = blender::nodes::node_shader_curves_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
- ntype.declare = blender::nodes::sh_node_curve_rgb_declare;
- node_type_init(&ntype, node_shader_init_curve_rgb);
+ sh_fn_node_type_base(&ntype, SH_NODE_CURVE_FLOAT, "Float Curve", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_curve_float_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_curve_float);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
- node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_rgb);
- node_type_gpu(&ntype, gpu_shader_curve_rgb);
- ntype.build_multi_function = sh_node_curve_rgb_build_multi_function;
+ node_type_gpu(&ntype, file_ns::gpu_shader_curve_float);
+ ntype.build_multi_function = file_ns::sh_node_curve_float_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.cc
index c88083d109f..47af2447440 100644
--- a/source/blender/nodes/shader/nodes/node_shader_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_displacement.cc
@@ -17,22 +17,18 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_displacement_cc {
-static bNodeSocketTemplate sh_node_displacement_in[] = {
- {SOCK_FLOAT, N_("Height"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_displacement_out[] = {
- {SOCK_VECTOR, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Height")).default_value(0.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Midlevel")).default_value(0.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Vector>(N_("Displacement"));
+}
static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -63,16 +59,19 @@ static int gpu_shader_displacement(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_displacement_world", in, out);
}
+} // namespace blender::nodes::node_shader_displacement_cc
+
/* node type definition */
-void register_node_type_sh_displacement(void)
+void register_node_type_sh_displacement()
{
+ namespace file_ns = blender::nodes::node_shader_displacement_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_DISPLACEMENT, "Displacement", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_displacement_in, sh_node_displacement_out);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_init(&ntype, node_shader_init_displacement);
- node_type_gpu(&ntype, gpu_shader_displacement);
+ sh_node_type_base(&ntype, SH_NODE_DISPLACEMENT, "Displacement", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_displacement);
+ node_type_gpu(&ntype, file_ns::gpu_shader_displacement);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c
deleted file mode 100644
index 191a8b2a376..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_eevee_specular_in[] = {
- {SOCK_RGBA, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
- {SOCK_RGBA, N_("Specular"), 0.03f, 0.03f, 0.03f, 1.0f},
- {SOCK_FLOAT, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR,
- N_("Clear Coat Normal"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_HIDE_VALUE},
- {SOCK_FLOAT,
- N_("Ambient Occlusion"),
- 1.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_eevee_specular_out[] = {
- {SOCK_SHADER, N_("BSDF")},
- {-1, ""},
-};
-
-static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- static float one = 1.0f;
-
- /* Normals */
- if (!in[5].link) {
- GPU_link(mat, "world_normals_get", &in[5].link);
- }
-
- /* Clearcoat Normals */
- if (!in[8].link) {
- GPU_link(mat, "world_normals_get", &in[8].link);
- }
-
- /* Occlusion */
- if (!in[9].link) {
- GPU_link(mat, "set_value", GPU_constant(&one), &in[9].link);
- }
-
- GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY);
-
- GPU_stack_link(mat, node, "node_eevee_specular", in, out);
- return GPU_stack_eval_link(mat, node, "node_eevee_specular_eval", in, out);
-}
-
-/* node type definition */
-void register_node_type_sh_eevee_specular(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_EEVEE_SPECULAR, "Specular BSDF", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_eevee_specular_in, sh_node_eevee_specular_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_eevee_specular);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
new file mode 100644
index 00000000000..e4c80725c8e
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.cc
@@ -0,0 +1,97 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_eevee_specular_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Base Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Color>(N_("Specular")).default_value({0.03f, 0.03f, 0.03f, 1.0f});
+ b.add_input<decl::Float>(N_("Roughness"))
+ .default_value(0.2f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Emissive Color")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Transparency"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Clear Coat"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Clear Coat Roughness"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Clear Coat Normal")).hide_value();
+ b.add_input<decl::Float>(N_("Ambient Occlusion")).hide_value();
+ b.add_output<decl::Shader>(N_("BSDF"));
+}
+
+static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ static float one = 1.0f;
+
+ /* Normals */
+ if (!in[5].link) {
+ GPU_link(mat, "world_normals_get", &in[5].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[8].link) {
+ GPU_link(mat, "world_normals_get", &in[8].link);
+ }
+
+ /* Occlusion */
+ if (!in[9].link) {
+ GPU_link(mat, "set_value", GPU_constant(&one), &in[9].link);
+ }
+
+ GPU_material_flag_set(mat, static_cast<eGPUMatFlag>(GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY));
+
+ return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_constant(&node->ssr_id));
+}
+
+} // namespace blender::nodes::node_shader_eevee_specular_cc
+
+/* node type definition */
+void register_node_type_sh_eevee_specular()
+{
+ namespace file_ns = blender::nodes::node_shader_eevee_specular_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_EEVEE_SPECULAR, "Specular BSDF", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_eevee_specular);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_emission.c b/source/blender/nodes/shader/nodes/node_shader_emission.cc
index 64bef6adb46..ea36763578f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_emission.c
+++ b/source/blender/nodes/shader/nodes/node_shader_emission.cc
@@ -17,21 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_emission_cc {
-static bNodeSocketTemplate sh_node_emission_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_emission_out[] = {
- {SOCK_SHADER, N_("Emission")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Strength")).default_value(1.0f).min(0.0f).max(1000000.0f);
+ b.add_output<decl::Shader>(N_("Emission"));
+}
static int node_shader_gpu_emission(GPUMaterial *mat,
bNode *node,
@@ -39,20 +34,21 @@ static int node_shader_gpu_emission(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- GPU_material_flag_set(mat, GPU_MATFLAG_EMISSION);
- return GPU_stack_link(mat, node, "node_emission", in, out);
+ return GPU_stack_link(mat, node, "node_emission", in, out, GPU_builtin(GPU_VIEW_NORMAL));
}
+} // namespace blender::nodes::node_shader_emission_cc
+
/* node type definition */
-void register_node_type_sh_emission(void)
+void register_node_type_sh_emission()
{
+ namespace file_ns = blender::nodes::node_shader_emission_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_emission_in, sh_node_emission_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_emission);
+ sh_node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_emission);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.cc
index 9b25af912ef..19eb79e2138 100644
--- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c
+++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.cc
@@ -17,19 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Fresnel ******************** */
-static bNodeSocketTemplate sh_node_fresnel_in[] = {
- {SOCK_FLOAT, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_fresnel_cc {
-static bNodeSocketTemplate sh_node_fresnel_out[] = {
- {SOCK_FLOAT, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Float>(N_("Fac"));
+}
static int node_shader_gpu_fresnel(GPUMaterial *mat,
bNode *node,
@@ -44,26 +41,18 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_fresnel", in, out);
}
-static void node_shader_exec_fresnel(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **UNUSED(in),
- bNodeStack **UNUSED(out))
-{
-}
+} // namespace blender::nodes::node_shader_fresnel_cc
/* node type definition */
-void register_node_type_sh_fresnel(void)
+void register_node_type_sh_fresnel()
{
+ namespace file_ns = blender::nodes::node_shader_fresnel_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_FRESNEL, "Fresnel", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, sh_node_fresnel_in, sh_node_fresnel_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_fresnel);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_fresnel);
+ sh_node_type_base(&ntype, SH_NODE_FRESNEL, "Fresnel", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_fresnel);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
deleted file mode 100644
index b48838e5f56..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- */
-
-#include "node_shader_util.h"
-
-/* **************** Gamma Tools ******************** */
-
-static bNodeSocketTemplate sh_node_gamma_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f},
- {SOCK_FLOAT, N_("Gamma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_gamma_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
-
-static void node_shader_exec_gamma(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float col[3];
- float gamma;
- nodestack_get_vec(col, SOCK_VECTOR, in[0]);
- nodestack_get_vec(&gamma, SOCK_FLOAT, in[1]);
-
- out[0]->vec[0] = col[0] > 0.0f ? powf(col[0], gamma) : col[0];
- out[0]->vec[1] = col[1] > 0.0f ? powf(col[1], gamma) : col[1];
- out[0]->vec[2] = col[2] > 0.0f ? powf(col[2], gamma) : col[2];
-}
-
-static int node_shader_gpu_gamma(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "node_gamma", in, out);
-}
-
-void register_node_type_sh_gamma(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, 0);
- node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_gamma);
- node_type_gpu(&ntype, node_shader_gpu_gamma);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.cc b/source/blender/nodes/shader/nodes/node_shader_gamma.cc
new file mode 100644
index 00000000000..98a287b08da
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_gamma_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Gamma"))
+ .default_value(1.0f)
+ .min(0.001f)
+ .max(10.0f)
+ .subtype(PROP_UNSIGNED);
+ b.add_output<decl::Color>(N_("Color"));
+}
+
+static int node_shader_gpu_gamma(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "node_gamma", in, out);
+}
+
+} // namespace blender::nodes::node_shader_gamma_cc
+
+void register_node_type_sh_gamma()
+{
+ namespace file_ns = blender::nodes::node_shader_gamma_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_gamma);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.cc
index 633f071ab86..35eef95adb5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.cc
@@ -17,22 +17,22 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_geometry_cc {
-static bNodeSocketTemplate sh_node_geometry_out[] = {
- {SOCK_VECTOR, N_("Position"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Tangent"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("True Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Incoming"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Parametric"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Backfacing"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Pointiness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Random Per Island"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("Position"));
+ b.add_output<decl::Vector>(N_("Normal"));
+ b.add_output<decl::Vector>(N_("Tangent"));
+ b.add_output<decl::Vector>(N_("True Normal"));
+ b.add_output<decl::Vector>(N_("Incoming"));
+ b.add_output<decl::Vector>(N_("Parametric"));
+ b.add_output<decl::Float>(N_("Backfacing"));
+ b.add_output<decl::Float>(N_("Pointiness"));
+ b.add_output<decl::Float>(N_("Random Per Island"));
+}
static int node_shader_gpu_geometry(GPUMaterial *mat,
bNode *node,
@@ -52,8 +52,8 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
const bool success = GPU_stack_link(mat, node, "node_geometry", in, out, orco_link);
- /* for each output */
- for (int i = 0; sh_node_geometry_out[i].type != -1; i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->outputs, i) {
node_shader_gpu_bump_tex_coord(mat, node, &out[i].link);
/* Normalize some vectors after dFdx/dFdy offsets.
* This is the case for interpolated, non linear functions.
@@ -67,23 +67,25 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
out[i].link,
out[i].link,
&out[i].link,
- NULL);
+ nullptr);
}
}
return success;
}
+} // namespace blender::nodes::node_shader_geometry_cc
+
/* node type definition */
-void register_node_type_sh_geometry(void)
+void register_node_type_sh_geometry()
{
+ namespace file_ns = blender::nodes::node_shader_geometry_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_NEW_GEOMETRY, "Geometry", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_geometry_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_geometry);
+ sh_node_type_base(&ntype, SH_NODE_NEW_GEOMETRY, "Geometry", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_geometry);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.cc
index c721fb9c77a..12c29c40b1d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hair_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.cc
@@ -17,18 +17,19 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
-
-static bNodeSocketTemplate outputs[] = {
- {SOCK_FLOAT, N_("Is Strand"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Intercept"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Length"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- // { SOCK_FLOAT, 0, N_("Fade"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Random")},
- {-1, ""},
-};
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_hair_info_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>(N_("Is Strand"));
+ b.add_output<decl::Float>(N_("Intercept"));
+ b.add_output<decl::Float>(N_("Length"));
+ b.add_output<decl::Float>(N_("Thickness"));
+ b.add_output<decl::Vector>(N_("Tangent Normal"));
+ b.add_output<decl::Float>(N_("Random"));
+}
static int node_shader_gpu_hair_info(GPUMaterial *mat,
bNode *node,
@@ -43,16 +44,18 @@ static int node_shader_gpu_hair_info(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_hair_info", in, out, length_link);
}
+} // namespace blender::nodes::node_shader_hair_info_cc
+
/* node type definition */
-void register_node_type_sh_hair_info(void)
+void register_node_type_sh_hair_info()
{
+ namespace file_ns = blender::nodes::node_shader_hair_info_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_HAIR_INFO, "Hair Info", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, outputs);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_hair_info);
+ sh_node_type_base(&ntype, SH_NODE_HAIR_INFO, "Hair Info", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_hair_info);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_holdout.c b/source/blender/nodes/shader/nodes/node_shader_holdout.cc
index eb087183a0b..4f6f8a639de 100644
--- a/source/blender/nodes/shader/nodes/node_shader_holdout.c
+++ b/source/blender/nodes/shader/nodes/node_shader_holdout.cc
@@ -17,19 +17,14 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_holdout_cc {
-static bNodeSocketTemplate sh_node_holdout_in[] = {
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_holdout_out[] = {
- {SOCK_SHADER, N_("Holdout")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Shader>(N_("Holdout"));
+}
static int gpu_shader_rgb(GPUMaterial *mat,
bNode *node,
@@ -37,20 +32,21 @@ static int gpu_shader_rgb(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- GPU_material_flag_set(mat, GPU_MATFLAG_HOLDOUT);
return GPU_stack_link(mat, node, "node_holdout", in, out);
}
+} // namespace blender::nodes::node_shader_holdout_cc
+
/* node type definition */
-void register_node_type_sh_holdout(void)
+void register_node_type_sh_holdout()
{
+ namespace file_ns = blender::nodes::node_shader_holdout_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_holdout_in, sh_node_holdout_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, gpu_shader_rgb);
+ sh_node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_rgb);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
deleted file mode 100644
index 50eb5bf32c9..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2006 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** Hue Saturation ******************** */
-static bNodeSocketTemplate sh_node_hue_sat_in[] = {
- {SOCK_FLOAT, N_("Hue"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Saturation"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Value"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f},
- {-1, ""},
-};
-static bNodeSocketTemplate sh_node_hue_sat_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
-
-/* NOTE: it would be possible to use CMP version for both nodes. */
-static void do_hue_sat_fac(
- bNode *UNUSED(node), float *out, float hue, float sat, float val, const float in[4], float fac)
-{
- if (fac != 0.0f && (hue != 0.5f || sat != 1.0f || val != 1.0f)) {
- float col[3], hsv[3], mfac = 1.0f - fac;
-
- rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
- hsv[0] = fmodf(hsv[0] + hue + 0.5f, 1.0f);
- hsv[1] = clamp_f(hsv[1] * sat, 0.0f, 1.0f);
- hsv[2] *= val;
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col + 1, col + 2);
-
- out[0] = mfac * in[0] + fac * col[0];
- out[1] = mfac * in[1] + fac * col[1];
- out[2] = mfac * in[2] + fac * col[2];
- }
- else {
- copy_v4_v4(out, in);
- }
-}
-
-static void node_shader_exec_hue_sat(void *UNUSED(data),
- int UNUSED(thread),
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float hue, sat, val, fac;
- float col[4];
- nodestack_get_vec(&hue, SOCK_FLOAT, in[0]);
- nodestack_get_vec(&sat, SOCK_FLOAT, in[1]);
- nodestack_get_vec(&val, SOCK_FLOAT, in[2]);
- nodestack_get_vec(&fac, SOCK_FLOAT, in[3]);
- nodestack_get_vec(col, SOCK_RGBA, in[4]);
- do_hue_sat_fac(node, out[0]->vec, hue, sat, val, col, fac);
-}
-
-static int gpu_shader_hue_sat(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "hue_sat", in, out);
-}
-
-void register_node_type_sh_hue_sat(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, 0);
- node_type_socket_templates(&ntype, sh_node_hue_sat_in, sh_node_hue_sat_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_hue_sat);
- node_type_gpu(&ntype, gpu_shader_hue_sat);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc
new file mode 100644
index 00000000000..94b9a61c602
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.cc
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_hueSatVal_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Hue")).default_value(0.5f).min(0.0f).max(1.0f);
+ b.add_input<decl::Float>(N_("Saturation")).default_value(1.0f).min(0.0f).max(2.0f);
+ b.add_input<decl::Float>(N_("Value")).default_value(1.0f).min(0.0f).max(2.0f);
+ b.add_input<decl::Float>(N_("Fac")).default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_output<decl::Color>(N_("Color"));
+}
+
+static int gpu_shader_hue_sat(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "hue_sat", in, out);
+}
+
+} // namespace blender::nodes::node_shader_hueSatVal_cc
+
+void register_node_type_sh_hue_sat()
+{
+ namespace file_ns = blender::nodes::node_shader_hueSatVal_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_gpu(&ntype, file_ns::gpu_shader_hue_sat);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_ies_light.c b/source/blender/nodes/shader/nodes/node_shader_ies_light.c
deleted file mode 100644
index 9cc5fd46181..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_ies_light.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2018 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** IES Light ******************** */
-
-static bNodeSocketTemplate sh_node_tex_ies_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f, PROP_NONE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_ies_out[] = {
- {SOCK_FLOAT, N_("Fac")},
- {-1, ""},
-};
-
-static void node_shader_init_tex_ies(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeShaderTexIES *tex = MEM_callocN(sizeof(NodeShaderTexIES), "NodeShaderIESLight");
- node->storage = tex;
-}
-
-/* node type definition */
-void register_node_type_sh_tex_ies(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_IES, "IES Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_ies_in, sh_node_tex_ies_out);
- node_type_init(&ntype, node_shader_init_tex_ies);
- node_type_storage(
- &ntype, "NodeShaderTexIES", node_free_standard_storage, node_copy_standard_storage);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_ies_light.cc b/source/blender/nodes/shader/nodes/node_shader_ies_light.cc
new file mode 100644
index 00000000000..82f0a3045c9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_ies_light.cc
@@ -0,0 +1,74 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_ies_light_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector")).hide_value();
+ b.add_input<decl::Float>(N_("Strength")).default_value(1.0f).min(0.0f).max(1000000.0f);
+ b.add_output<decl::Float>(N_("Fac"));
+}
+
+static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, ptr, "mode", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+
+ row = uiLayoutRow(layout, true);
+
+ if (RNA_enum_get(ptr, "mode") == NODE_IES_INTERNAL) {
+ uiItemR(row, ptr, "ies", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+ else {
+ uiItemR(row, ptr, "filepath", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+}
+
+static void node_shader_init_tex_ies(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderTexIES *tex = MEM_cnew<NodeShaderTexIES>("NodeShaderIESLight");
+ node->storage = tex;
+}
+
+} // namespace blender::nodes::node_shader_ies_light_cc
+
+/* node type definition */
+void register_node_type_sh_tex_ies()
+{
+ namespace file_ns = blender::nodes::node_shader_ies_light_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_TEX_IES, "IES Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_ies;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_ies);
+ node_type_storage(
+ &ntype, "NodeShaderTexIES", node_free_standard_storage, node_copy_standard_storage);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c
deleted file mode 100644
index 0d6709a1968..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_invert.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** INVERT ******************** */
-static bNodeSocketTemplate sh_node_invert_in[] = {
- {SOCK_FLOAT, N_("Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""}};
-
-static bNodeSocketTemplate sh_node_invert_out[] = {{SOCK_RGBA, N_("Color")}, {-1, ""}};
-
-static void node_shader_exec_invert(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float col[3], icol[3], fac;
-
- nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
- nodestack_get_vec(col, SOCK_VECTOR, in[1]);
-
- icol[0] = 1.0f - col[0];
- icol[1] = 1.0f - col[1];
- icol[2] = 1.0f - col[2];
-
- /* if fac, blend result against original input */
- if (fac < 1.0f) {
- interp_v3_v3v3(out[0]->vec, col, icol, fac);
- }
- else {
- copy_v3_v3(out[0]->vec, icol);
- }
-}
-
-static int gpu_shader_invert(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "invert", in, out);
-}
-
-void register_node_type_sh_invert(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, 0);
- node_type_socket_templates(&ntype, sh_node_invert_in, sh_node_invert_out);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_invert);
- node_type_gpu(&ntype, gpu_shader_invert);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.cc b/source/blender/nodes/shader/nodes/node_shader_invert.cc
new file mode 100644
index 00000000000..3b5f4cb1d38
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_invert_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Fac")).default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Color")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_output<decl::Color>(N_("Color"));
+}
+
+static int gpu_shader_invert(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "invert", in, out);
+}
+
+} // namespace blender::nodes::node_shader_invert_cc
+
+void register_node_type_sh_invert()
+{
+ namespace file_ns = blender::nodes::node_shader_invert_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_invert);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc
index 599a44c2ec3..0294a0bde07 100644
--- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c
+++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.cc
@@ -17,21 +17,17 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Layer Weight ******************** */
+namespace blender::nodes::node_shader_layer_weight_cc {
-static bNodeSocketTemplate sh_node_layer_weight_in[] = {
- {SOCK_FLOAT, N_("Blend"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_layer_weight_out[] = {
- {SOCK_FLOAT, N_("Fresnel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Facing"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Blend")).default_value(0.5f).min(0.0f).max(1.0f);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Float>(N_("Fresnel"));
+ b.add_output<decl::Float>(N_("Facing"));
+}
static int node_shader_gpu_layer_weight(GPUMaterial *mat,
bNode *node,
@@ -46,26 +42,18 @@ static int node_shader_gpu_layer_weight(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_layer_weight", in, out);
}
-static void node_shader_exec_layer_weight(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **UNUSED(in),
- bNodeStack **UNUSED(out))
-{
-}
+} // namespace blender::nodes::node_shader_layer_weight_cc
/* node type definition */
-void register_node_type_sh_layer_weight(void)
+void register_node_type_sh_layer_weight()
{
+ namespace file_ns = blender::nodes::node_shader_layer_weight_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_LAYER_WEIGHT, "Layer Weight", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, sh_node_layer_weight_in, sh_node_layer_weight_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_layer_weight);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_layer_weight);
+ sh_node_type_base(&ntype, SH_NODE_LAYER_WEIGHT, "Layer Weight", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_layer_weight);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_falloff.c b/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc
index 22172221f77..50eea2b3643 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_falloff.c
+++ b/source/blender/nodes/shader/nodes/node_shader_light_falloff.cc
@@ -17,24 +17,18 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** INPUT ********************* */
+namespace blender::nodes::node_shader_light_falloff_cc {
-static bNodeSocketTemplate sh_node_light_falloff_in[] = {
- {SOCK_FLOAT, N_("Strength"), 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
- {SOCK_FLOAT, N_("Smooth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {-1, ""},
-};
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_light_falloff_out[] = {
- {SOCK_FLOAT, N_("Quadratic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Linear"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Constant"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Strength")).default_value(100.0f).min(0.0f).max(1000000.0f);
+ b.add_input<decl::Float>(N_("Smooth")).default_value(0.0f).min(0.0f).max(1000.0f);
+ b.add_output<decl::Float>(N_("Quadratic"));
+ b.add_output<decl::Float>(N_("Linear"));
+ b.add_output<decl::Float>(N_("Constant"));
+}
static int node_shader_gpu_light_falloff(GPUMaterial *mat,
bNode *node,
@@ -45,17 +39,19 @@ static int node_shader_gpu_light_falloff(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_light_falloff", in, out);
}
+} // namespace blender::nodes::node_shader_light_falloff_cc
+
/* node type definition */
-void register_node_type_sh_light_falloff(void)
+void register_node_type_sh_light_falloff()
{
+ namespace file_ns = blender::nodes::node_shader_light_falloff_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_LIGHT_FALLOFF, "Light Falloff", NODE_CLASS_OP_COLOR, 0);
- node_type_socket_templates(&ntype, sh_node_light_falloff_in, sh_node_light_falloff_out);
+ sh_node_type_base(&ntype, SH_NODE_LIGHT_FALLOFF, "Light Falloff", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_light_falloff);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_light_falloff);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.c b/source/blender/nodes/shader/nodes/node_shader_light_path.c
deleted file mode 100644
index 45ad2133ee8..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_light_path.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_light_path_out[] = {
- {SOCK_FLOAT, N_("Is Camera Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Shadow Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Diffuse Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Glossy Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Singular Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Reflection Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Is Transmission Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Ray Length"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Ray Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Diffuse Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Glossy Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Transparent Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Transmission Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
-
-static int node_shader_gpu_light_path(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "node_light_path", in, out);
-}
-
-/* node type definition */
-void register_node_type_sh_light_path(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_LIGHT_PATH, "Light Path", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_light_path_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_light_path);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.cc b/source/blender/nodes/shader/nodes/node_shader_light_path.cc
new file mode 100644
index 00000000000..6fbd5751886
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_light_path.cc
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_light_path_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>(N_("Is Camera Ray"));
+ b.add_output<decl::Float>(N_("Is Shadow Ray"));
+ b.add_output<decl::Float>(N_("Is Diffuse Ray"));
+ b.add_output<decl::Float>(N_("Is Glossy Ray"));
+ b.add_output<decl::Float>(N_("Is Singular Ray"));
+ b.add_output<decl::Float>(N_("Is Reflection Ray"));
+ b.add_output<decl::Float>(N_("Is Transmission Ray"));
+ b.add_output<decl::Float>(N_("Ray Length"));
+ b.add_output<decl::Float>(N_("Ray Depth"));
+ b.add_output<decl::Float>(N_("Diffuse Depth"));
+ b.add_output<decl::Float>(N_("Glossy Depth"));
+ b.add_output<decl::Float>(N_("Transparent Depth"));
+ b.add_output<decl::Float>(N_("Transmission Depth"));
+}
+
+static int node_shader_gpu_light_path(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "node_light_path", in, out);
+}
+
+} // namespace blender::nodes::node_shader_light_path_cc
+
+/* node type definition */
+void register_node_type_sh_light_path()
+{
+ namespace file_ns = blender::nodes::node_shader_light_path_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_LIGHT_PATH, "Light Path", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_light_path);
+
+ nodeRegisterType(&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 5ea194ddc83..bc7ca661a77 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -21,49 +21,173 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include <algorithm>
+
+#include "node_shader_util.hh"
#include "BLI_math_base_safe.h"
-namespace blender::nodes {
+#include "NOD_socket_search_link.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_map_range_cc {
+
+NODE_STORAGE_FUNCS(NodeMapRange)
static void sh_node_map_range_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Value").min(-10000.0f).max(10000.0f).default_value(1.0f);
- b.add_input<decl::Float>("From Min").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("From Max").min(-10000.0f).max(10000.0f).default_value(1.0f);
- b.add_input<decl::Float>("To Min").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("To Max").min(-10000.0f).max(10000.0f).default_value(1.0f);
- b.add_input<decl::Float>("Steps").min(-10000.0f).max(10000.0f).default_value(4.0f);
- b.add_output<decl::Float>("Result");
-};
+ b.add_input<decl::Float>(N_("Value")).min(-10000.0f).max(10000.0f).default_value(1.0f);
+ b.add_input<decl::Float>(N_("From Min")).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("From Max")).min(-10000.0f).max(10000.0f).default_value(1.0f);
+ 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_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "interpolation_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ if (!ELEM(RNA_enum_get(ptr, "interpolation_type"),
+ NODE_MAP_RANGE_SMOOTHSTEP,
+ NODE_MAP_RANGE_SMOOTHERSTEP)) {
+ uiItemR(layout, ptr, "clamp", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+}
-static void node_shader_update_map_range(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_map_range(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sockSteps = nodeFindSocket(node, SOCK_IN, "Steps");
- nodeSetSocketAvailability(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 = MEM_cnew<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)
+class SocketSearchOp {
+ public:
+ std::string socket_name;
+ CustomDataType data_type;
+ int interpolation_type = NODE_MAP_RANGE_LINEAR;
+
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("ShaderNodeMapRange");
+ node_storage(node).data_type = data_type;
+ node_storage(node).interpolation_type = interpolation_type;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
+};
+
+static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+{
+ switch (socket.type) {
+ case SOCK_FLOAT:
+ case SOCK_BOOLEAN:
+ case SOCK_INT:
+ return CD_PROP_FLOAT;
+ case SOCK_VECTOR:
+ case SOCK_RGBA:
+ return CD_PROP_FLOAT3;
+ default:
+ return {};
+ }
+}
+
+static void node_map_range_gather_link_searches(GatherLinkSearchOpParams &params)
{
- 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";
+ const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ if (!type) {
+ return;
+ }
+
+ if (params.in_out() == SOCK_IN) {
+ if (*type == CD_PROP_FLOAT3) {
+ params.add_item(IFACE_("Vector"), SocketSearchOp{"Vector", *type}, 0);
+ }
+ else {
+ params.add_item(IFACE_("Value"), SocketSearchOp{"Value", *type}, 0);
+ }
+ params.add_item(IFACE_("From Min"), SocketSearchOp{"From Min", *type}, -1);
+ params.add_item(IFACE_("From Max"), SocketSearchOp{"From Max", *type}, -1);
+ params.add_item(IFACE_("To Min"), SocketSearchOp{"To Min", *type}, -2);
+ params.add_item(IFACE_("To Max"), SocketSearchOp{"To Max", *type}, -2);
+ params.add_item(IFACE_("Steps"), SocketSearchOp{"Steps", *type, NODE_MAP_RANGE_STEPPED}, -3);
+ }
+ else {
+ if (*type == CD_PROP_FLOAT3) {
+ params.add_item(IFACE_("Vector"), SocketSearchOp{"Vector", *type});
+ }
+ else {
+ params.add_item(IFACE_("Result"), SocketSearchOp{"Result", *type});
+ }
+ }
+}
+
+static const char *gpu_shader_get_name(int mode, bool use_vector)
+{
+ 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 +199,205 @@ 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;
}
+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 = math::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 = math::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ factor = math::safe_divide(math::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 = math::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 = math::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 +447,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 +491,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 +570,107 @@ 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::node_shader_map_range_cc
+
+void register_node_type_sh_map_range()
{
- static bNodeType ntype;
+ namespace file_ns = blender::nodes::node_shader_map_range_cc;
- 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_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;
+ static bNodeType ntype;
+ sh_fn_node_type_base(&ntype, SH_NODE_MAP_RANGE, "Map Range", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_map_range_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_map_range;
+ node_type_init(&ntype, file_ns::node_shader_init_map_range);
+ node_type_storage(
+ &ntype, "NodeMapRange", node_free_standard_storage, node_copy_standard_storage);
+ node_type_update(&ntype, file_ns::node_shader_update_map_range);
+ node_type_gpu(&ntype, file_ns::gpu_shader_map_range);
+ ntype.build_multi_function = file_ns::sh_node_map_range_build_multi_function;
+ ntype.gather_link_search_ops = file_ns::node_map_range_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
deleted file mode 100644
index 774e7fed029..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** MAPPING ******************** */
-static bNodeSocketTemplate sh_node_mapping_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_NONE},
- {SOCK_VECTOR, N_("Location"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION},
- {SOCK_VECTOR, N_("Rotation"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_EULER},
- {SOCK_VECTOR, N_("Scale"), 1.0f, 1.0f, 1.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_XYZ},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_mapping_out[] = {
- {SOCK_VECTOR, N_("Vector")},
- {-1, ""},
-};
-
-static int gpu_shader_mapping(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- static const char *names[] = {
- [NODE_MAPPING_TYPE_POINT] = "mapping_point",
- [NODE_MAPPING_TYPE_TEXTURE] = "mapping_texture",
- [NODE_MAPPING_TYPE_VECTOR] = "mapping_vector",
- [NODE_MAPPING_TYPE_NORMAL] = "mapping_normal",
- };
-
- if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
- return GPU_stack_link(mat, node, names[node->custom1], in, out);
- }
-
- return 0;
-}
-
-static void node_shader_update_mapping(bNodeTree *UNUSED(ntree), bNode *node)
-{
- bNodeSocket *sock = nodeFindSocket(node, SOCK_IN, "Location");
- nodeSetSocketAvailability(
- sock, ELEM(node->custom1, NODE_MAPPING_TYPE_POINT, NODE_MAPPING_TYPE_TEXTURE));
-}
-
-void register_node_type_sh_mapping(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_mapping_in, sh_node_mapping_out);
- node_type_gpu(&ntype, gpu_shader_mapping);
- node_type_update(&ntype, node_shader_update_mapping);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.cc b/source/blender/nodes/shader/nodes/node_shader_mapping.cc
new file mode 100644
index 00000000000..19c3a26796e
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.cc
@@ -0,0 +1,110 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_mapping_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector"))
+ .default_value({0.0f, 0.0f, 0.0f})
+ .min(-FLT_MAX)
+ .max(FLT_MAX);
+ b.add_input<decl::Vector>(N_("Location"))
+ .default_value({0.0f, 0.0f, 0.0f})
+ .min(-FLT_MAX)
+ .max(FLT_MAX)
+ .subtype(PROP_TRANSLATION);
+ b.add_input<decl::Vector>(N_("Rotation"))
+ .default_value({0.0f, 0.0f, 0.0f})
+ .min(-FLT_MAX)
+ .max(FLT_MAX)
+ .subtype(PROP_EULER);
+ b.add_input<decl::Vector>(N_("Scale"))
+ .default_value({1.0f, 1.0f, 1.0f})
+ .min(-FLT_MAX)
+ .max(FLT_MAX)
+ .subtype(PROP_XYZ);
+ b.add_output<decl::Vector>(N_("Vector"));
+}
+
+static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "vector_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
+
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_MAPPING_TYPE_POINT:
+ return "mapping_point";
+ case NODE_MAPPING_TYPE_TEXTURE:
+ return "mapping_texture";
+ case NODE_MAPPING_TYPE_VECTOR:
+ return "mapping_vector";
+ case NODE_MAPPING_TYPE_NORMAL:
+ return "mapping_normal";
+ }
+ return nullptr;
+}
+
+static int gpu_shader_mapping(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ if (gpu_shader_get_name(node->custom1)) {
+ return GPU_stack_link(mat, node, gpu_shader_get_name(node->custom1), in, out);
+ }
+
+ return 0;
+}
+
+static void node_shader_update_mapping(bNodeTree *ntree, bNode *node)
+{
+ bNodeSocket *sock = nodeFindSocket(node, SOCK_IN, "Location");
+ nodeSetSocketAvailability(
+ ntree, sock, ELEM(node->custom1, NODE_MAPPING_TYPE_POINT, NODE_MAPPING_TYPE_TEXTURE));
+}
+
+} // namespace blender::nodes::node_shader_mapping_cc
+
+void register_node_type_sh_mapping()
+{
+ namespace file_ns = blender::nodes::node_shader_mapping_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_mapping;
+ node_type_gpu(&ntype, file_ns::gpu_shader_mapping);
+ node_type_update(&ntype, file_ns::node_shader_update_mapping);
+
+ 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 96d1be49c04..50585405cbf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_math.cc
@@ -21,24 +21,67 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
#include "NOD_math_functions.hh"
+#include "NOD_socket_search_link.hh"
+
+#include "RNA_enum_types.h"
/* **************** SCALAR MATH ******************** */
-namespace blender::nodes {
+namespace blender::nodes::node_shader_math_cc {
static void sh_node_math_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Value").default_value(0.5f).min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Value", "Value_001").default_value(0.5f).min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Value", "Value_002").default_value(0.5f).min(-10000.0f).max(10000.0f);
- b.add_output<decl::Float>("Value");
+ b.add_input<decl::Float>(N_("Value")).default_value(0.5f).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("Value"), "Value_001")
+ .default_value(0.5f)
+ .min(-10000.0f)
+ .max(10000.0f);
+ b.add_input<decl::Float>(N_("Value"), "Value_002")
+ .default_value(0.5f)
+ .min(-10000.0f)
+ .max(10000.0f);
+ b.add_output<decl::Float>(N_("Value"));
+}
+
+class SocketSearchOp {
+ public:
+ std::string socket_name;
+ NodeMathOperation mode = NODE_MATH_ADD;
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("ShaderNodeMath");
+ node.custom1 = mode;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
};
-} // namespace blender::nodes
+static void sh_node_math_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ if (!params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ return;
+ }
+
+ const bool is_geometry_node_tree = params.node_tree().type == NTREE_GEOMETRY;
+ const int weight = ELEM(params.other_socket().type, SOCK_FLOAT, SOCK_BOOLEAN, SOCK_INT) ? 0 : -1;
+
+ for (const EnumPropertyItem *item = rna_enum_node_math_items; item->identifier != nullptr;
+ item++) {
+ if (item->name != nullptr && item->identifier[0] != '\0') {
+ const int gn_weight =
+ (is_geometry_node_tree &&
+ ELEM(item->value, NODE_MATH_COMPARE, NODE_MATH_GREATER_THAN, NODE_MATH_LESS_THAN)) ?
+ -1 :
+ weight;
+ params.add_item(
+ IFACE_(item->name), SocketSearchOp{"Value", (NodeMathOperation)item->value}, gn_weight);
+ }
+ }
+}
static const char *gpu_shader_get_name(int mode)
{
@@ -82,7 +125,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) {
@@ -91,7 +135,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;
});
@@ -102,7 +146,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) {
@@ -154,16 +198,21 @@ static void sh_node_math_build_multi_function(blender::nodes::NodeMultiFunctionB
}
}
-void register_node_type_sh_math(void)
+} // namespace blender::nodes::node_shader_math_cc
+
+void register_node_type_sh_math()
{
+ namespace file_ns = blender::nodes::node_shader_math_cc;
+
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);
- node_type_gpu(&ntype, gpu_shader_math);
+ sh_fn_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_math_declare;
+ ntype.labelfunc = node_math_label;
+ node_type_gpu(&ntype, file_ns::gpu_shader_math);
node_type_update(&ntype, node_math_update);
- ntype.build_multi_function = sh_node_math_build_multi_function;
+ ntype.build_multi_function = file_ns::sh_node_math_build_multi_function;
+ ntype.gather_link_search_ops = file_ns::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 d4d02e80ada..9678e86d289 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc
@@ -21,45 +21,17 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_mix_rgb_cc {
static void sh_node_mix_rgb_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("Fac").default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
- b.add_input<decl::Color>("Color1").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_input<decl::Color>("Color2").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_output<decl::Color>("Color");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_mix_rgb(void *UNUSED(data),
- int UNUSED(thread),
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- /* stack order in: fac, col1, col2 */
- /* stack order out: col */
- float col[3];
- float fac;
- float vec[3];
-
- nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
- CLAMP(fac, 0.0f, 1.0f);
-
- nodestack_get_vec(col, SOCK_VECTOR, in[1]);
- nodestack_get_vec(vec, SOCK_VECTOR, in[2]);
-
- ramp_blend(node->custom1, col, fac, vec);
- if (node->custom2 & SHD_MIXRGB_CLAMP) {
- CLAMP3(col, 0.0f, 1.0f);
- }
- copy_v3_v3(out[0]->vec, col);
+ b.add_input<decl::Float>(N_("Fac")).default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Color1")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
+ b.add_input<decl::Color>(N_("Color2")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
+ b.add_output<decl::Color>(N_("Color"));
}
static const char *gpu_shader_get_name(int mode)
@@ -183,16 +155,19 @@ 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)
+} // namespace blender::nodes::node_shader_mix_rgb_cc
+
+void register_node_type_sh_mix_rgb()
{
+ namespace file_ns = blender::nodes::node_shader_mix_rgb_cc;
+
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);
- 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;
+ sh_fn_node_type_base(&ntype, SH_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR);
+ ntype.declare = file_ns::sh_node_mix_rgb_declare;
+ ntype.labelfunc = node_blend_label;
+ node_type_gpu(&ntype, file_ns::gpu_shader_mix_rgb);
+ ntype.build_multi_function = file_ns::sh_node_mix_rgb_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_shader.c b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc
index 33cbf34543c..d9aa906e451 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mix_shader.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mix_shader.cc
@@ -17,21 +17,17 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_mix_shader_cc {
-static bNodeSocketTemplate sh_node_mix_shader_in[] = {
- {SOCK_FLOAT, N_("Fac"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_SHADER, N_("Shader")},
- {SOCK_SHADER, N_("Shader")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_mix_shader_out[] = {
- {SOCK_SHADER, N_("Shader")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Fac")).default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+ b.add_input<decl::Shader>(N_("Shader"));
+ b.add_input<decl::Shader>(N_("Shader"), "Shader_001");
+ b.add_output<decl::Shader>(N_("Shader"));
+}
static int node_shader_gpu_mix_shader(GPUMaterial *mat,
bNode *node,
@@ -42,16 +38,18 @@ static int node_shader_gpu_mix_shader(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_mix_shader", in, out);
}
+} // namespace blender::nodes::node_shader_mix_shader_cc
+
/* node type definition */
-void register_node_type_sh_mix_shader(void)
+void register_node_type_sh_mix_shader()
{
+ namespace file_ns = blender::nodes::node_shader_mix_shader_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_mix_shader_in, sh_node_mix_shader_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_mix_shader);
+ sh_node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_mix_shader);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.cc
index 83d5abcba67..e677f36e425 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal.cc
@@ -21,37 +21,23 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** NORMAL ******************** */
-static bNodeSocketTemplate sh_node_normal_in[] = {
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, PROP_DIRECTION},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_normal_cc {
-static bNodeSocketTemplate sh_node_normal_out[] = {
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, PROP_DIRECTION},
- {SOCK_FLOAT, N_("Dot")},
- {-1, ""},
-};
-
-/* generates normal, does dot product */
-static void node_shader_exec_normal(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
+static void node_declare(NodeDeclarationBuilder &b)
{
- float vec[3];
-
- /* stack order input: normal */
- /* stack order output: normal, value */
-
- nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
-
- /* render normals point inside... the widget points outside */
- out[1]->vec[0] = -dot_v3v3(vec, out[0]->vec);
+ b.add_input<decl::Vector>(N_("Normal"))
+ .default_value({0.0f, 0.0f, 1.0f})
+ .min(-1.0f)
+ .max(1.0f)
+ .subtype(PROP_DIRECTION);
+ b.add_output<decl::Vector>(N_("Normal"))
+ .default_value({0.0f, 0.0f, 1.0f})
+ .min(-1.0f)
+ .max(1.0f)
+ .subtype(PROP_DIRECTION);
+ b.add_output<decl::Float>(N_("Dot"));
}
static int gpu_shader_normal(GPUMaterial *mat,
@@ -64,14 +50,17 @@ static int gpu_shader_normal(GPUMaterial *mat,
return GPU_stack_link(mat, node, "normal_new_shading", in, out, vec);
}
-void register_node_type_sh_normal(void)
+} // namespace blender::nodes::node_shader_normal_cc
+
+void register_node_type_sh_normal()
{
+ namespace file_ns = blender::nodes::node_shader_normal_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_normal);
- node_type_gpu(&ntype, gpu_shader_normal);
+ sh_node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_normal);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc
index 6c4f2070035..9eadb6ce014 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc
@@ -17,34 +17,43 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "BKE_context.h"
-static bNodeSocketTemplate sh_node_normal_map_in[] = {
- {SOCK_FLOAT, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f},
- {SOCK_RGBA, N_("Color"), 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_normal_map_out[] = {
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_normal_map_cc {
-static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_declare(NodeDeclarationBuilder &b)
{
- NodeShaderNormalMap *attr = MEM_callocN(sizeof(NodeShaderNormalMap), "NodeShaderNormalMap");
- node->storage = attr;
+ b.add_input<decl::Float>(N_("Strength")).default_value(1.0f).min(0.0f).max(10.0f);
+ b.add_input<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 1.0f, 1.0f});
+ b.add_output<decl::Vector>(N_("Normal"));
+}
+
+static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "space", UI_ITEM_R_SPLIT_EMPTY_NAME, "", 0);
+
+ if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) {
+ PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
+
+ if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
+ PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
+ }
+ else {
+ uiItemR(layout, ptr, "uv_map", UI_ITEM_R_SPLIT_EMPTY_NAME, "", 0);
+ }
+ }
}
-static void node_shader_exec_normal_map(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **UNUSED(in),
- bNodeStack **UNUSED(out))
+static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node)
{
+ NodeShaderNormalMap *attr = MEM_cnew<NodeShaderNormalMap>("NodeShaderNormalMap");
+ node->storage = attr;
}
static int gpu_shader_normal_map(GPUMaterial *mat,
@@ -53,15 +62,16 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- NodeShaderNormalMap *nm = node->storage;
+ NodeShaderNormalMap *nm = static_cast<NodeShaderNormalMap *>(node->storage);
GPUNodeLink *strength;
if (in[0].link) {
strength = in[0].link;
}
else if (node->original) {
- bNodeSocket *socket = BLI_findlink(&node->original->inputs, 0);
- bNodeSocketValueFloat *socket_data = socket->default_value;
+ bNodeSocket *socket = static_cast<bNodeSocket *>(BLI_findlink(&node->original->inputs, 0));
+ bNodeSocketValueFloat *socket_data = static_cast<bNodeSocketValueFloat *>(
+ socket->default_value);
strength = GPU_uniform(&socket_data->value);
}
else {
@@ -73,8 +83,8 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
newnormal = in[1].link;
}
else if (node->original) {
- bNodeSocket *socket = BLI_findlink(&node->original->inputs, 1);
- bNodeSocketValueRGBA *socket_data = socket->default_value;
+ bNodeSocket *socket = static_cast<bNodeSocket *>(BLI_findlink(&node->original->inputs, 1));
+ bNodeSocketValueRGBA *socket_data = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
newnormal = GPU_uniform(socket_data->value);
}
else {
@@ -111,19 +121,23 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
return true;
}
+} // namespace blender::nodes::node_shader_normal_map_cc
+
/* node type definition */
-void register_node_type_sh_normal_map(void)
+void register_node_type_sh_normal_map()
{
+ namespace file_ns = blender::nodes::node_shader_normal_map_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_NORMAL_MAP, "Normal Map", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_normal_map_in, sh_node_normal_map_out);
+ sh_node_type_base(&ntype, SH_NODE_NORMAL_MAP, "Normal Map", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_normal_map;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_normal_map);
+ node_type_init(&ntype, file_ns::node_shader_init_normal_map);
node_type_storage(
&ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, gpu_shader_normal_map);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_normal_map);
+ node_type_gpu(&ntype, file_ns::gpu_shader_normal_map);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.cc
index f3eb5dcc26d..75c9c8f9206 100644
--- a/source/blender/nodes/shader/nodes/node_shader_object_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_object_info.cc
@@ -17,18 +17,18 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_object_info_cc {
-static bNodeSocketTemplate sh_node_object_info_out[] = {
- {SOCK_VECTOR, N_("Location"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Object Index"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Material Index"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("Location"));
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Object Index"));
+ b.add_output<decl::Float>(N_("Material Index"));
+ b.add_output<decl::Float>(N_("Random"));
+}
static int node_shader_gpu_object_info(GPUMaterial *mat,
bNode *node,
@@ -42,13 +42,17 @@ static int node_shader_gpu_object_info(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_object_info", in, out, GPU_constant(&index));
}
-void register_node_type_sh_object_info(void)
+} // namespace blender::nodes::node_shader_object_info_cc
+
+void register_node_type_sh_object_info()
{
+ namespace file_ns = blender::nodes::node_shader_object_info_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_object_info_out);
- node_type_gpu(&ntype, node_shader_gpu_object_info);
+ sh_node_type_base(&ntype, SH_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_object_info);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_aov.c b/source/blender/nodes/shader/nodes/node_shader_output_aov.cc
index 18c8edfe41c..b5177014f3a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_aov.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_aov.cc
@@ -17,21 +17,29 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
#include "BLI_hash.h"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_output_aov_in[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_output_aov_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Value")).default_value(0.0f).min(0.0f).max(1.0f);
+}
+
+static void node_shader_buts_output_aov(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "name", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
static void node_shader_init_output_aov(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderOutputAOV *aov = MEM_callocN(sizeof(NodeShaderOutputAOV), "NodeShaderOutputAOV");
+ NodeShaderOutputAOV *aov = MEM_cnew<NodeShaderOutputAOV>("NodeShaderOutputAOV");
node->storage = aov;
}
@@ -49,20 +57,24 @@ static int node_shader_gpu_output_aov(GPUMaterial *mat,
return true;
}
+} // namespace blender::nodes::node_shader_output_aov_cc
+
/* node type definition */
-void register_node_type_sh_output_aov(void)
+void register_node_type_sh_output_aov()
{
+ namespace file_ns = blender::nodes::node_shader_output_aov_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_AOV, "AOV Output", NODE_CLASS_OUTPUT, 0);
- node_type_socket_templates(&ntype, sh_node_output_aov_in, NULL);
- node_type_init(&ntype, node_shader_init_output_aov);
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_AOV, "AOV Output", NODE_CLASS_OUTPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_output_aov;
+ node_type_init(&ntype, file_ns::node_shader_init_output_aov);
node_type_storage(
&ntype, "NodeShaderOutputAOV", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_output_aov);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_output_aov);
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
+ ntype.no_muting = true;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_light.c b/source/blender/nodes/shader/nodes/node_shader_output_light.cc
index 722202bafdc..0c8288f801b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_light.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_light.cc
@@ -17,27 +17,27 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_output_light_cc {
-static bNodeSocketTemplate sh_node_output_light_in[] = {
- {SOCK_SHADER, N_("Surface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Shader>(N_("Surface"));
+}
+
+} // namespace blender::nodes::node_shader_output_light_cc
/* node type definition */
-void register_node_type_sh_output_light(void)
+void register_node_type_sh_output_light()
{
- static bNodeType ntype;
+ namespace file_ns = blender::nodes::node_shader_output_light_cc;
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_LIGHT, "Light Output", NODE_CLASS_OUTPUT, 0);
- node_type_socket_templates(&ntype, sh_node_output_light_in, NULL);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
+ static bNodeType ntype;
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_LIGHT, "Light Output", NODE_CLASS_OUTPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.no_muting = true;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_linestyle.c b/source/blender/nodes/shader/nodes/node_shader_output_linestyle.c
deleted file mode 100644
index 5b4ebf21f5f..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_output_linestyle.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_output_linestyle_in[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 0.0f, 1.0f, 1.0f},
- {SOCK_FLOAT, N_("Color Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Alpha Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {-1, ""},
-};
-
-/* node type definition */
-void register_node_type_sh_output_linestyle(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_LINESTYLE, "Line Style Output", NODE_CLASS_OUTPUT, 0);
- node_type_socket_templates(&ntype, sh_node_output_linestyle_in, NULL);
- node_type_init(&ntype, NULL);
-
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc b/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc
new file mode 100644
index 00000000000..9b6c3292e75
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_linestyle.cc
@@ -0,0 +1,72 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_output_linestyle_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 0.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Color Fac"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Alpha"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Alpha Fac"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+}
+
+static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row, *col;
+
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRow(col, true);
+ uiItemR(row, ptr, "blend_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(col, ptr, "use_clamp", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
+
+} // namespace blender::nodes::node_shader_output_linestyle_cc
+
+/* node type definition */
+void register_node_type_sh_output_linestyle()
+{
+ namespace file_ns = blender::nodes::node_shader_output_linestyle_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_LINESTYLE, "Line Style Output", NODE_CLASS_OUTPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_buts_output_linestyle;
+ ntype.no_muting = true;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.c b/source/blender/nodes/shader/nodes/node_shader_output_material.c
deleted file mode 100644
index 5b6d2914ccf..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_output_material.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-#include "BKE_scene.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_output_material_in[] = {
- {SOCK_SHADER, N_("Surface")},
- {SOCK_SHADER, N_("Volume")},
- {SOCK_VECTOR,
- N_("Displacement"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static int node_shader_gpu_output_material(GPUMaterial *mat,
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *UNUSED(out))
-{
- GPUNodeLink *outlink_surface, *outlink_volume, *outlink_displacement, *outlink_thickness;
- /* Passthrough node in order to do the right socket conversions (important for displacement). */
- if (in[0].link) {
- GPU_link(mat, "node_output_material_surface", in[0].link, &outlink_surface);
- GPU_material_output_surface(mat, outlink_surface);
- }
- if (in[1].link) {
- GPU_link(mat, "node_output_material_volume", in[1].link, &outlink_volume);
- GPU_material_output_volume(mat, outlink_volume);
- }
- if (in[2].link) {
- GPU_link(mat, "node_output_material_displacement", in[2].link, &outlink_displacement);
- GPU_material_output_displacement(mat, outlink_displacement);
- }
- if (in[3].link) {
- GPU_link(mat, "node_output_material_thickness", in[3].link, &outlink_thickness);
- GPU_material_output_thickness(mat, outlink_thickness);
- }
- return true;
-}
-
-/* node type definition */
-void register_node_type_sh_output_material(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_MATERIAL, "Material Output", NODE_CLASS_OUTPUT, 0);
- node_type_socket_templates(&ntype, sh_node_output_material_in, NULL);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_output_material);
-
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_material.cc b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
new file mode 100644
index 00000000000..5fc95b92e3f
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_material.cc
@@ -0,0 +1,83 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "BKE_scene.h"
+
+namespace blender::nodes::node_shader_output_material_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Shader>(N_("Surface"));
+ b.add_input<decl::Shader>(N_("Volume"));
+ b.add_input<decl::Vector>(N_("Displacement")).hide_value();
+}
+
+static int node_shader_gpu_output_material(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ GPUNodeLink *outlink, *alpha_threshold_link, *shadow_threshold_link;
+ Material *ma = GPU_material_get_material(mat);
+
+ static float no_alpha_threshold = -1.0f;
+ if (ma) {
+ alpha_threshold_link = GPU_uniform((ma->blend_method == MA_BM_CLIP) ? &ma->alpha_threshold :
+ &no_alpha_threshold);
+ shadow_threshold_link = GPU_uniform((ma->blend_shadow == MA_BS_CLIP) ? &ma->alpha_threshold :
+ &no_alpha_threshold);
+ }
+ else {
+ alpha_threshold_link = GPU_uniform(&no_alpha_threshold);
+ shadow_threshold_link = GPU_uniform(&no_alpha_threshold);
+ }
+
+ GPU_stack_link(mat,
+ node,
+ "node_output_material",
+ in,
+ out,
+ alpha_threshold_link,
+ shadow_threshold_link,
+ &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return true;
+}
+
+} // namespace blender::nodes::node_shader_output_material_cc
+
+/* node type definition */
+void register_node_type_sh_output_material()
+{
+ namespace file_ns = blender::nodes::node_shader_output_material_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_MATERIAL, "Material Output", NODE_CLASS_OUTPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_output_material);
+
+ ntype.no_muting = true;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.cc
index eaecfc266a3..a3509fd3ff4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.cc
@@ -17,15 +17,15 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_output_world_cc {
-static bNodeSocketTemplate sh_node_output_world_in[] = {
- {SOCK_SHADER, N_("Surface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_SHADER, N_("Volume"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Shader>(N_("Surface"));
+ b.add_input<decl::Shader>(N_("Volume"));
+}
static int node_shader_gpu_output_world(GPUMaterial *mat,
bNode *UNUSED(node),
@@ -45,19 +45,20 @@ static int node_shader_gpu_output_world(GPUMaterial *mat,
return true;
}
+} // namespace blender::nodes::node_shader_output_world_cc
+
/* node type definition */
-void register_node_type_sh_output_world(void)
+void register_node_type_sh_output_world()
{
+ namespace file_ns = blender::nodes::node_shader_output_world_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_WORLD, "World Output", NODE_CLASS_OUTPUT, 0);
- node_type_socket_templates(&ntype, sh_node_output_world_in, NULL);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_output_world);
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT_WORLD, "World Output", NODE_CLASS_OUTPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_output_world);
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
+ ntype.no_muting = true;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.cc
index 75966843294..5792282fa0f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.cc
@@ -17,30 +17,25 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
+
#include "RE_texture.h"
-static bNodeSocketTemplate outputs[] = {
- {SOCK_FLOAT, "Index"},
- {SOCK_FLOAT, "Random"},
- {SOCK_FLOAT, "Age"},
- {SOCK_FLOAT, "Lifetime"},
- {SOCK_VECTOR, "Location"},
+namespace blender::nodes::node_shader_particle_info_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>(N_("Index"));
+ b.add_output<decl::Float>(N_("Random"));
+ b.add_output<decl::Float>(N_("Age"));
+ b.add_output<decl::Float>(N_("Lifetime"));
+ b.add_output<decl::Vector>(N_("Location"));
#if 0 /* quaternion sockets not yet supported */
- {SOCK_QUATERNION, "Rotation"},
+ b.add_output<decl::Quaternion>(N_("Rotation"));
#endif
- {SOCK_FLOAT, "Size"},
- {SOCK_VECTOR, "Velocity"},
- {SOCK_VECTOR, "Angular Velocity"},
- {-1, ""},
-};
-static void node_shader_exec_particle_info(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **UNUSED(in),
- bNodeStack **UNUSED(out))
-{
+ b.add_output<decl::Float>(N_("Size"));
+ b.add_output<decl::Vector>(N_("Velocity"));
+ b.add_output<decl::Vector>(N_("Angular Velocity"));
}
static int gpu_shader_particle_info(GPUMaterial *mat,
@@ -54,15 +49,18 @@ static int gpu_shader_particle_info(GPUMaterial *mat,
return GPU_stack_link(mat, node, "particle_info", in, out);
}
+} // namespace blender::nodes::node_shader_particle_info_cc
+
/* node type definition */
-void register_node_type_sh_particle_info(void)
+void register_node_type_sh_particle_info()
{
+ namespace file_ns = blender::nodes::node_shader_particle_info_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_PARTICLE_INFO, "Particle Info", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, outputs);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_particle_info);
- node_type_gpu(&ntype, gpu_shader_particle_info);
+ sh_node_type_base(&ntype, SH_NODE_PARTICLE_INFO, "Particle Info", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_particle_info);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_point_info.cc b/source/blender/nodes/shader/nodes/node_shader_point_info.cc
new file mode 100644
index 00000000000..adc58ca065a
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_point_info.cc
@@ -0,0 +1,54 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_point_info_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("Position"));
+ b.add_output<decl::Float>(N_("Radius"));
+ b.add_output<decl::Float>(N_("Random"));
+}
+
+static int node_shader_gpu_point_info(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "node_point_info", in, out);
+}
+
+} // namespace blender::nodes::node_shader_point_info_cc
+
+/* node type definition */
+void register_node_type_sh_point_info()
+{
+ namespace file_ns = blender::nodes::node_shader_point_info_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_POINT_INFO, "Point Info", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_point_info);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb.c b/source/blender/nodes/shader/nodes/node_shader_rgb.cc
index 0bdef9a2a17..f3b83b72232 100644
--- a/source/blender/nodes/shader/nodes/node_shader_rgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_rgb.cc
@@ -21,13 +21,14 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** RGB ******************** */
-static bNodeSocketTemplate sh_node_rgb_out[] = {
- {SOCK_RGBA, N_("Color"), 0.5f, 0.5f, 0.5f, 1.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_rgb_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
+}
static int gpu_shader_rgb(GPUMaterial *mat,
bNode *node,
@@ -39,13 +40,17 @@ static int gpu_shader_rgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "set_rgba", in, out, link);
}
-void register_node_type_sh_rgb(void)
+} // namespace blender::nodes::node_shader_rgb_cc
+
+void register_node_type_sh_rgb()
{
+ namespace file_ns = blender::nodes::node_shader_rgb_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_rgb_out);
- node_type_gpu(&ntype, gpu_shader_rgb);
+ sh_node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_rgb);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
new file mode 100644
index 00000000000..13ba056d9ee
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_rgb_to_bw.cc
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "IMB_colormanagement.h"
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_rgb_to_bw_cc {
+
+static void sh_node_rgbtobw_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
+ b.add_output<decl::Float>(N_("Val"));
+}
+
+static int gpu_shader_rgbtobw(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "rgbtobw", in, out);
+}
+
+} // namespace blender::nodes::node_shader_rgb_to_bw_cc
+
+void register_node_type_sh_rgbtobw()
+{
+ namespace file_ns = blender::nodes::node_shader_rgb_to_bw_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_rgbtobw_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_rgbtobw);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_script.c b/source/blender/nodes/shader/nodes/node_shader_script.c
deleted file mode 100644
index 42ab272de0e..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_script.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** Script ******************** */
-
-static void init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeShaderScript *nss = MEM_callocN(sizeof(NodeShaderScript), "shader script node");
- node->storage = nss;
-}
-
-static void node_free_script(bNode *node)
-{
- NodeShaderScript *nss = node->storage;
-
- if (nss) {
- if (nss->bytecode) {
- MEM_freeN(nss->bytecode);
- }
-
- MEM_freeN(nss);
- }
-}
-
-static void node_copy_script(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
-{
- NodeShaderScript *src_nss = src_node->storage;
- NodeShaderScript *dest_nss = MEM_dupallocN(src_nss);
-
- if (src_nss->bytecode) {
- dest_nss->bytecode = MEM_dupallocN(src_nss->bytecode);
- }
-
- dest_node->storage = dest_nss;
-}
-
-void register_node_type_sh_script(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_SCRIPT, "Script", NODE_CLASS_SCRIPT, 0);
- node_type_init(&ntype, init);
- node_type_storage(&ntype, "NodeShaderScript", node_free_script, node_copy_script);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_script.cc b/source/blender/nodes/shader/nodes/node_shader_script.cc
new file mode 100644
index 00000000000..e6af90fa588
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_script.cc
@@ -0,0 +1,112 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_script_cc {
+
+static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, ptr, "mode", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+
+ row = uiLayoutRow(layout, true);
+
+ if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_INTERNAL) {
+ uiItemR(row, ptr, "script", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+ else {
+ uiItemR(row, ptr, "filepath", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+
+ uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update");
+}
+
+static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemS(layout);
+
+ node_shader_buts_script(layout, C, ptr);
+
+#if 0 /* not implemented yet */
+ if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL) {
+ uiItemR(layout, ptr, "use_auto_update", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+#endif
+}
+
+static void init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderScript *nss = MEM_cnew<NodeShaderScript>("shader script node");
+ node->storage = nss;
+}
+
+static void node_free_script(bNode *node)
+{
+ NodeShaderScript *nss = static_cast<NodeShaderScript *>(node->storage);
+
+ if (nss) {
+ if (nss->bytecode) {
+ MEM_freeN(nss->bytecode);
+ }
+
+ MEM_freeN(nss);
+ }
+}
+
+static void node_copy_script(bNodeTree *UNUSED(dest_ntree),
+ bNode *dest_node,
+ const bNode *src_node)
+{
+ NodeShaderScript *src_nss = static_cast<NodeShaderScript *>(src_node->storage);
+ NodeShaderScript *dest_nss = static_cast<NodeShaderScript *>(MEM_dupallocN(src_nss));
+
+ if (src_nss->bytecode) {
+ dest_nss->bytecode = static_cast<char *>(MEM_dupallocN(src_nss->bytecode));
+ }
+
+ dest_node->storage = dest_nss;
+}
+
+} // namespace blender::nodes::node_shader_script_cc
+
+void register_node_type_sh_script()
+{
+ namespace file_ns = blender::nodes::node_shader_script_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_SCRIPT, "Script", NODE_CLASS_SCRIPT);
+ ntype.draw_buttons = file_ns::node_shader_buts_script;
+ ntype.draw_buttons_ex = file_ns::node_shader_buts_script_ex;
+ node_type_init(&ntype, file_ns::init);
+ node_type_storage(
+ &ntype, "NodeShaderScript", file_ns::node_free_script, file_ns::node_copy_script);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
deleted file mode 100644
index dfecb830b35..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** SEPARATE HSV ******************** */
-static bNodeSocketTemplate sh_node_sephsv_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f},
- {-1, ""},
-};
-static bNodeSocketTemplate sh_node_sephsv_out[] = {
- {SOCK_FLOAT, N_("H")},
- {SOCK_FLOAT, N_("S")},
- {SOCK_FLOAT, N_("V")},
- {-1, ""},
-};
-
-static void node_shader_exec_sephsv(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float col[3];
- nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
- rgb_to_hsv(col[0], col[1], col[2], &out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
-}
-
-static int gpu_shader_sephsv(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "separate_hsv", in, out);
-}
-
-void register_node_type_sh_sephsv(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTER, 0);
- node_type_socket_templates(&ntype, sh_node_sephsv_in, sh_node_sephsv_out);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_sephsv);
- node_type_gpu(&ntype, gpu_shader_sephsv);
-
- nodeRegisterType(&ntype);
-}
-
-/* **************** COMBINE HSV ******************** */
-static bNodeSocketTemplate sh_node_combhsv_in[] = {
- {SOCK_FLOAT, N_("H"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
- {SOCK_FLOAT, N_("S"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
- {SOCK_FLOAT, N_("V"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
- {-1, ""},
-};
-static bNodeSocketTemplate sh_node_combhsv_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
-
-static void node_shader_exec_combhsv(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float h, s, v;
- nodestack_get_vec(&h, SOCK_FLOAT, in[0]);
- nodestack_get_vec(&s, SOCK_FLOAT, in[1]);
- nodestack_get_vec(&v, SOCK_FLOAT, in[2]);
-
- hsv_to_rgb(h, s, v, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
-}
-
-static int gpu_shader_combhsv(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "combine_hsv", in, out);
-}
-
-void register_node_type_sh_combhsv(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTER, 0);
- node_type_socket_templates(&ntype, sh_node_combhsv_in, sh_node_combhsv_out);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_combhsv);
- node_type_gpu(&ntype, gpu_shader_combhsv);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
new file mode 100644
index 00000000000..700e4ce3667
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_hsv.cc
@@ -0,0 +1,96 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_sepcomb_hsv_cc {
+
+/* **************** SEPARATE HSV ******************** */
+
+static void node_declare_sephsv(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0});
+ b.add_output<decl::Float>(N_("H"));
+ b.add_output<decl::Float>(N_("S"));
+ b.add_output<decl::Float>(N_("V"));
+}
+
+static int gpu_shader_sephsv(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "separate_hsv", in, out);
+}
+
+} // namespace blender::nodes::node_shader_sepcomb_hsv_cc
+
+void register_node_type_sh_sephsv()
+{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_hsv_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare_sephsv;
+ node_type_gpu(&ntype, file_ns::gpu_shader_sephsv);
+
+ nodeRegisterType(&ntype);
+}
+
+namespace blender::nodes::node_shader_sepcomb_hsv_cc {
+
+/* **************** COMBINE HSV ******************** */
+
+static void node_declare_combhsv(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("H")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_UNSIGNED);
+ b.add_input<decl::Float>(N_("S")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_UNSIGNED);
+ b.add_input<decl::Float>(N_("V")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_UNSIGNED);
+ b.add_output<decl::Color>(N_("Color"));
+}
+
+static int gpu_shader_combhsv(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "combine_hsv", in, out);
+}
+
+} // namespace blender::nodes::node_shader_sepcomb_hsv_cc
+
+void register_node_type_sh_combhsv()
+{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_hsv_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare_combhsv;
+ node_type_gpu(&ntype, file_ns::gpu_shader_combhsv);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
index 24c5dcf7ba3..d4be0bd14dc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc
@@ -21,34 +21,17 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_sepcomb_rgb_cc {
static void sh_node_seprgb_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Color>("Image").default_value({0.8f, 0.8f, 0.8f, 1.0f});
- b.add_output<decl::Float>("R");
- b.add_output<decl::Float>("G");
- b.add_output<decl::Float>("B");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_seprgb(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float col[3];
- nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
- out[0]->vec[0] = col[0];
- out[1]->vec[0] = col[1];
- out[2]->vec[0] = col[2];
+ b.add_input<decl::Color>(N_("Image")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_output<decl::Float>(N_("R"));
+ b.add_output<decl::Float>(N_("G"));
+ b.add_output<decl::Float>(N_("B"));
}
static int gpu_shader_seprgb(GPUMaterial *mat,
@@ -103,47 +86,31 @@ static void sh_node_seprgb_build_multi_function(blender::nodes::NodeMultiFunctio
builder.set_matching_fn(fn);
}
-void register_node_type_sh_seprgb(void)
+} // namespace blender::nodes::node_shader_sepcomb_rgb_cc
+
+void register_node_type_sh_seprgb()
{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_rgb_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_seprgb_declare;
- node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_seprgb);
- node_type_gpu(&ntype, gpu_shader_seprgb);
- ntype.build_multi_function = sh_node_seprgb_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_seprgb_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_seprgb);
+ ntype.build_multi_function = file_ns::sh_node_seprgb_build_multi_function;
nodeRegisterType(&ntype);
}
-namespace blender::nodes {
+namespace blender::nodes::node_shader_sepcomb_rgb_cc {
static void sh_node_combrgb_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("R").min(0.0f).max(1.0f);
- b.add_input<decl::Float>("G").min(0.0f).max(1.0f);
- b.add_input<decl::Float>("B").min(0.0f).max(1.0f);
- b.add_output<decl::Color>("Image");
-};
-
-} // namespace blender::nodes
-
-static void node_shader_exec_combrgb(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float r, g, b;
- nodestack_get_vec(&r, SOCK_FLOAT, in[0]);
- nodestack_get_vec(&g, SOCK_FLOAT, in[1]);
- nodestack_get_vec(&b, SOCK_FLOAT, in[2]);
-
- out[0]->vec[0] = r;
- out[0]->vec[1] = g;
- out[0]->vec[2] = b;
+ b.add_input<decl::Float>(N_("R")).min(0.0f).max(1.0f);
+ b.add_input<decl::Float>(N_("G")).min(0.0f).max(1.0f);
+ b.add_input<decl::Float>(N_("B")).min(0.0f).max(1.0f);
+ b.add_output<decl::Color>(N_("Image"));
}
static int gpu_shader_combrgb(GPUMaterial *mat,
@@ -163,15 +130,18 @@ static void sh_node_combrgb_build_multi_function(blender::nodes::NodeMultiFuncti
builder.set_matching_fn(fn);
}
-void register_node_type_sh_combrgb(void)
+} // namespace blender::nodes::node_shader_sepcomb_rgb_cc
+
+void register_node_type_sh_combrgb()
{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_rgb_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_combrgb_declare;
- node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_combrgb);
- node_type_gpu(&ntype, gpu_shader_combrgb);
- ntype.build_multi_function = sh_node_combrgb_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_combrgb_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_combrgb);
+ ntype.build_multi_function = file_ns::sh_node_combrgb_build_multi_function;
nodeRegisterType(&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 8ca8fc19521..f8064eb192a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
@@ -21,20 +21,18 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_sepcomb_xyz_cc {
static void sh_node_sepxyz_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").min(-10000.0f).max(10000.0f);
- b.add_output<decl::Float>("X");
- b.add_output<decl::Float>("Y");
- b.add_output<decl::Float>("Z");
-};
-
-} // namespace blender::nodes
+ b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f);
+ b.add_output<decl::Float>(N_("X"));
+ b.add_output<decl::Float>(N_("Y"));
+ b.add_output<decl::Float>(N_("Z"));
+}
static int gpu_shader_sepxyz(GPUMaterial *mat,
bNode *node,
@@ -88,30 +86,32 @@ static void sh_node_sepxyz_build_multi_function(blender::nodes::NodeMultiFunctio
builder.set_matching_fn(separate_fn);
}
-void register_node_type_sh_sepxyz(void)
+} // namespace blender::nodes::node_shader_sepcomb_xyz_cc
+
+void register_node_type_sh_sepxyz()
{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_sepxyz_declare;
- node_type_gpu(&ntype, gpu_shader_sepxyz);
- ntype.build_multi_function = sh_node_sepxyz_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_sepxyz_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_sepxyz);
+ ntype.build_multi_function = file_ns::sh_node_sepxyz_build_multi_function;
nodeRegisterType(&ntype);
}
-namespace blender::nodes {
+namespace blender::nodes::node_shader_sepcomb_xyz_cc {
static void sh_node_combxyz_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Float>("X").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Y").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Z").min(-10000.0f).max(10000.0f);
- b.add_output<decl::Vector>("Vector");
-};
-
-} // namespace blender::nodes
+ b.add_input<decl::Float>(N_("X")).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("Y")).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("Z")).min(-10000.0f).max(10000.0f);
+ b.add_output<decl::Vector>(N_("Vector"));
+}
static int gpu_shader_combxyz(GPUMaterial *mat,
bNode *node,
@@ -129,14 +129,18 @@ static void sh_node_combxyz_build_multi_function(blender::nodes::NodeMultiFuncti
builder.set_matching_fn(fn);
}
-void register_node_type_sh_combxyz(void)
+} // namespace blender::nodes::node_shader_sepcomb_xyz_cc
+
+void register_node_type_sh_combxyz()
{
+ namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::sh_node_combxyz_declare;
- node_type_gpu(&ntype, gpu_shader_combxyz);
- ntype.build_multi_function = sh_node_combxyz_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::sh_node_combxyz_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_combxyz);
+ ntype.build_multi_function = file_ns::sh_node_combxyz_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc
index 4e8f47c087a..d601f45b49f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_shader_to_rgb.cc
@@ -17,20 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_shader_to_rgb_cc {
-static bNodeSocketTemplate sh_node_shadertorgb_in[] = {
- {SOCK_SHADER, N_("Shader")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_shadertorgb_out[] = {
- {SOCK_RGBA, N_("Color")},
- {SOCK_FLOAT, N_("Alpha")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Shader>(N_("Shader"));
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Alpha"));
+}
static int node_shader_gpu_shadertorgb(GPUMaterial *mat,
bNode *node,
@@ -43,16 +39,18 @@ static int node_shader_gpu_shadertorgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_shader_to_rgba", in, out);
}
+} // namespace blender::nodes::node_shader_shader_to_rgb_cc
+
/* node type definition */
-void register_node_type_sh_shadertorgb(void)
+void register_node_type_sh_shadertorgb()
{
+ namespace file_ns = blender::nodes::node_shader_shader_to_rgb_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTER, 0);
- node_type_socket_templates(&ntype, sh_node_shadertorgb_in, sh_node_shadertorgb_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_shadertorgb);
+ sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_shadertorgb);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
deleted file mode 100644
index ca7bdf41df9..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** VALUE SQUEEZE ******************** */
-static bNodeSocketTemplate sh_node_squeeze_in[] = {
- {SOCK_FLOAT, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Width"), 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Center"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
- {-1, ""}};
-
-static bNodeSocketTemplate sh_node_squeeze_out[] = {{SOCK_FLOAT, N_("Value")}, {-1, ""}};
-
-static void node_shader_exec_squeeze(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **in,
- bNodeStack **out)
-{
- float vec[3];
-
- nodestack_get_vec(vec, SOCK_FLOAT, in[0]);
- nodestack_get_vec(vec + 1, SOCK_FLOAT, in[1]);
- nodestack_get_vec(vec + 2, SOCK_FLOAT, in[2]);
-
- out[0]->vec[0] = 1.0f / (1.0f + powf(M_E, -((vec[0] - vec[2]) * vec[1])));
-}
-
-static int gpu_shader_squeeze(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- return GPU_stack_link(mat, node, "squeeze", in, out);
-}
-
-void register_node_type_sh_squeeze(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTER, 0);
- node_type_socket_templates(&ntype, sh_node_squeeze_in, sh_node_squeeze_out);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_squeeze);
- node_type_gpu(&ntype, gpu_shader_squeeze);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.cc b/source/blender/nodes/shader/nodes/node_shader_squeeze.cc
new file mode 100644
index 00000000000..83965160019
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.cc
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_squeeze_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Value")).default_value(0.0f).min(-100.0f).max(100.0f);
+ b.add_input<decl::Float>(N_("Width")).default_value(1.0f).min(-100.0f).max(100.0f);
+ b.add_input<decl::Float>(N_("Center")).default_value(0.0f).min(-100.0f).max(100.0f);
+ b.add_output<decl::Float>(N_("Value"));
+}
+
+static int gpu_shader_squeeze(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, node, "squeeze", in, out);
+}
+
+} // namespace blender::nodes::node_shader_squeeze_cc
+
+void register_node_type_sh_squeeze()
+{
+ namespace file_ns = blender::nodes::node_shader_squeeze_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_squeeze);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
deleted file mode 100644
index 159e986e19e..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_subsurface_scattering_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_VECTOR, N_("Radius"), 1.0f, 0.2f, 0.1f, 0.0f, 0.0f, 100.0f, PROP_NONE, SOCK_COMPACT},
- {SOCK_FLOAT, N_("IOR"), 1.4f, 0.0f, 0.0f, 0.0f, 1.01f, 3.8f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_subsurface_scattering_out[] = {
- {SOCK_SHADER, N_("BSSRDF")},
- {-1, ""},
-};
-
-static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
-{
- node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
- node->custom2 = true;
-}
-
-static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- if (!in[5].link) {
- GPU_link(mat, "world_normals_get", &in[5].link);
- }
-
- GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SUBSURFACE);
- GPU_stack_link(mat, node, "node_subsurface_scattering", in, out);
- return GPU_stack_eval_link(mat, node, "node_subsurface_scattering_eval", in, out);
-}
-
-/* node type definition */
-void register_node_type_sh_subsurface_scattering(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(
- &ntype, SH_NODE_SUBSURFACE_SCATTERING, "Subsurface Scattering", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(
- &ntype, sh_node_subsurface_scattering_in, sh_node_subsurface_scattering_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_subsurface_scattering);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_subsurface_scattering);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
new file mode 100644
index 00000000000..f60db81b4a9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.cc
@@ -0,0 +1,113 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_subsurface_scattering_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Vector>(N_("Radius"))
+ .default_value({1.0f, 0.2f, 0.1f})
+ .min(0.0f)
+ .max(100.0f)
+ .compact();
+ b.add_input<decl::Float>(N_("IOR")).default_value(1.4f).min(1.01f).max(3.8f).subtype(
+ PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Anisotropy"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Vector>(N_("Normal")).hide_value();
+ b.add_output<decl::Shader>(N_("BSSRDF"));
+}
+
+static void node_shader_buts_subsurface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "falloff", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
+ node->custom2 = true;
+}
+
+static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ if (!in[5].link) {
+ GPU_link(mat, "world_normals_get", &in[5].link);
+ }
+
+ if (node->sss_id > 0) {
+ bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
+ bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
+ /* For some reason it seems that the socket value is in ARGB format. */
+ GPU_material_sss_profile_create(mat, &socket_data->value[1]);
+
+ /* sss_id is 0 only the node is not connected to any output.
+ * In this case flagging the material would trigger a bug (see T68736). */
+ GPU_material_flag_set(mat, (eGPUMatFlag)(GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS));
+ }
+
+ return GPU_stack_link(
+ 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;
+
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+ if (STR_ELEM(sock->name, "IOR", "Anisotropy")) {
+ nodeSetSocketAvailability(ntree, sock, sss_method != SHD_SUBSURFACE_BURLEY);
+ }
+ }
+}
+
+} // namespace blender::nodes::node_shader_subsurface_scattering_cc
+
+/* node type definition */
+void register_node_type_sh_subsurface_scattering()
+{
+ namespace file_ns = blender::nodes::node_shader_subsurface_scattering_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(
+ &ntype, SH_NODE_SUBSURFACE_SCATTERING, "Subsurface Scattering", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_subsurface;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, file_ns::node_shader_init_subsurface_scattering);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_subsurface_scattering);
+ node_type_update(&ntype, file_ns::node_shader_update_subsurface_scattering);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.cc
index 7ec332bd34a..58625cacf9c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.cc
@@ -17,18 +17,49 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "BKE_context.h"
-static bNodeSocketTemplate sh_node_tangent_out[] = {
- {SOCK_VECTOR, N_("Tangent"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tangent_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("Tangent"));
+}
+
+static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiLayout *split, *row;
+
+ split = uiLayoutSplit(layout, 0.0f, false);
+
+ uiItemR(split, ptr, "direction_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", 0);
+
+ row = uiLayoutRow(split, false);
+
+ if (RNA_enum_get(ptr, "direction_type") == SHD_TANGENT_UVMAP) {
+ PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
+
+ if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
+ PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
+ uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
+ }
+ else {
+ uiItemR(row, ptr, "uv_map", UI_ITEM_R_SPLIT_EMPTY_NAME, "", 0);
+ }
+ }
+ else {
+ uiItemR(row, ptr, "axis", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, nullptr, 0);
+ }
+}
static void node_shader_init_tangent(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderTangent *attr = MEM_callocN(sizeof(NodeShaderTangent), "NodeShaderTangent");
+ NodeShaderTangent *attr = MEM_cnew<NodeShaderTangent>("NodeShaderTangent");
attr->axis = SHD_TANGENT_AXIS_Z;
node->storage = attr;
}
@@ -39,7 +70,7 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- NodeShaderTangent *attr = node->storage;
+ NodeShaderTangent *attr = static_cast<NodeShaderTangent *>(node->storage);
if (attr->direction_type == SHD_TANGENT_UVMAP) {
return GPU_stack_link(
@@ -61,16 +92,21 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tangent", in, out, orco);
}
+} // namespace blender::nodes::node_shader_tangent_cc
+
/* node type definition */
-void register_node_type_sh_tangent(void)
+void register_node_type_sh_tangent()
{
+ namespace file_ns = blender::nodes::node_shader_tangent_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TANGENT, "Tangent", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_tangent_out);
+ sh_node_type_base(&ntype, SH_NODE_TANGENT, "Tangent", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tangent;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_tangent);
- node_type_gpu(&ntype, node_shader_gpu_tangent);
+ node_type_init(&ntype, file_ns::node_shader_init_tangent);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tangent);
node_type_storage(
&ntype, "NodeShaderTangent", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
deleted file mode 100644
index 1b802f1dfd7..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_tex_brick_in[] = {
- {SOCK_VECTOR,
- N_("Vector"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_HIDE_VALUE | SOCK_NO_INTERNAL_LINK},
- {SOCK_RGBA, N_("Color1"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_RGBA, N_("Color2"), 0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f},
- {SOCK_RGBA,
- N_("Mortar"),
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Scale"),
- 5.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- -1000.0f,
- 1000.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Mortar Size"),
- 0.02f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.125f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Mortar Smooth"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Bias"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- -1.0f,
- 1.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Brick Width"),
- 0.5f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.01f,
- 100.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Row Height"),
- 0.25f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.01f,
- 100.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_brick_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT,
- N_("Fac"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_FACTOR,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeTexBrick *tex = MEM_callocN(sizeof(NodeTexBrick), "NodeTexBrick");
- BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
- BKE_texture_colormapping_default(&tex->base.color_mapping);
-
- tex->offset = 0.5f;
- tex->squash = 1.0f;
- tex->offset_freq = 2;
- tex->squash_freq = 2;
-
- node->storage = tex;
-
- LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if (STREQ(sock->name, "Mortar Smooth")) {
- ((bNodeSocketValueFloat *)sock->default_value)->value = 0.1f;
- }
- }
-}
-
-static int node_shader_gpu_tex_brick(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
- node_shader_gpu_tex_mapping(mat, node, in, out);
- NodeTexBrick *tex = (NodeTexBrick *)node->storage;
- float offset_freq = tex->offset_freq;
- float squash_freq = tex->squash_freq;
- return GPU_stack_link(mat,
- node,
- "node_tex_brick",
- in,
- out,
- GPU_uniform(&tex->offset),
- GPU_constant(&offset_freq),
- GPU_uniform(&tex->squash),
- GPU_constant(&squash_freq));
-}
-
-/* node type definition */
-void register_node_type_sh_tex_brick(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_BRICK, "Brick Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_brick_in, sh_node_tex_brick_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_tex_brick);
- node_type_storage(
- &ntype, "NodeTexBrick", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_brick);
-
- 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
new file mode 100644
index 00000000000..81a69ef18da
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc
@@ -0,0 +1,306 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "BLI_math_vec_types.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_brick_cc {
+
+static void sh_node_tex_brick_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::Color>(N_("Color1")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Color>(N_("Color2")).default_value({0.2f, 0.2f, 0.2f, 1.0f});
+ b.add_input<decl::Color>(N_("Mortar")).default_value({0.0f, 0.0f, 0.0f, 1.0f}).no_muted_links();
+ b.add_input<decl::Float>(N_("Scale"))
+ .min(-1000.0f)
+ .max(1000.0f)
+ .default_value(5.0f)
+ .no_muted_links();
+ b.add_input<decl::Float>(N_("Mortar Size"))
+ .min(0.0f)
+ .max(0.125f)
+ .default_value(0.02f)
+ .no_muted_links();
+ b.add_input<decl::Float>(N_("Mortar Smooth")).min(0.0f).max(1.0f).no_muted_links();
+ b.add_input<decl::Float>(N_("Bias")).min(-1.0f).max(1.0f).no_muted_links();
+ b.add_input<decl::Float>(N_("Brick Width"))
+ .min(0.01f)
+ .max(100.0f)
+ .default_value(0.5f)
+ .no_muted_links();
+ b.add_input<decl::Float>(N_("Row Height"))
+ .min(0.01f)
+ .max(100.0f)
+ .default_value(0.25f)
+ .no_muted_links();
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Fac"));
+}
+
+static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *col;
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col,
+ ptr,
+ "offset",
+ UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_SLIDER,
+ IFACE_("Offset"),
+ ICON_NONE);
+ uiItemR(
+ col, ptr, "offset_frequency", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Frequency"), ICON_NONE);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "squash", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Squash"), ICON_NONE);
+ uiItemR(
+ col, ptr, "squash_frequency", UI_ITEM_R_SPLIT_EMPTY_NAME, IFACE_("Frequency"), ICON_NONE);
+}
+
+static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeTexBrick *tex = MEM_cnew<NodeTexBrick>(__func__);
+ BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
+ BKE_texture_colormapping_default(&tex->base.color_mapping);
+
+ tex->offset = 0.5f;
+ tex->squash = 1.0f;
+ tex->offset_freq = 2;
+ tex->squash_freq = 2;
+
+ node->storage = tex;
+
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+ if (STREQ(sock->name, "Mortar Smooth")) {
+ ((bNodeSocketValueFloat *)sock->default_value)->value = 0.1f;
+ }
+ }
+}
+
+static int node_shader_gpu_tex_brick(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
+ node_shader_gpu_tex_mapping(mat, node, in, out);
+ NodeTexBrick *tex = (NodeTexBrick *)node->storage;
+ float offset_freq = tex->offset_freq;
+ float squash_freq = tex->squash_freq;
+ return GPU_stack_link(mat,
+ node,
+ "node_tex_brick",
+ in,
+ out,
+ GPU_uniform(&tex->offset),
+ GPU_constant(&offset_freq),
+ GPU_uniform(&tex->squash),
+ GPU_constant(&squash_freq));
+}
+
+class BrickFunction : public fn::MultiFunction {
+ private:
+ const float offset_;
+ const int offset_freq_;
+ const float squash_;
+ const int squash_freq_;
+
+ public:
+ BrickFunction(const float offset,
+ const int offset_freq,
+ const float squash,
+ const int squash_freq)
+ : offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq)
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"BrickTexture"};
+ signature.single_input<float3>("Vector");
+ signature.single_input<ColorGeometry4f>("Color1");
+ signature.single_input<ColorGeometry4f>("Color2");
+ signature.single_input<ColorGeometry4f>("Mortar");
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Mortar Size");
+ signature.single_input<float>("Mortar Smooth");
+ signature.single_input<float>("Bias");
+ signature.single_input<float>("Brick Width");
+ signature.single_input<float>("Row Height");
+ signature.single_output<ColorGeometry4f>("Color");
+ signature.single_output<float>("Fac");
+ return signature.build();
+ }
+
+ /* Fast integer noise. */
+ static float brick_noise(uint n)
+ {
+ n = (n + 1013) & 0x7fffffff;
+ n = (n >> 13) ^ n;
+ const uint nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
+ return 0.5f * ((float)nn / 1073741824.0f);
+ }
+
+ static float smoothstepf(const float f)
+ {
+ const float ff = f * f;
+ return (3.0f * ff - 2.0f * ff * f);
+ }
+
+ static float2 brick(float3 p,
+ float mortar_size,
+ float mortar_smooth,
+ float bias,
+ float brick_width,
+ float row_height,
+ float offset_amount,
+ int offset_frequency,
+ float squash_amount,
+ int squash_frequency)
+ {
+ float offset = 0.0f;
+
+ const int rownum = (int)floorf(p.y / row_height);
+
+ if (offset_frequency && squash_frequency) {
+ brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount;
+ offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount);
+ }
+
+ const int bricknum = (int)floorf((p.x + offset) / brick_width);
+
+ const float x = (p.x + offset) - brick_width * bricknum;
+ const float y = p.y - row_height * rownum;
+
+ const float tint = clamp_f(
+ brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias, 0.0f, 1.0f);
+ float min_dist = std::min(std::min(x, y), std::min(brick_width - x, row_height - y));
+
+ float mortar;
+ if (min_dist >= mortar_size) {
+ mortar = 0.0f;
+ }
+ else if (mortar_smooth == 0.0f) {
+ mortar = 1.0f;
+ }
+ else {
+ min_dist = 1.0f - min_dist / mortar_size;
+ mortar = (min_dist < mortar_smooth) ? smoothstepf(min_dist / mortar_smooth) : 1.0f;
+ }
+
+ return float2(tint, mortar);
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ const VArray<ColorGeometry4f> &color1_values = params.readonly_single_input<ColorGeometry4f>(
+ 1, "Color1");
+ const VArray<ColorGeometry4f> &color2_values = params.readonly_single_input<ColorGeometry4f>(
+ 2, "Color2");
+ const VArray<ColorGeometry4f> &mortar_values = params.readonly_single_input<ColorGeometry4f>(
+ 3, "Mortar");
+ const VArray<float> &scale = params.readonly_single_input<float>(4, "Scale");
+ const VArray<float> &mortar_size = params.readonly_single_input<float>(5, "Mortar Size");
+ const VArray<float> &mortar_smooth = params.readonly_single_input<float>(6, "Mortar Smooth");
+ const VArray<float> &bias = params.readonly_single_input<float>(7, "Bias");
+ const VArray<float> &brick_width = params.readonly_single_input<float>(8, "Brick Width");
+ const VArray<float> &row_height = params.readonly_single_input<float>(9, "Row Height");
+
+ MutableSpan<ColorGeometry4f> r_color =
+ params.uninitialized_single_output_if_required<ColorGeometry4f>(10, "Color");
+ MutableSpan<float> r_fac = params.uninitialized_single_output_if_required<float>(11, "Fac");
+
+ const bool store_fac = !r_fac.is_empty();
+ const bool store_color = !r_color.is_empty();
+
+ for (int64_t i : mask) {
+ const float2 f2 = brick(vector[i] * scale[i],
+ mortar_size[i],
+ mortar_smooth[i],
+ bias[i],
+ brick_width[i],
+ row_height[i],
+ offset_,
+ offset_freq_,
+ squash_,
+ squash_freq_);
+
+ float4 color_data, color1, color2, mortar;
+ copy_v4_v4(color_data, color1_values[i]);
+ copy_v4_v4(color1, color1_values[i]);
+ copy_v4_v4(color2, color2_values[i]);
+ copy_v4_v4(mortar, mortar_values[i]);
+ const float tint = f2.x;
+ const float f = f2.y;
+
+ if (f != 1.0f) {
+ const float facm = 1.0f - tint;
+ color_data = color1 * facm + color2 * tint;
+ }
+
+ if (store_color) {
+ color_data = color_data * (1.0f - f) + mortar * f;
+ copy_v4_v4(r_color[i], color_data);
+ }
+ if (store_fac) {
+ r_fac[i] = f;
+ }
+ }
+ }
+};
+
+static void sh_node_brick_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ NodeTexBrick *tex = (NodeTexBrick *)node.storage;
+
+ builder.construct_and_set_matching_fn<BrickFunction>(
+ tex->offset, tex->offset_freq, tex->squash, tex->squash_freq);
+}
+
+} // namespace blender::nodes::node_shader_tex_brick_cc
+
+void register_node_type_sh_tex_brick()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_brick_cc;
+
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_BRICK, "Brick Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_brick_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_brick;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, file_ns::node_shader_init_tex_brick);
+ node_type_storage(
+ &ntype, "NodeTexBrick", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_brick);
+ ntype.build_multi_function = file_ns::sh_node_brick_build_multi_function;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
deleted file mode 100644
index 75219f4c3f9..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_tex_checker_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_RGBA, N_("Color1"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_RGBA, N_("Color2"), 0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT,
- N_("Scale"),
- 5.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- -1000.0f,
- 1000.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_checker_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT,
- N_("Fac"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_FACTOR,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeTexChecker *tex = MEM_callocN(sizeof(NodeTexChecker), "NodeTexChecker");
- BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
- BKE_texture_colormapping_default(&tex->base.color_mapping);
-
- node->storage = tex;
-}
-
-static int node_shader_gpu_tex_checker(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
- node_shader_gpu_tex_mapping(mat, node, in, out);
-
- return GPU_stack_link(mat, node, "node_tex_checker", in, out);
-}
-
-/* node type definition */
-void register_node_type_sh_tex_checker(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_checker_in, sh_node_tex_checker_out);
- node_type_init(&ntype, node_shader_init_tex_checker);
- node_type_storage(
- &ntype, "NodeTexChecker", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_checker);
-
- nodeRegisterType(&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
new file mode 100644
index 00000000000..6022f13821a
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc
@@ -0,0 +1,137 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_tex_checker_cc {
+
+static void sh_node_tex_checker_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::Color>(N_("Color1")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Color>(N_("Color2")).default_value({0.2f, 0.2f, 0.2f, 1.0f});
+ b.add_input<decl::Float>(N_("Scale"))
+ .min(-10000.0f)
+ .max(10000.0f)
+ .default_value(5.0f)
+ .no_muted_links();
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Fac"));
+}
+
+static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeTexChecker *tex = MEM_cnew<NodeTexChecker>(__func__);
+ BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
+ BKE_texture_colormapping_default(&tex->base.color_mapping);
+
+ node->storage = tex;
+}
+
+static int node_shader_gpu_tex_checker(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
+ node_shader_gpu_tex_mapping(mat, node, in, out);
+
+ return GPU_stack_link(mat, node, "node_tex_checker", in, out);
+}
+
+class NodeTexChecker : public fn::MultiFunction {
+ public:
+ NodeTexChecker()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Checker"};
+ signature.single_input<float3>("Vector");
+ signature.single_input<ColorGeometry4f>("Color1");
+ signature.single_input<ColorGeometry4f>("Color2");
+ signature.single_input<float>("Scale");
+ signature.single_output<ColorGeometry4f>("Color");
+ signature.single_output<float>("Fac");
+ return signature.build();
+ }
+
+ void call(blender::IndexMask mask,
+ fn::MFParams params,
+ fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ const VArray<ColorGeometry4f> &color1 = params.readonly_single_input<ColorGeometry4f>(
+ 1, "Color1");
+ const VArray<ColorGeometry4f> &color2 = params.readonly_single_input<ColorGeometry4f>(
+ 2, "Color2");
+ const VArray<float> &scale = params.readonly_single_input<float>(3, "Scale");
+ MutableSpan<ColorGeometry4f> r_color =
+ params.uninitialized_single_output_if_required<ColorGeometry4f>(4, "Color");
+ MutableSpan<float> r_fac = params.uninitialized_single_output<float>(5, "Fac");
+
+ for (int64_t i : mask) {
+ /* Avoid precision issues on unit coordinates. */
+ const float3 p = (vector[i] * scale[i] + 0.000001f) * 0.999999f;
+
+ const int xi = abs((int)(floorf(p.x)));
+ const int yi = abs((int)(floorf(p.y)));
+ const int zi = abs((int)(floorf(p.z)));
+
+ r_fac[i] = ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f;
+ }
+
+ if (!r_color.is_empty()) {
+ for (int64_t i : mask) {
+ r_color[i] = (r_fac[i] == 1.0f) ? color1[i] : color2[i];
+ }
+ }
+ }
+};
+
+static void sh_node_tex_checker_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ static NodeTexChecker fn;
+ builder.set_matching_fn(fn);
+}
+
+} // namespace blender::nodes::node_shader_tex_checker_cc
+
+void register_node_type_sh_tex_checker()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_checker_cc;
+
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_CHECKER, "Checker Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_checker_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_checker);
+ node_type_storage(
+ &ntype, "NodeTexChecker", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_checker);
+ ntype.build_multi_function = file_ns::sh_node_tex_checker_build_multi_function;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
index 76966e0bbee..1bbaed88ea5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.cc
@@ -17,22 +17,31 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
#include "DNA_customdata_types.h"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_tex_coord_out[] = {
- {SOCK_VECTOR, N_("Generated"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("UV"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Object"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Camera"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Window"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Reflection"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_tex_coord_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("Generated"));
+ b.add_output<decl::Vector>(N_("Normal"));
+ b.add_output<decl::Vector>(N_("UV"));
+ b.add_output<decl::Vector>(N_("Object"));
+ b.add_output<decl::Vector>(N_("Camera"));
+ b.add_output<decl::Vector>(N_("Window"));
+ b.add_output<decl::Vector>(N_("Reflection"));
+}
+
+static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "object", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+ uiItemR(layout, ptr, "from_instancer", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+}
static int node_shader_gpu_tex_coord(GPUMaterial *mat,
bNode *node,
@@ -42,25 +51,27 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
{
Object *ob = (Object *)node->id;
- /* Use special matrix to let the shader branch to using the render object's matrix. */
- float dummy_matrix[4][4];
- dummy_matrix[3][3] = 0.0f;
- GPUNodeLink *inv_obmat = (ob != NULL) ? GPU_uniform(&ob->imat[0][0]) :
- GPU_uniform(&dummy_matrix[0][0]);
+ GPUNodeLink *inv_obmat = (ob != nullptr) ? GPU_uniform(&ob->imat[0][0]) :
+ GPU_builtin(GPU_INVERSE_OBJECT_MATRIX);
/* Opti: don't request orco if not needed. */
- GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant((float[4]){0.0f, 0.0f, 0.0f, 0.0f}) :
+ const float default_coords[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPUNodeLink *orco = (!out[0].hasoutput) ? GPU_constant(default_coords) :
GPU_attribute(mat, CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, "");
+ GPUNodeLink *viewpos = GPU_builtin(GPU_VIEW_POSITION);
+ GPUNodeLink *worldnor = GPU_builtin(GPU_WORLD_NORMAL);
+ GPUNodeLink *texcofacs = GPU_builtin(GPU_CAMERA_TEXCO_FACTORS);
if (out[0].hasoutput) {
GPU_link(mat, "generated_from_orco", orco, &orco);
}
- GPU_stack_link(mat, node, "node_tex_coord", in, out, inv_obmat, orco, mtface);
+ GPU_stack_link(
+ mat, node, "node_tex_coord", in, out, viewpos, worldnor, inv_obmat, texcofacs, orco, mtface);
- /* for each output. */
- for (int i = 0; sh_node_tex_coord_out[i].type != -1; i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (bNodeSocket *, sock, &node->outputs, i) {
node_shader_gpu_bump_tex_coord(mat, node, &out[i].link);
/* Normalize some vectors after dFdx/dFdy offsets.
* This is the case for interpolated, non linear functions.
@@ -74,23 +85,26 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat,
out[i].link,
out[i].link,
&out[i].link,
- NULL);
+ nullptr);
}
}
return 1;
}
+} // namespace blender::nodes::node_shader_tex_coord_cc
+
/* node type definition */
-void register_node_type_sh_tex_coord(void)
+void register_node_type_sh_tex_coord()
{
+ namespace file_ns = blender::nodes::node_shader_tex_coord_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_tex_coord_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_tex_coord);
+ sh_node_type_base(&ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_coord;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_coord);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc
index 51ced8c2842..24ecdee12d8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc
@@ -17,23 +17,19 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_tex_environment_cc {
-static bNodeSocketTemplate sh_node_tex_environment_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_environment_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector")).hide_value();
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+}
static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexEnvironment *tex = MEM_callocN(sizeof(NodeTexEnvironment), "NodeTexEnvironment");
+ NodeTexEnvironment *tex = MEM_cnew<NodeTexEnvironment>("NodeTexEnvironment");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->projection = SHD_PROJ_EQUIRECTANGULAR;
@@ -49,12 +45,12 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPUNodeStack *out)
{
Image *ima = (Image *)node->id;
- NodeTexEnvironment *tex = node->storage;
+ NodeTexEnvironment *tex = (NodeTexEnvironment *)node->storage;
/* We get the image user from the original node, since GPU image keeps
* a pointer to it and the dependency refreshes the original. */
bNode *node_original = node->original ? node->original : node;
- NodeTexImage *tex_original = node_original->storage;
+ NodeTexImage *tex_original = (NodeTexImage *)node_original->storage;
ImageUser *iuser = &tex_original->iuser;
eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
/* TODO(fclem): For now assume mipmap is always enabled. */
@@ -130,18 +126,22 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
return true;
}
+} // namespace blender::nodes::node_shader_tex_environment_cc
+
/* node type definition */
-void register_node_type_sh_tex_environment(void)
+void register_node_type_sh_tex_environment()
{
+ namespace file_ns = blender::nodes::node_shader_tex_environment_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_ENVIRONMENT, "Environment Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_environment_in, sh_node_tex_environment_out);
- node_type_init(&ntype, node_shader_init_tex_environment);
+ sh_node_type_base(&ntype, SH_NODE_TEX_ENVIRONMENT, "Environment Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_environment);
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);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_environment);
+ 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 e0520ee49d3..53be5bc09d9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc
@@ -17,23 +17,29 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_gradient_cc {
static void sh_node_tex_gradient_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Vector>("Vector").hide_value();
- b.add_output<decl::Color>("Color").no_muted_links();
- b.add_output<decl::Float>("Fac").no_muted_links();
-};
+ b.is_function_node();
+ b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+ b.add_output<decl::Float>(N_("Fac")).no_muted_links();
+}
-} // namespace blender::nodes
+static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "gradient_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_tex_gradient(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexGradient *tex = (NodeTexGradient *)MEM_callocN(sizeof(NodeTexGradient),
- "NodeTexGradient");
+ NodeTexGradient *tex = MEM_cnew<NodeTexGradient>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->gradient_type = SHD_BLEND_LINEAR;
@@ -55,17 +61,122 @@ static int node_shader_gpu_tex_gradient(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tex_gradient", in, out, GPU_constant(&gradient_type));
}
-/* node type definition */
-void register_node_type_sh_tex_gradient(void)
+class GradientFunction : public fn::MultiFunction {
+ private:
+ int gradient_type_;
+
+ public:
+ GradientFunction(int gradient_type) : gradient_type_(gradient_type)
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"GradientFunction"};
+ signature.single_input<float3>("Vector");
+ signature.single_output<ColorGeometry4f>("Color");
+ signature.single_output<float>("Fac");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+
+ MutableSpan<ColorGeometry4f> r_color =
+ params.uninitialized_single_output_if_required<ColorGeometry4f>(1, "Color");
+ MutableSpan<float> fac = params.uninitialized_single_output<float>(2, "Fac");
+
+ const bool compute_color = !r_color.is_empty();
+
+ switch (gradient_type_) {
+ case SHD_BLEND_LINEAR: {
+ for (int64_t i : mask) {
+ fac[i] = vector[i].x;
+ }
+ break;
+ }
+ case SHD_BLEND_QUADRATIC: {
+ for (int64_t i : mask) {
+ const float r = std::max(vector[i].x, 0.0f);
+ fac[i] = r * r;
+ }
+ break;
+ }
+ case SHD_BLEND_EASING: {
+ for (int64_t i : mask) {
+ const float r = std::min(std::max(vector[i].x, 0.0f), 1.0f);
+ const float t = r * r;
+ fac[i] = (3.0f * t - 2.0f * t * r);
+ }
+ break;
+ }
+ case SHD_BLEND_DIAGONAL: {
+ for (int64_t i : mask) {
+ fac[i] = (vector[i].x + vector[i].y) * 0.5f;
+ }
+ break;
+ }
+ case SHD_BLEND_RADIAL: {
+ for (int64_t i : mask) {
+ fac[i] = atan2f(vector[i].y, vector[i].x) / (M_PI * 2.0f) + 0.5f;
+ }
+ break;
+ }
+ case SHD_BLEND_QUADRATIC_SPHERE: {
+ for (int64_t i : mask) {
+ /* Bias a little bit for the case where input is a unit length vector,
+ * to get exactly zero instead of a small random value depending
+ * on float precision. */
+ const float r = std::max(0.999999f - math::length(vector[i]), 0.0f);
+ fac[i] = r * r;
+ }
+ break;
+ }
+ case SHD_BLEND_SPHERICAL: {
+ for (int64_t i : mask) {
+ /* Bias a little bit for the case where input is a unit length vector,
+ * to get exactly zero instead of a small random value depending
+ * on float precision. */
+ fac[i] = std::max(0.999999f - math::length(vector[i]), 0.0f);
+ }
+ break;
+ }
+ }
+ if (compute_color) {
+ for (int64_t i : mask) {
+ r_color[i] = ColorGeometry4f(fac[i], fac[i], fac[i], 1.0f);
+ }
+ }
+ }
+};
+
+static void sh_node_gradient_tex_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ NodeTexGradient *tex = (NodeTexGradient *)node.storage;
+ builder.construct_and_set_matching_fn<GradientFunction>(tex->gradient_type);
+}
+
+} // namespace blender::nodes::node_shader_tex_gradient_cc
+
+void register_node_type_sh_tex_gradient()
{
+ namespace file_ns = blender::nodes::node_shader_tex_gradient_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_GRADIENT, "Gradient Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::sh_node_tex_gradient_declare;
- node_type_init(&ntype, node_shader_init_tex_gradient);
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_GRADIENT, "Gradient Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_gradient_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_gradient;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_gradient);
node_type_storage(
&ntype, "NodeTexGradient", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_gradient);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_gradient);
+ ntype.build_multi_function = file_ns::sh_node_gradient_tex_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
index bf7c4edc1c9..7c7154b8f7a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc
@@ -17,33 +17,21 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_tex_image_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_image_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Alpha"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_NONE,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_tex_image_cc {
+
+static void sh_node_tex_image_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+ b.add_output<decl::Float>(N_("Alpha")).no_muted_links();
+}
static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexImage *tex = MEM_callocN(sizeof(NodeTexImage), "NodeTexImage");
+ NodeTexImage *tex = MEM_cnew<NodeTexImage>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
BKE_imageuser_default(&tex->iuser);
@@ -58,12 +46,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPUNodeStack *out)
{
Image *ima = (Image *)node->id;
- NodeTexImage *tex = node->storage;
+ NodeTexImage *tex = (NodeTexImage *)node->storage;
/* We get the image user from the original node, since GPU image keeps
* a pointer to it and the dependency refreshes the original. */
bNode *node_original = node->original ? node->original : node;
- NodeTexImage *tex_original = node_original->storage;
+ NodeTexImage *tex_original = (NodeTexImage *)node_original->storage;
ImageUser *iuser = &tex_original->iuser;
if (!ima) {
@@ -78,7 +66,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
node_shader_gpu_tex_mapping(mat, node, in, out);
- eGPUSamplerState sampler_state = 0;
+ eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT;
switch (tex->extension) {
case SHD_IMAGE_EXTENSION_REPEAT:
@@ -94,7 +82,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (tex->interpolation != SHD_INTERP_CLOSEST) {
sampler_state |= GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
/* TODO(fclem): For now assume mipmap is always enabled. */
- sampler_state |= true ? GPU_SAMPLER_MIPMAP : 0;
+ sampler_state |= GPU_SAMPLER_MIPMAP;
}
const bool use_cubic = ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART);
@@ -181,18 +169,21 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
return true;
}
-/* node type definition */
-void register_node_type_sh_tex_image(void)
+} // namespace blender::nodes::node_shader_tex_image_cc
+
+void register_node_type_sh_tex_image()
{
+ namespace file_ns = blender::nodes::node_shader_tex_image_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_IMAGE, "Image Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_image_in, sh_node_tex_image_out);
- node_type_init(&ntype, node_shader_init_tex_image);
+ sh_node_type_base(&ntype, SH_NODE_TEX_IMAGE, "Image Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_image_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_image);
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);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_image);
+ 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.c b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
deleted file mode 100644
index 51721f8bb09..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_tex_magic_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {SOCK_FLOAT, N_("Distortion"), 1.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_magic_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Fac"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_FACTOR,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static void node_shader_init_tex_magic(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeTexMagic *tex = MEM_callocN(sizeof(NodeTexMagic), "NodeTexMagic");
- BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
- BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->depth = 2;
-
- node->storage = tex;
-}
-
-static int node_shader_gpu_tex_magic(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- NodeTexMagic *tex = (NodeTexMagic *)node->storage;
- float depth = tex->depth;
-
- node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
- node_shader_gpu_tex_mapping(mat, node, in, out);
-
- return GPU_stack_link(mat, node, "node_tex_magic", in, out, GPU_constant(&depth));
-}
-
-/* node type definition */
-void register_node_type_sh_tex_magic(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_MAGIC, "Magic Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_magic_in, sh_node_tex_magic_out);
- node_type_init(&ntype, node_shader_init_tex_magic);
- node_type_storage(
- &ntype, "NodeTexMagic", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_magic);
-
- 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
new file mode 100644
index 00000000000..e40914783b6
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc
@@ -0,0 +1,204 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_magic_cc {
+
+static void sh_node_tex_magic_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
+ b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(1.0f);
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+ b.add_output<decl::Float>(N_("Fac")).no_muted_links();
+}
+
+static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "turbulence_depth", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
+
+static void node_shader_init_tex_magic(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeTexMagic *tex = MEM_cnew<NodeTexMagic>(__func__);
+ BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
+ BKE_texture_colormapping_default(&tex->base.color_mapping);
+ tex->depth = 2;
+
+ node->storage = tex;
+}
+
+static int node_shader_gpu_tex_magic(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ NodeTexMagic *tex = (NodeTexMagic *)node->storage;
+ float depth = tex->depth;
+
+ node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
+ node_shader_gpu_tex_mapping(mat, node, in, out);
+
+ return GPU_stack_link(mat, node, "node_tex_magic", in, out, GPU_constant(&depth));
+}
+
+class MagicFunction : public fn::MultiFunction {
+ private:
+ int depth_;
+
+ public:
+ MagicFunction(int depth) : depth_(depth)
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"MagicFunction"};
+ signature.single_input<float3>("Vector");
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Distortion");
+ signature.single_output<ColorGeometry4f>("Color");
+ signature.single_output<float>("Fac");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
+ const VArray<float> &distortion = params.readonly_single_input<float>(2, "Distortion");
+
+ MutableSpan<ColorGeometry4f> r_color = params.uninitialized_single_output<ColorGeometry4f>(
+ 3, "Color");
+ MutableSpan<float> r_fac = params.uninitialized_single_output_if_required<float>(4, "Fac");
+
+ const bool compute_factor = !r_fac.is_empty();
+
+ for (int64_t i : mask) {
+ const float3 co = vector[i] * scale[i];
+ const float distort = distortion[i];
+ float x = sinf((co[0] + co[1] + co[2]) * 5.0f);
+ float y = cosf((-co[0] + co[1] - co[2]) * 5.0f);
+ float z = -cosf((-co[0] - co[1] + co[2]) * 5.0f);
+
+ if (depth_ > 0) {
+ x *= distort;
+ y *= distort;
+ z *= distort;
+ y = -cosf(x - y + z);
+ y *= distort;
+
+ if (depth_ > 1) {
+ x = cosf(x - y - z);
+ x *= distort;
+
+ if (depth_ > 2) {
+ z = sinf(-x - y - z);
+ z *= distort;
+
+ if (depth_ > 3) {
+ x = -cosf(-x + y - z);
+ x *= distort;
+
+ if (depth_ > 4) {
+ y = -sinf(-x + y + z);
+ y *= distort;
+
+ if (depth_ > 5) {
+ y = -cosf(-x + y + z);
+ y *= distort;
+
+ if (depth_ > 6) {
+ x = cosf(x + y + z);
+ x *= distort;
+
+ if (depth_ > 7) {
+ z = sinf(x + y - z);
+ z *= distort;
+
+ if (depth_ > 8) {
+ x = -cosf(-x - y + z);
+ x *= distort;
+
+ if (depth_ > 9) {
+ y = -sinf(x - y + z);
+ y *= distort;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (distort != 0.0f) {
+ const float d = distort * 2.0f;
+ x /= d;
+ y /= d;
+ z /= d;
+ }
+
+ r_color[i] = ColorGeometry4f(0.5f - x, 0.5f - y, 0.5f - z, 1.0f);
+ }
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ r_fac[i] = (r_color[i].r + r_color[i].g + r_color[i].b) * (1.0f / 3.0f);
+ }
+ }
+ }
+};
+
+static void sh_node_magic_tex_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ NodeTexMagic *tex = (NodeTexMagic *)node.storage;
+ builder.construct_and_set_matching_fn<MagicFunction>(tex->depth);
+}
+
+} // namespace blender::nodes::node_shader_tex_magic_cc
+
+void register_node_type_sh_tex_magic()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_magic_cc;
+
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_MAGIC, "Magic Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_magic_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_magic;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_magic);
+ node_type_storage(
+ &ntype, "NodeTexMagic", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_magic);
+ ntype.build_multi_function = file_ns::sh_node_magic_tex_build_multi_function;
+
+ nodeRegisterType(&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 23f150d8135..45c2a83c178 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
@@ -17,30 +17,43 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "BLI_noise.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_musgrave_cc {
+
+NODE_STORAGE_FUNCS(NodeTexMusgrave)
static void sh_node_tex_musgrave_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").hide_value();
- b.add_input<decl::Float>("W").min(-1000.0f).max(1000.0f);
- b.add_input<decl::Float>("Scale").min(-1000.0f).max(1000.0f).default_value(5.0f);
- b.add_input<decl::Float>("Detail").min(0.0f).max(16.0f).default_value(2.0f);
- b.add_input<decl::Float>("Dimension").min(0.0f).max(1000.0f).default_value(2.0f);
- b.add_input<decl::Float>("Lacunarity").min(0.0f).max(1000.0f).default_value(2.0f);
- b.add_input<decl::Float>("Offset").min(-1000.0f).max(1000.0f);
- b.add_input<decl::Float>("Gain").min(0.0f).max(1000.0f).default_value(1.0f);
- b.add_output<decl::Float>("Fac").no_muted_links();
-};
+ b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ 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);
+ b.add_input<decl::Float>(N_("Lacunarity")).min(0.0f).max(1000.0f).default_value(2.0f);
+ b.add_input<decl::Float>(N_("Offset")).min(-1000.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Gain")).min(0.0f).max(1000.0f).default_value(1.0f);
+ b.add_output<decl::Float>(N_("Fac")).no_muted_links();
+}
-} // namespace blender::nodes
+static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "musgrave_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "musgrave_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_tex_musgrave(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexMusgrave *tex = (NodeTexMusgrave *)MEM_callocN(sizeof(NodeTexMusgrave),
- "NodeTexMusgrave");
+ NodeTexMusgrave *tex = MEM_cnew<NodeTexMusgrave>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->musgrave_type = SHD_MUSGRAVE_FBM;
@@ -102,40 +115,447 @@ static int node_shader_gpu_tex_musgrave(GPUMaterial *mat,
return GPU_stack_link(mat, node, name, in, out);
}
-static void node_shader_update_tex_musgrave(bNodeTree *UNUSED(ntree), bNode *node)
+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(inVectorSock, tex->dimensions != 1);
- nodeSetSocketAvailability(inWSock, tex->dimensions == 1 || tex->dimensions == 4);
- nodeSetSocketAvailability(inOffsetSock,
- tex->musgrave_type != SHD_MUSGRAVE_MULTIFRACTAL &&
- tex->musgrave_type != SHD_MUSGRAVE_FBM);
- nodeSetSocketAvailability(inGainSock,
- tex->musgrave_type == SHD_MUSGRAVE_HYBRID_MULTIFRACTAL ||
- tex->musgrave_type == SHD_MUSGRAVE_RIDGED_MULTIFRACTAL);
+ nodeSetSocketAvailability(ntree, inVectorSock, storage.dimensions != 1);
+ nodeSetSocketAvailability(ntree, inWSock, storage.dimensions == 1 || storage.dimensions == 4);
+ nodeSetSocketAvailability(ntree,
+ inOffsetSock,
+ storage.musgrave_type != SHD_MUSGRAVE_MULTIFRACTAL &&
+ storage.musgrave_type != SHD_MUSGRAVE_FBM);
+ nodeSetSocketAvailability(ntree,
+ inGainSock,
+ 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");
}
-void register_node_type_sh_tex_musgrave(void)
+class MusgraveFunction : public fn::MultiFunction {
+ private:
+ const int dimensions_;
+ const int musgrave_type_;
+
+ public:
+ MusgraveFunction(const int dimensions, const int musgrave_type)
+ : dimensions_(dimensions), musgrave_type_(musgrave_type)
+ {
+ BLI_assert(dimensions >= 1 && dimensions <= 4);
+ BLI_assert(musgrave_type >= 0 && musgrave_type <= 4);
+ static std::array<fn::MFSignature, 20> signatures{
+ create_signature(1, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_FBM),
+ create_signature(2, SHD_MUSGRAVE_FBM),
+ create_signature(3, SHD_MUSGRAVE_FBM),
+ create_signature(4, SHD_MUSGRAVE_FBM),
+
+ create_signature(1, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(2, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(3, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(4, SHD_MUSGRAVE_HETERO_TERRAIN),
+ };
+ this->set_signature(&signatures[dimensions + musgrave_type * 4 - 1]);
+ }
+
+ static fn::MFSignature create_signature(const int dimensions, const int musgrave_type)
+ {
+ fn::MFSignatureBuilder signature{"Musgrave"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Detail");
+ signature.single_input<float>("Dimension");
+ signature.single_input<float>("Lacunarity");
+ if (ELEM(musgrave_type,
+ SHD_MUSGRAVE_RIDGED_MULTIFRACTAL,
+ SHD_MUSGRAVE_HYBRID_MULTIFRACTAL,
+ SHD_MUSGRAVE_HETERO_TERRAIN)) {
+ signature.single_input<float>("Offset");
+ }
+ if (ELEM(musgrave_type, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL)) {
+ signature.single_input<float>("Gain");
+ }
+
+ signature.single_output<float>("Fac");
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ auto get_vector = [&](int param_index) -> VArray<float3> {
+ return params.readonly_single_input<float3>(param_index, "Vector");
+ };
+ auto get_w = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "W");
+ };
+ auto get_scale = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Scale");
+ };
+ auto get_detail = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Detail");
+ };
+ auto get_dimension = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Dimension");
+ };
+ auto get_lacunarity = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Lacunarity");
+ };
+ auto get_offset = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Offset");
+ };
+ auto get_gain = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Gain");
+ };
+
+ auto get_r_factor = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "Fac");
+ };
+
+ int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &detail = get_detail(param++);
+ const VArray<float> &dimension = get_dimension(param++);
+ const VArray<float> &lacunarity = get_lacunarity(param++);
+
+ switch (musgrave_type_) {
+ case SHD_MUSGRAVE_MULTIFRACTAL: {
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_RIDGED_MULTIFRACTAL: {
+ const VArray<float> &offset = get_offset(param++);
+ const VArray<float> &gain = get_gain(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_HYBRID_MULTIFRACTAL: {
+ const VArray<float> &offset = get_offset(param++);
+ const VArray<float> &gain = get_gain(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_FBM: {
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_HETERO_TERRAIN: {
+ const VArray<float> &offset = get_offset(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+};
+
+static void sh_node_musgrave_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
{
+ bNode &node = builder.node();
+ NodeTexMusgrave *tex = (NodeTexMusgrave *)node.storage;
+ builder.construct_and_set_matching_fn<MusgraveFunction>(tex->dimensions, tex->musgrave_type);
+}
+
+} // namespace blender::nodes::node_shader_tex_musgrave_cc
+
+void register_node_type_sh_tex_musgrave()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_musgrave_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::sh_node_tex_musgrave_declare;
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_musgrave_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_musgrave;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_tex_musgrave);
+ node_type_init(&ntype, file_ns::node_shader_init_tex_musgrave);
node_type_storage(
&ntype, "NodeTexMusgrave", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_musgrave);
- node_type_update(&ntype, node_shader_update_tex_musgrave);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_musgrave);
+ node_type_update(&ntype, file_ns::node_shader_update_tex_musgrave);
+ ntype.build_multi_function = file_ns::sh_node_musgrave_build_multi_function;
nodeRegisterType(&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 6ffc8979815..1c703313edf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc
@@ -17,34 +17,45 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
#include "BLI_noise.hh"
-namespace blender::nodes {
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_noise_cc {
+
+NODE_STORAGE_FUNCS(NodeTexNoise)
static void sh_node_tex_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").implicit_field();
- b.add_input<decl::Float>("W").min(-1000.0f).max(1000.0f);
- b.add_input<decl::Float>("Scale").min(-1000.0f).max(1000.0f).default_value(5.0f);
- b.add_input<decl::Float>("Detail").min(0.0f).max(16.0f).default_value(2.0f);
- b.add_input<decl::Float>("Roughness")
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ 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"))
.min(0.0f)
.max(1.0f)
.default_value(0.5f)
.subtype(PROP_FACTOR);
- b.add_input<decl::Float>("Distortion").min(-1000.0f).max(1000.0f).default_value(0.0f);
- b.add_output<decl::Float>("Fac").no_muted_links();
- b.add_output<decl::Color>("Color").no_muted_links();
-};
+ b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(0.0f);
+ b.add_output<decl::Float>(N_("Fac")).no_muted_links();
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+}
-} // namespace blender::nodes
+static void node_shader_buts_tex_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "noise_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_tex_noise(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexNoise *tex = (NodeTexNoise *)MEM_callocN(sizeof(NodeTexNoise), "NodeTexNoise");
+ NodeTexNoise *tex = MEM_cnew<NodeTexNoise>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->dimensions = 3;
@@ -71,23 +82,21 @@ 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);
}
-static void node_shader_update_tex_noise(bNodeTree *UNUSED(ntree), bNode *node)
+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(sockVector, tex->dimensions != 1);
- nodeSetSocketAvailability(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 {
-
class NoiseFunction : public fn::MultiFunction {
private:
int dimensions_;
@@ -167,14 +176,14 @@ class NoiseFunction : public fn::MultiFunction {
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
if (compute_factor) {
for (int64_t i : mask) {
- const float2 position = vector[i] * scale[i];
+ const float2 position = float2(vector[i] * scale[i]);
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
}
}
if (compute_color) {
for (int64_t i : mask) {
- const float2 position = vector[i] * scale[i];
+ const float2 position = float2(vector[i] * scale[i]);
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], distortion[i]);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
@@ -229,30 +238,39 @@ 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
+} // namespace blender::nodes::node_shader_tex_noise_cc
-/* node type definition */
-void register_node_type_sh_tex_noise(void)
+void register_node_type_sh_tex_noise()
{
+ namespace file_ns = blender::nodes::node_shader_tex_noise_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_TEX_NOISE, "Noise Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::sh_node_tex_noise_declare;
- node_type_init(&ntype, node_shader_init_tex_noise);
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_NOISE, "Noise Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_noise_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_noise;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_noise);
node_type_storage(
&ntype, "NodeTexNoise", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_noise);
- node_type_update(&ntype, node_shader_update_tex_noise);
- ntype.build_multi_function = blender::nodes::sh_node_noise_build_multi_function;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_noise);
+ node_type_update(&ntype, file_ns::node_shader_update_tex_noise);
+ ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c
deleted file mode 100644
index 14cd1fd4c0c..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2015 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-#include "RE_texture.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_tex_pointdensity_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_pointdensity_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Density"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
- {-1, ""},
-};
-
-static void node_shader_init_tex_pointdensity(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeShaderTexPointDensity *point_density = MEM_callocN(sizeof(NodeShaderTexPointDensity),
- "new pd node");
- point_density->resolution = 100;
- point_density->radius = 0.3f;
- point_density->space = SHD_POINTDENSITY_SPACE_OBJECT;
- point_density->color_source = SHD_POINTDENSITY_COLOR_PARTAGE;
- node->storage = point_density;
-}
-
-static void node_shader_free_tex_pointdensity(bNode *node)
-{
- NodeShaderTexPointDensity *point_density = node->storage;
- PointDensity *pd = &point_density->pd;
- RE_point_density_free(pd);
- BKE_texture_pointdensity_free_data(pd);
- memset(pd, 0, sizeof(*pd));
- MEM_freeN(point_density);
-}
-
-static void node_shader_copy_tex_pointdensity(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
-{
- dest_node->storage = MEM_dupallocN(src_node->storage);
- NodeShaderTexPointDensity *point_density = dest_node->storage;
- PointDensity *pd = &point_density->pd;
- memset(pd, 0, sizeof(*pd));
-}
-
-/* node type definition */
-void register_node_type_sh_tex_pointdensity(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_POINTDENSITY, "Point Density", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_pointdensity_in, sh_node_tex_pointdensity_out);
- node_type_init(&ntype, node_shader_init_tex_pointdensity);
- node_type_storage(&ntype,
- "NodeShaderTexPointDensity",
- node_shader_free_tex_pointdensity,
- node_shader_copy_tex_pointdensity);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc
new file mode 100644
index 00000000000..1a4cf70565f
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.cc
@@ -0,0 +1,131 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2015 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "RE_texture.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_pointdensity_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector")).hide_value();
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Density"));
+}
+
+static void node_shader_buts_tex_pointdensity(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderTexPointDensity *shader_point_density = (NodeShaderTexPointDensity *)node->storage;
+ Object *ob = (Object *)node->id;
+
+ PointerRNA ob_ptr, obdata_ptr;
+ RNA_id_pointer_create((ID *)ob, &ob_ptr);
+ RNA_id_pointer_create(ob ? (ID *)ob->data : nullptr, &obdata_ptr);
+
+ uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "object", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+
+ if (node->id && shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
+ PointerRNA dataptr;
+ RNA_id_pointer_create((ID *)node->id, &dataptr);
+ uiItemPointerR(
+ layout, ptr, "particle_system", &dataptr, "particle_systems", nullptr, ICON_NONE);
+ }
+
+ uiItemR(layout, ptr, "space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "radius", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "interpolation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "resolution", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
+ uiItemR(layout, ptr, "particle_color_source", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+ else {
+ uiItemR(layout, ptr, "vertex_color_source", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTWEIGHT) {
+ if (ob_ptr.data) {
+ uiItemPointerR(
+ layout, ptr, "vertex_attribute_name", &ob_ptr, "vertex_groups", "", ICON_NONE);
+ }
+ }
+ if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTCOL) {
+ if (obdata_ptr.data) {
+ uiItemPointerR(
+ layout, ptr, "vertex_attribute_name", &obdata_ptr, "vertex_colors", "", ICON_NONE);
+ }
+ }
+ }
+}
+
+static void node_shader_init_tex_pointdensity(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderTexPointDensity *point_density = MEM_cnew<NodeShaderTexPointDensity>("new pd node");
+ point_density->resolution = 100;
+ point_density->radius = 0.3f;
+ point_density->space = SHD_POINTDENSITY_SPACE_OBJECT;
+ point_density->color_source = SHD_POINTDENSITY_COLOR_PARTAGE;
+ node->storage = point_density;
+}
+
+static void node_shader_free_tex_pointdensity(bNode *node)
+{
+ NodeShaderTexPointDensity *point_density = (NodeShaderTexPointDensity *)node->storage;
+ PointDensity *pd = &point_density->pd;
+ RE_point_density_free(pd);
+ BKE_texture_pointdensity_free_data(pd);
+ memset(pd, 0, sizeof(*pd));
+ MEM_freeN(point_density);
+}
+
+static void node_shader_copy_tex_pointdensity(bNodeTree *UNUSED(dest_ntree),
+ bNode *dest_node,
+ const bNode *src_node)
+{
+ dest_node->storage = MEM_dupallocN(src_node->storage);
+ NodeShaderTexPointDensity *point_density = (NodeShaderTexPointDensity *)dest_node->storage;
+ PointDensity *pd = &point_density->pd;
+ memset(pd, 0, sizeof(*pd));
+}
+
+} // namespace blender::nodes::node_shader_tex_pointdensity_cc
+
+/* node type definition */
+void register_node_type_sh_tex_pointdensity()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_pointdensity_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_TEX_POINTDENSITY, "Point Density", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_pointdensity;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_pointdensity);
+ node_type_storage(&ntype,
+ "NodeShaderTexPointDensity",
+ file_ns::node_shader_free_tex_pointdensity,
+ file_ns::node_shader_copy_tex_pointdensity);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
index 5dc11c4df00..b8728d69bba 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
@@ -17,24 +17,66 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
#include "sky_model.h"
-/* **************** OUTPUT ******************** */
+#include "BKE_context.h"
+#include "BKE_scene.h"
-static bNodeSocketTemplate sh_node_tex_sky_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {-1, ""},
-};
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_tex_sky_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_tex_sky_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector")).hide_value();
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+}
+
+static void node_shader_buts_tex_sky(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "sky_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) {
+ uiItemR(layout, ptr, "sun_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) {
+ uiItemR(layout, ptr, "sun_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "ground_albedo", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
+ Scene *scene = CTX_data_scene(C);
+ if (BKE_scene_uses_blender_eevee(scene)) {
+ uiItemL(layout, TIP_("Nishita not available in Eevee"), ICON_ERROR);
+ }
+ uiItemR(layout, ptr, "sun_disc", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+
+ uiLayout *col;
+ if (RNA_boolean_get(ptr, "sun_disc")) {
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "sun_size", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sun_intensity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "sun_elevation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sun_rotation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+
+ uiItemR(layout, ptr, "altitude", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "air_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "dust_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "ozone_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ }
+}
static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexSky *tex = MEM_callocN(sizeof(NodeTexSky), "NodeTexSky");
+ NodeTexSky *tex = MEM_cnew<NodeTexSky>("NodeTexSky");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->sun_direction[0] = 0.0f;
@@ -55,10 +97,10 @@ static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = tex;
}
-typedef struct SkyModelPreetham {
+struct SkyModelPreetham {
float config_Y[5], config_x[5], config_y[5]; /* named after xyY color space */
float radiance[3];
-} SkyModelPreetham;
+};
static float sky_perez_function(const float *lam, float theta, float gamma)
{
@@ -195,27 +237,32 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
}
-static void node_shader_update_sky(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
NodeTexSky *tex = (NodeTexSky *)node->storage;
- nodeSetSocketAvailability(sockVector, !(tex->sky_model == 2 && tex->sun_disc == 1));
+ nodeSetSocketAvailability(ntree, sockVector, !(tex->sky_model == 2 && tex->sun_disc == 1));
}
+} // namespace blender::nodes::node_shader_tex_sky_cc
+
/* node type definition */
-void register_node_type_sh_tex_sky(void)
+void register_node_type_sh_tex_sky()
{
+ namespace file_ns = blender::nodes::node_shader_tex_sky_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_SKY, "Sky Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_sky_in, sh_node_tex_sky_out);
+ sh_node_type_base(&ntype, SH_NODE_TEX_SKY, "Sky Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_sky;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_tex_sky);
+ node_type_init(&ntype, file_ns::node_shader_init_tex_sky);
node_type_storage(&ntype, "NodeTexSky", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_sky);
- /* remove Vector input for Nishita */
- node_type_update(&ntype, node_shader_update_sky);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_sky);
+ /* Remove vector input for Nishita sky model. */
+ node_type_update(&ntype, file_ns::node_shader_update_sky);
nodeRegisterType(&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 e12e5724e8e..209f96449cd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc
@@ -17,39 +17,68 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "BLI_noise.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_voronoi_cc {
+
+NODE_STORAGE_FUNCS(NodeTexVoronoi)
static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").hide_value();
- b.add_input<decl::Float>("W").min(-1000.0f).max(1000.0f);
- b.add_input<decl::Float>("Scale").min(-1000.0f).max(1000.0f).default_value(5.0f);
- b.add_input<decl::Float>("Smoothness")
+ b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
+ 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>("Exponent").min(0.0f).max(32.0f).default_value(0.5f);
- b.add_input<decl::Float>("Randomness")
+ .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)
.default_value(1.0f)
.subtype(PROP_FACTOR);
- b.add_output<decl::Float>("Distance").no_muted_links();
- b.add_output<decl::Color>("Color").no_muted_links();
- b.add_output<decl::Vector>("Position").no_muted_links();
- b.add_output<decl::Float>("W").no_muted_links();
- b.add_output<decl::Float>("Radius").no_muted_links();
-};
+ 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().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
+static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "voronoi_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "feature", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ int feature = RNA_enum_get(ptr, "feature");
+ if (!ELEM(feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS) &&
+ RNA_enum_get(ptr, "voronoi_dimensions") != 1) {
+ uiItemR(layout, ptr, "distance", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+}
static void node_shader_init_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeTexVoronoi *tex = (NodeTexVoronoi *)MEM_callocN(sizeof(NodeTexVoronoi), "NodeTexVoronoi");
+ NodeTexVoronoi *tex = MEM_cnew<NodeTexVoronoi>(__func__);
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->dimensions = 3;
@@ -121,7 +150,7 @@ static int node_shader_gpu_tex_voronoi(GPUMaterial *mat,
return GPU_stack_link(mat, node, name, in, out, GPU_constant(&metric));
}
-static void node_shader_update_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
{
bNodeSocket *inVectorSock = nodeFindSocket(node, SOCK_IN, "Vector");
bNodeSocket *inWSock = nodeFindSocket(node, SOCK_IN, "W");
@@ -134,41 +163,1210 @@ static void node_shader_update_tex_voronoi(bNodeTree *UNUSED(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(inWSock, tex->dimensions == 1 || tex->dimensions == 4);
- nodeSetSocketAvailability(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(inSmoothnessSock, tex->feature == SHD_VORONOI_SMOOTH_F1);
- nodeSetSocketAvailability(outDistanceSock, tex->feature != SHD_VORONOI_N_SPHERE_RADIUS);
- nodeSetSocketAvailability(outColorSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS);
- nodeSetSocketAvailability(outPositionSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS &&
- tex->dimensions != 1);
- nodeSetSocketAvailability(outWSock,
- tex->feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
- tex->feature != SHD_VORONOI_N_SPHERE_RADIUS &&
- (tex->dimensions == 1 || tex->dimensions == 4));
- nodeSetSocketAvailability(outRadiusSock, tex->feature == SHD_VORONOI_N_SPHERE_RADIUS);
+ 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, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
+ nodeSetSocketAvailability(ntree,
+ outColorSock,
+ storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
+ storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
+ nodeSetSocketAvailability(ntree,
+ outPositionSock,
+ storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE &&
+ storage.feature != SHD_VORONOI_N_SPHERE_RADIUS &&
+ storage.dimensions != 1);
+ nodeSetSocketAvailability(ntree,
+ outWSock,
+ 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);
+}
+
+static MultiFunction::ExecutionHints voronoi_execution_hints{50, false};
+
+class VoronoiMinowskiFunction : public fn::MultiFunction {
+ private:
+ int dimensions_;
+ int feature_;
+
+ public:
+ VoronoiMinowskiFunction(int dimensions, int feature) : dimensions_(dimensions), feature_(feature)
+ {
+ BLI_assert(dimensions >= 2 && dimensions <= 4);
+ BLI_assert(feature >= 0 && feature <= 2);
+ static std::array<fn::MFSignature, 9> signatures{
+ create_signature(2, SHD_VORONOI_F1),
+ create_signature(3, SHD_VORONOI_F1),
+ create_signature(4, SHD_VORONOI_F1),
+
+ create_signature(2, SHD_VORONOI_F2),
+ create_signature(3, SHD_VORONOI_F2),
+ create_signature(4, SHD_VORONOI_F2),
+
+ create_signature(2, SHD_VORONOI_SMOOTH_F1),
+ create_signature(3, SHD_VORONOI_SMOOTH_F1),
+ create_signature(4, SHD_VORONOI_SMOOTH_F1),
+ };
+ this->set_signature(&signatures[(dimensions - 1) + feature * 3 - 1]);
+ }
+
+ static fn::MFSignature create_signature(int dimensions, int feature)
+ {
+ fn::MFSignatureBuilder signature{"voronoi_minowski"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+ signature.single_input<float>("Scale");
+ if (feature == SHD_VORONOI_SMOOTH_F1) {
+ signature.single_input<float>("Smoothness");
+ }
+ signature.single_input<float>("Exponent");
+ signature.single_input<float>("Randomness");
+ signature.single_output<float>("Distance");
+ signature.single_output<ColorGeometry4f>("Color");
+
+ if (dimensions != 1) {
+ signature.single_output<float3>("Position");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_output<float>("W");
+ }
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ auto get_vector = [&](int param_index) -> VArray<float3> {
+ return params.readonly_single_input<float3>(param_index, "Vector");
+ };
+ auto get_w = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "W");
+ };
+ auto get_scale = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Scale");
+ };
+ auto get_smoothness = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Smoothness");
+ };
+ auto get_exponent = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Exponent");
+ };
+ auto get_randomness = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Randomness");
+ };
+ auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "Distance");
+ };
+ auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> {
+ return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color");
+ };
+ auto get_r_position = [&](int param_index) -> MutableSpan<float3> {
+ return params.uninitialized_single_output_if_required<float3>(param_index, "Position");
+ };
+ auto get_r_w = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "W");
+ };
+
+ int param = 0;
+ switch (dimensions_) {
+ case 2: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_f1(float2(vector[i].x, vector[i].y) * scale[i],
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_f2(float2(vector[i].x, vector[i].y) * scale[i],
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_smooth_f1(float2(vector[i].x, vector[i].y) * scale[i],
+ smth,
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 3: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f1(vector[i] * scale[i],
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f2(vector[i] * scale[i],
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_smooth_f1(vector[i] * scale[i],
+ smth,
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 4: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_f1(p,
+ exponent[i],
+ rand,
+ SHD_VORONOI_F1,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_f2(p,
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &exponent = get_exponent(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_smooth_f1(p,
+ smth,
+ exponent[i],
+ rand,
+ SHD_VORONOI_MINKOWSKI,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
+};
+
+class VoronoiMetricFunction : public fn::MultiFunction {
+ private:
+ int dimensions_;
+ int feature_;
+ int metric_;
+
+ public:
+ VoronoiMetricFunction(int dimensions, int feature, int metric)
+ : dimensions_(dimensions), feature_(feature), metric_(metric)
+ {
+ BLI_assert(dimensions >= 1 && dimensions <= 4);
+ BLI_assert(feature >= 0 && feature <= 4);
+ static std::array<fn::MFSignature, 12> signatures{
+ create_signature(1, SHD_VORONOI_F1),
+ create_signature(2, SHD_VORONOI_F1),
+ create_signature(3, SHD_VORONOI_F1),
+ create_signature(4, SHD_VORONOI_F1),
+
+ create_signature(1, SHD_VORONOI_F2),
+ create_signature(2, SHD_VORONOI_F2),
+ create_signature(3, SHD_VORONOI_F2),
+ create_signature(4, SHD_VORONOI_F2),
+
+ create_signature(1, SHD_VORONOI_SMOOTH_F1),
+ create_signature(2, SHD_VORONOI_SMOOTH_F1),
+ create_signature(3, SHD_VORONOI_SMOOTH_F1),
+ create_signature(4, SHD_VORONOI_SMOOTH_F1),
+ };
+ this->set_signature(&signatures[dimensions + feature * 4 - 1]);
+ }
+
+ static fn::MFSignature create_signature(int dimensions, int feature)
+ {
+ fn::MFSignatureBuilder signature{"voronoi_metric"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+ signature.single_input<float>("Scale");
+ if (feature == SHD_VORONOI_SMOOTH_F1) {
+ signature.single_input<float>("Smoothness");
+ }
+ signature.single_input<float>("Randomness");
+ signature.single_output<float>("Distance");
+ signature.single_output<ColorGeometry4f>("Color");
+
+ if (dimensions != 1) {
+ signature.single_output<float3>("Position");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_output<float>("W");
+ }
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ auto get_vector = [&](int param_index) -> VArray<float3> {
+ return params.readonly_single_input<float3>(param_index, "Vector");
+ };
+ auto get_w = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "W");
+ };
+ auto get_scale = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Scale");
+ };
+ auto get_smoothness = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Smoothness");
+ };
+ auto get_randomness = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Randomness");
+ };
+ auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "Distance");
+ };
+ auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> {
+ return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color");
+ };
+ auto get_r_position = [&](int param_index) -> MutableSpan<float3> {
+ return params.uninitialized_single_output_if_required<float3>(param_index, "Position");
+ };
+ auto get_r_w = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "W");
+ };
+
+ int param = 0;
+ switch (dimensions_) {
+ case 1: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float p = w[i] * scale[i];
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f1(p,
+ rand,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_w ? &r_w[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_w) {
+ r_w[i] = safe_divide(r_w[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float p = w[i] * scale[i];
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f2(p,
+ rand,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_w ? &r_w[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_w) {
+ r_w[i] = safe_divide(r_w[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float p = w[i] * scale[i];
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_smooth_f1(p,
+ smth,
+ rand,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_w ? &r_w[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_w) {
+ r_w[i] = safe_divide(r_w[i], scale[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 2: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_f1(float2(vector[i].x, vector[i].y) * scale[i],
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_f2(float2(vector[i].x, vector[i].y) * scale[i],
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ float2 pos;
+ noise::voronoi_smooth_f1(float2(vector[i].x, vector[i].y) * scale[i],
+ smth,
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ pos = math::safe_divide(pos, scale[i]);
+ r_position[i] = float3(pos.x, pos.y, 0.0f);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 3: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f1(vector[i] * scale[i],
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_f2(vector[i] * scale[i],
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ {
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ float3 col;
+ noise::voronoi_smooth_f1(vector[i] * scale[i],
+ smth,
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position ? &r_position[i] : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position) {
+ r_position[i] = math::safe_divide(r_position[i], scale[i]);
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ break;
+ }
+ case 4: {
+ switch (feature_) {
+ case SHD_VORONOI_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_f1(p,
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_F2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_f2(p,
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ case SHD_VORONOI_SMOOTH_F1: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &smoothness = get_smoothness(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
+ MutableSpan<float3> r_position = get_r_position(param++);
+ MutableSpan<float> r_w = get_r_w(param++);
+ const bool calc_distance = !r_distance.is_empty();
+ const bool calc_color = !r_color.is_empty();
+ const bool calc_position = !r_position.is_empty();
+ const bool calc_w = !r_w.is_empty();
+ for (int64_t i : mask) {
+ const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ float3 col;
+ float4 pos;
+ noise::voronoi_smooth_f1(p,
+ smth,
+ 0.0f,
+ rand,
+ metric_,
+ calc_distance ? &r_distance[i] : nullptr,
+ calc_color ? &col : nullptr,
+ calc_position || calc_w ? &pos : nullptr);
+ if (calc_color) {
+ r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
+ }
+ if (calc_position || calc_w) {
+ pos = math::safe_divide(pos, scale[i]);
+ if (calc_position) {
+ r_position[i] = float3(pos.x, pos.y, pos.z);
+ }
+ if (calc_w) {
+ r_w[i] = pos.w;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
+};
+
+class VoronoiEdgeFunction : public fn::MultiFunction {
+ private:
+ int dimensions_;
+ int feature_;
+
+ public:
+ VoronoiEdgeFunction(int dimensions, int feature) : dimensions_(dimensions), feature_(feature)
+ {
+ BLI_assert(dimensions >= 1 && dimensions <= 4);
+ BLI_assert(feature >= 3 && feature <= 4);
+ static std::array<fn::MFSignature, 8> signatures{
+ create_signature(1, SHD_VORONOI_DISTANCE_TO_EDGE),
+ create_signature(2, SHD_VORONOI_DISTANCE_TO_EDGE),
+ create_signature(3, SHD_VORONOI_DISTANCE_TO_EDGE),
+ create_signature(4, SHD_VORONOI_DISTANCE_TO_EDGE),
+
+ create_signature(1, SHD_VORONOI_N_SPHERE_RADIUS),
+ create_signature(2, SHD_VORONOI_N_SPHERE_RADIUS),
+ create_signature(3, SHD_VORONOI_N_SPHERE_RADIUS),
+ create_signature(4, SHD_VORONOI_N_SPHERE_RADIUS),
+ };
+ this->set_signature(&signatures[dimensions + (feature - 3) * 4 - 1]);
+ }
+
+ static fn::MFSignature create_signature(int dimensions, int feature)
+ {
+ fn::MFSignatureBuilder signature{"voronoi_edge"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Randomness");
+
+ if (feature == SHD_VORONOI_DISTANCE_TO_EDGE) {
+ signature.single_output<float>("Distance");
+ }
+ if (feature == SHD_VORONOI_N_SPHERE_RADIUS) {
+ signature.single_output<float>("Radius");
+ }
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ auto get_vector = [&](int param_index) -> VArray<float3> {
+ return params.readonly_single_input<float3>(param_index, "Vector");
+ };
+ auto get_w = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "W");
+ };
+ auto get_scale = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Scale");
+ };
+ auto get_randomness = [&](int param_index) -> VArray<float> {
+ return params.readonly_single_input<float>(param_index, "Randomness");
+ };
+ auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output<float>(param_index, "Distance");
+ };
+ auto get_r_radius = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output<float>(param_index, "Radius");
+ };
+
+ int param = 0;
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ switch (feature_) {
+ case SHD_VORONOI_DISTANCE_TO_EDGE: {
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float p = w[i] * scale[i];
+ noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
+ }
+ break;
+ }
+ case SHD_VORONOI_N_SPHERE_RADIUS: {
+ MutableSpan<float> r_radius = get_r_radius(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float p = w[i] * scale[i];
+ noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ switch (feature_) {
+ case SHD_VORONOI_DISTANCE_TO_EDGE: {
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
+ noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
+ }
+ break;
+ }
+ case SHD_VORONOI_N_SPHERE_RADIUS: {
+ MutableSpan<float> r_radius = get_r_radius(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
+ noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ switch (feature_) {
+ case SHD_VORONOI_DISTANCE_TO_EDGE: {
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ noise::voronoi_distance_to_edge(vector[i] * scale[i], rand, &r_distance[i]);
+ }
+ break;
+ }
+ case SHD_VORONOI_N_SPHERE_RADIUS: {
+ MutableSpan<float> r_radius = get_r_radius(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ noise::voronoi_n_sphere_radius(vector[i] * scale[i], rand, &r_radius[i]);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(param++);
+ const VArray<float> &w = get_w(param++);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &randomness = get_randomness(param++);
+ switch (feature_) {
+ case SHD_VORONOI_DISTANCE_TO_EDGE: {
+ MutableSpan<float> r_distance = get_r_distance(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
+ }
+ break;
+ }
+ case SHD_VORONOI_N_SPHERE_RADIUS: {
+ MutableSpan<float> r_radius = get_r_radius(param++);
+ for (int64_t i : mask) {
+ const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
+ const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
+ noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ ExecutionHints get_execution_hints() const override
+ {
+ return voronoi_execution_hints;
+ }
+};
+
+static void sh_node_voronoi_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ 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>(storage.dimensions,
+ storage.feature);
+ }
+ else if (minowski) {
+ builder.construct_and_set_matching_fn<VoronoiMinowskiFunction>(storage.dimensions,
+ storage.feature);
+ }
+ else {
+ builder.construct_and_set_matching_fn<VoronoiMetricFunction>(
+ storage.dimensions, storage.feature, storage.distance);
+ }
}
-void register_node_type_sh_tex_voronoi(void)
+} // namespace blender::nodes::node_shader_tex_voronoi_cc
+
+void register_node_type_sh_tex_voronoi()
{
+ namespace file_ns = blender::nodes::node_shader_tex_voronoi_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::sh_node_tex_voronoi_declare;
- node_type_init(&ntype, node_shader_init_tex_voronoi);
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_voronoi_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_voronoi;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_voronoi);
node_type_storage(
&ntype, "NodeTexVoronoi", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_voronoi);
- node_type_update(&ntype, node_shader_update_tex_voronoi);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_voronoi);
+ node_type_update(&ntype, file_ns::node_shader_update_tex_voronoi);
+ ntype.build_multi_function = file_ns::sh_node_voronoi_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
deleted file mode 100644
index bba568ed5b7..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-#include "../node_shader_util.h"
-
-/* **************** WAVE ******************** */
-
-static bNodeSocketTemplate sh_node_tex_wave_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {SOCK_FLOAT, N_("Distortion"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {SOCK_FLOAT, N_("Detail"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 16.0f},
- {SOCK_FLOAT, N_("Detail Scale"), 1.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {SOCK_FLOAT, N_("Detail Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Phase Offset"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_tex_wave_out[] = {
- {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
- {SOCK_FLOAT,
- N_("Fac"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- PROP_FACTOR,
- SOCK_NO_INTERNAL_LINK},
- {-1, ""},
-};
-
-static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeTexWave *tex = MEM_callocN(sizeof(NodeTexWave), "NodeTexWave");
- BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
- BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->wave_type = SHD_WAVE_BANDS;
- tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_X;
- tex->rings_direction = SHD_WAVE_RINGS_DIRECTION_X;
- tex->wave_profile = SHD_WAVE_PROFILE_SIN;
- node->storage = tex;
-}
-
-static int node_shader_gpu_tex_wave(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
- node_shader_gpu_tex_mapping(mat, node, in, out);
-
- NodeTexWave *tex = (NodeTexWave *)node->storage;
- float wave_type = tex->wave_type;
- float bands_direction = tex->bands_direction;
- float rings_direction = tex->rings_direction;
- float wave_profile = tex->wave_profile;
-
- return GPU_stack_link(mat,
- node,
- "node_tex_wave",
- in,
- out,
- GPU_constant(&wave_type),
- GPU_constant(&bands_direction),
- GPU_constant(&rings_direction),
- GPU_constant(&wave_profile));
-}
-
-/* node type definition */
-void register_node_type_sh_tex_wave(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_TEX_WAVE, "Wave Texture", NODE_CLASS_TEXTURE, 0);
- node_type_socket_templates(&ntype, sh_node_tex_wave_in, sh_node_tex_wave_out);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_tex_wave);
- node_type_storage(&ntype, "NodeTexWave", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_tex_wave);
-
- nodeRegisterType(&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
new file mode 100644
index 00000000000..fc6c66061ff
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc
@@ -0,0 +1,250 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "node_shader_util.hh"
+
+#include "BLI_noise.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_wave_cc {
+
+static void sh_node_tex_wave_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field();
+ b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
+ b.add_input<decl::Float>(N_("Distortion")).min(-1000.0f).max(1000.0f).default_value(0.0f);
+ b.add_input<decl::Float>(N_("Detail")).min(0.0f).max(15.0f).default_value(2.0f);
+ b.add_input<decl::Float>(N_("Detail Scale")).min(-1000.0f).max(1000.0f).default_value(1.0f);
+ b.add_input<decl::Float>(N_("Detail Roughness"))
+ .min(0.0f)
+ .max(1.0f)
+ .default_value(0.5f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Float>(N_("Phase Offset")).min(-1000.0f).max(1000.0f).default_value(0.0f);
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+ b.add_output<decl::Float>(N_("Fac")).no_muted_links();
+}
+
+static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "wave_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ int type = RNA_enum_get(ptr, "wave_type");
+ if (type == SHD_WAVE_BANDS) {
+ uiItemR(layout, ptr, "bands_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+ else { /* SHD_WAVE_RINGS */
+ uiItemR(layout, ptr, "rings_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ }
+
+ uiItemR(layout, ptr, "wave_profile", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeTexWave *tex = MEM_cnew<NodeTexWave>(__func__);
+ BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
+ BKE_texture_colormapping_default(&tex->base.color_mapping);
+ tex->wave_type = SHD_WAVE_BANDS;
+ tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_X;
+ tex->rings_direction = SHD_WAVE_RINGS_DIRECTION_X;
+ tex->wave_profile = SHD_WAVE_PROFILE_SIN;
+ node->storage = tex;
+}
+
+static int node_shader_gpu_tex_wave(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
+ node_shader_gpu_tex_mapping(mat, node, in, out);
+
+ NodeTexWave *tex = (NodeTexWave *)node->storage;
+ float wave_type = tex->wave_type;
+ float bands_direction = tex->bands_direction;
+ float rings_direction = tex->rings_direction;
+ float wave_profile = tex->wave_profile;
+
+ return GPU_stack_link(mat,
+ node,
+ "node_tex_wave",
+ in,
+ out,
+ GPU_constant(&wave_type),
+ GPU_constant(&bands_direction),
+ GPU_constant(&rings_direction),
+ GPU_constant(&wave_profile));
+}
+
+class WaveFunction : public fn::MultiFunction {
+ private:
+ int wave_type_;
+ int bands_direction_;
+ int rings_direction_;
+ int wave_profile_;
+
+ public:
+ WaveFunction(int wave_type, int bands_direction, int rings_direction, int wave_profile)
+ : wave_type_(wave_type),
+ bands_direction_(bands_direction),
+ rings_direction_(rings_direction),
+ wave_profile_(wave_profile)
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"MagicFunction"};
+ signature.single_input<float3>("Vector");
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Distortion");
+ signature.single_input<float>("Detail");
+ signature.single_input<float>("Detail Scale");
+ signature.single_input<float>("Detail Roughness");
+ signature.single_input<float>("Phase Offset");
+ signature.single_output<ColorGeometry4f>("Color");
+ signature.single_output<float>("Fac");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");
+ const VArray<float> &distortion = params.readonly_single_input<float>(2, "Distortion");
+ const VArray<float> &detail = params.readonly_single_input<float>(3, "Detail");
+ const VArray<float> &dscale = params.readonly_single_input<float>(4, "Detail Scale");
+ const VArray<float> &droughness = params.readonly_single_input<float>(5, "Detail Roughness");
+ const VArray<float> &phase = params.readonly_single_input<float>(6, "Phase Offset");
+
+ MutableSpan<ColorGeometry4f> r_color =
+ params.uninitialized_single_output_if_required<ColorGeometry4f>(7, "Color");
+ MutableSpan<float> r_fac = params.uninitialized_single_output<float>(8, "Fac");
+
+ for (int64_t i : mask) {
+
+ float3 p = vector[i] * scale[i];
+ /* Prevent precision issues on unit coordinates. */
+ p = (p + 0.000001f) * 0.999999f;
+
+ float n = 0.0f;
+ float val = 0.0f;
+
+ switch (wave_type_) {
+ case SHD_WAVE_BANDS:
+ switch (bands_direction_) {
+ case SHD_WAVE_BANDS_DIRECTION_X:
+ n = p.x * 20.0f;
+ break;
+ case SHD_WAVE_BANDS_DIRECTION_Y:
+ n = p.y * 20.0f;
+ break;
+ case SHD_WAVE_BANDS_DIRECTION_Z:
+ n = p.z * 20.0f;
+ break;
+ case SHD_WAVE_BANDS_DIRECTION_DIAGONAL:
+ n = (p.x + p.y + p.z) * 10.0f;
+ break;
+ }
+ break;
+ case SHD_WAVE_RINGS:
+ float3 rp = p;
+ switch (rings_direction_) {
+ case SHD_WAVE_RINGS_DIRECTION_X:
+ rp *= float3(0.0f, 1.0f, 1.0f);
+ break;
+ case SHD_WAVE_RINGS_DIRECTION_Y:
+ rp *= float3(1.0f, 0.0f, 1.0f);
+ break;
+ case SHD_WAVE_RINGS_DIRECTION_Z:
+ rp *= float3(1.0f, 1.0f, 0.0f);
+ break;
+ case SHD_WAVE_RINGS_DIRECTION_SPHERICAL:
+ /* Ignore. */
+ break;
+ }
+ n = len_v3(rp) * 20.0f;
+ break;
+ }
+
+ n += phase[i];
+
+ if (distortion[i] != 0.0f) {
+ n += distortion[i] *
+ (noise::perlin_fractal(p * dscale[i], detail[i], droughness[i]) * 2.0f - 1.0f);
+ }
+
+ switch (wave_profile_) {
+ case SHD_WAVE_PROFILE_SIN:
+ val = 0.5f + 0.5f * sinf(n - M_PI_2);
+ break;
+ case SHD_WAVE_PROFILE_SAW:
+ n /= M_PI * 2.0f;
+ val = n - floorf(n);
+ break;
+ case SHD_WAVE_PROFILE_TRI:
+ n /= M_PI * 2.0f;
+ val = fabsf(n - floorf(n + 0.5f)) * 2.0f;
+ break;
+ }
+
+ r_fac[i] = val;
+ }
+ if (!r_color.is_empty()) {
+ for (int64_t i : mask) {
+ r_color[i] = ColorGeometry4f(r_fac[i], r_fac[i], r_fac[i], 1.0f);
+ }
+ }
+ }
+};
+
+static void sh_node_wave_tex_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ NodeTexWave *tex = (NodeTexWave *)node.storage;
+ builder.construct_and_set_matching_fn<WaveFunction>(
+ tex->wave_type, tex->bands_direction, tex->rings_direction, tex->wave_profile);
+}
+
+} // namespace blender::nodes::node_shader_tex_wave_cc
+
+void register_node_type_sh_tex_wave()
+{
+ namespace file_ns = blender::nodes::node_shader_tex_wave_cc;
+
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_WAVE, "Wave Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_wave_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_tex_wave;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, file_ns::node_shader_init_tex_wave);
+ node_type_storage(&ntype, "NodeTexWave", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_wave);
+ ntype.build_multi_function = file_ns::sh_node_wave_tex_build_multi_function;
+
+ nodeRegisterType(&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 03543e5f7fe..3a5bc98896c 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
@@ -17,20 +17,31 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "BLI_noise.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_tex_white_noise_cc {
static void sh_node_tex_white_noise_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("W").min(-10000.0f).max(10000.0f);
- b.add_output<decl::Float>("Value");
- b.add_output<decl::Color>("Color");
-};
+ 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).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"));
+}
-} // namespace blender::nodes
+static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "noise_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -56,24 +67,150 @@ static int gpu_shader_tex_white_noise(GPUMaterial *mat,
return GPU_stack_link(mat, node, name, in, out);
}
-static void node_shader_update_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_tex_white_noise(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
bNodeSocket *sockW = nodeFindSocket(node, SOCK_IN, "W");
- nodeSetSocketAvailability(sockVector, node->custom1 != 1);
- nodeSetSocketAvailability(sockW, node->custom1 == 1 || node->custom1 == 4);
+ nodeSetSocketAvailability(ntree, sockVector, node->custom1 != 1);
+ nodeSetSocketAvailability(ntree, sockW, node->custom1 == 1 || node->custom1 == 4);
+}
+
+class WhiteNoiseFunction : public fn::MultiFunction {
+ private:
+ int dimensions_;
+
+ public:
+ WhiteNoiseFunction(int dimensions) : dimensions_(dimensions)
+ {
+ BLI_assert(dimensions >= 1 && dimensions <= 4);
+ static std::array<fn::MFSignature, 4> signatures{
+ create_signature(1),
+ create_signature(2),
+ create_signature(3),
+ create_signature(4),
+ };
+ this->set_signature(&signatures[dimensions - 1]);
+ }
+
+ static fn::MFSignature create_signature(int dimensions)
+ {
+ fn::MFSignatureBuilder signature{"WhiteNoise"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+
+ signature.single_output<float>("Value");
+ signature.single_output<ColorGeometry4f>("Color");
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
+
+ MutableSpan<float> r_value = params.uninitialized_single_output_if_required<float>(param++,
+ "Value");
+ MutableSpan<ColorGeometry4f> r_color =
+ params.uninitialized_single_output_if_required<ColorGeometry4f>(param++, "Color");
+
+ const bool compute_value = !r_value.is_empty();
+ const bool compute_color = !r_color.is_empty();
+
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = params.readonly_single_input<float>(0, "W");
+ if (compute_color) {
+ for (int64_t i : mask) {
+ const float3 c = noise::hash_float_to_float3(w[i]);
+ r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
+ }
+ }
+ if (compute_value) {
+ for (int64_t i : mask) {
+ r_value[i] = noise::hash_float_to_float(w[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ if (compute_color) {
+ for (int64_t i : mask) {
+ const float3 c = noise::hash_float_to_float3(float2(vector[i].x, vector[i].y));
+ r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
+ }
+ }
+ if (compute_value) {
+ for (int64_t i : mask) {
+ r_value[i] = noise::hash_float_to_float(float2(vector[i].x, vector[i].y));
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ if (compute_color) {
+ for (int64_t i : mask) {
+ const float3 c = noise::hash_float_to_float3(vector[i]);
+ r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
+ }
+ }
+ if (compute_value) {
+ for (int64_t i : mask) {
+ r_value[i] = noise::hash_float_to_float(vector[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
+ const VArray<float> &w = params.readonly_single_input<float>(1, "W");
+ if (compute_color) {
+ for (int64_t i : mask) {
+ const float3 c = noise::hash_float_to_float3(
+ float4(vector[i].x, vector[i].y, vector[i].z, w[i]));
+ r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
+ }
+ }
+ if (compute_value) {
+ for (int64_t i : mask) {
+ r_value[i] = noise::hash_float_to_float(
+ float4(vector[i].x, vector[i].y, vector[i].z, w[i]));
+ }
+ }
+ break;
+ }
+ }
+ }
+};
+
+static void sh_node_noise_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ builder.construct_and_set_matching_fn<WhiteNoiseFunction>((int)node.custom1);
}
-void register_node_type_sh_tex_white_noise(void)
+} // namespace blender::nodes::node_shader_tex_white_noise_cc
+
+void register_node_type_sh_tex_white_noise()
{
+ namespace file_ns = blender::nodes::node_shader_tex_white_noise_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::sh_node_tex_white_noise_declare;
- node_type_init(&ntype, node_shader_init_tex_white_noise);
- node_type_gpu(&ntype, gpu_shader_tex_white_noise);
- node_type_update(&ntype, node_shader_update_tex_white_noise);
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_tex_white_noise_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_white_noise;
+ node_type_init(&ntype, file_ns::node_shader_init_tex_white_noise);
+ node_type_gpu(&ntype, file_ns::gpu_shader_tex_white_noise);
+ node_type_update(&ntype, file_ns::node_shader_update_tex_white_noise);
+ ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc
index 05c3248af65..382a0f16ecd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uv_along_stroke.cc
@@ -17,23 +17,35 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_uvalongstroke_out[] = {
- {SOCK_VECTOR, N_("UV"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_uv_along_stroke_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("UV"));
+}
+
+static void node_shader_buts_uvalongstroke(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_tips", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+}
+
+} // namespace blender::nodes::node_shader_uv_along_stroke_cc
/* node type definition */
-void register_node_type_sh_uvalongstroke(void)
+void register_node_type_sh_uvalongstroke()
{
+ namespace file_ns = blender::nodes::node_shader_uv_along_stroke_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_UVALONGSTROKE, "UV Along Stroke", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_uvalongstroke_out);
- node_type_init(&ntype, NULL);
+ sh_node_type_base(&ntype, SH_NODE_UVALONGSTROKE, "UV Along Stroke", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_uvalongstroke;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.c b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
index 775b8ffbc06..b004be75188 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvmap.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc
@@ -17,20 +17,39 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
+
+#include "BKE_context.h"
#include "DNA_customdata_types.h"
-/* **************** OUTPUT ******************** */
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_uvmap_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>(N_("UV"));
+}
-static bNodeSocketTemplate sh_node_uvmap_out[] = {
- {SOCK_VECTOR, N_("UV"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "from_instancer", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+
+ if (!RNA_boolean_get(ptr, "from_instancer")) {
+ PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
+
+ if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
+ PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
+ uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
+ }
+ }
+}
static void node_shader_init_uvmap(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderUVMap *attr = MEM_callocN(sizeof(NodeShaderUVMap), "NodeShaderUVMap");
+ NodeShaderUVMap *attr = MEM_cnew<NodeShaderUVMap>("NodeShaderUVMap");
node->storage = attr;
}
@@ -40,7 +59,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- NodeShaderUVMap *attr = node->storage;
+ NodeShaderUVMap *attr = static_cast<NodeShaderUVMap *>(node->storage);
GPUNodeLink *mtface = GPU_attribute(mat, CD_MTFACE, attr->uv_map);
GPU_stack_link(mat, node, "node_uvmap", in, out, mtface);
@@ -50,18 +69,23 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat,
return 1;
}
+} // namespace blender::nodes::node_shader_uvmap_cc
+
/* node type definition */
-void register_node_type_sh_uvmap(void)
+void register_node_type_sh_uvmap()
{
+ namespace file_ns = blender::nodes::node_shader_uvmap_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_UVMAP, "UV Map", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_uvmap_out);
+ sh_node_type_base(&ntype, SH_NODE_UVMAP, "UV Map", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_uvmap;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, node_shader_init_uvmap);
+ node_type_init(&ntype, file_ns::node_shader_init_uvmap);
node_type_storage(
&ntype, "NodeShaderUVMap", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_uvmap);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_uvmap);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc
index 1344ce5c5d9..265f03e6e88 100644
--- a/source/blender/nodes/shader/nodes/node_shader_value.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_value.cc
@@ -21,16 +21,14 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_shader_value_cc {
static void sh_node_value_declare(NodeDeclarationBuilder &b)
{
- b.add_output<decl::Float>("Value");
-};
-
-} // namespace blender::nodes
+ b.add_output<decl::Float>(N_("Value"));
+}
static int gpu_shader_value(GPUMaterial *mat,
bNode *node,
@@ -49,14 +47,18 @@ 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)
+} // namespace blender::nodes::node_shader_value_cc
+
+void register_node_type_sh_value()
{
+ namespace file_ns = blender::nodes::node_shader_value_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, 0);
- ntype.declare = blender::nodes::sh_node_value_declare;
- node_type_gpu(&ntype, gpu_shader_value);
- ntype.build_multi_function = sh_node_value_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::sh_node_value_declare;
+ node_type_gpu(&ntype, file_ns::gpu_shader_value);
+ ntype.build_multi_function = file_ns::sh_node_value_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc
index 2b69e781e30..d34ef29c30a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.cc
@@ -17,21 +17,17 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_vector_displacement_cc {
-static bNodeSocketTemplate sh_node_vector_displacement_in[] = {
- {SOCK_RGBA, N_("Vector"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_FLOAT, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_vector_displacement_out[] = {
- {SOCK_VECTOR, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Vector")).hide_value();
+ b.add_input<decl::Float>(N_("Midlevel")).default_value(0.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_output<decl::Vector>(N_("Displacement"));
+}
static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -60,18 +56,20 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat,
}
}
+} // namespace blender::nodes::node_shader_vector_displacement_cc
+
/* node type definition */
-void register_node_type_sh_vector_displacement(void)
+void register_node_type_sh_vector_displacement()
{
+ namespace file_ns = blender::nodes::node_shader_vector_displacement_cc;
+
static bNodeType ntype;
sh_node_type_base(
- &ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(
- &ntype, sh_node_vector_displacement_in, sh_node_vector_displacement_out);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_init(&ntype, node_shader_init_vector_displacement);
- node_type_gpu(&ntype, gpu_shader_vector_displacement);
+ &ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_shader_init_vector_displacement);
+ node_type_gpu(&ntype, file_ns::gpu_shader_vector_displacement);
nodeRegisterType(&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 f49ff06cef1..591734c7dd6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
@@ -21,24 +21,74 @@
* \ingroup shdnodes
*/
-#include "node_shader_util.h"
+#include "node_shader_util.hh"
#include "NOD_math_functions.hh"
+#include "NOD_socket_search_link.hh"
-namespace blender::nodes {
+#include "RNA_enum_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_vector_math_cc {
static void sh_node_vector_math_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Vector>("Vector", "Vector_001").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Vector>("Vector", "Vector_002").min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>("Scale").default_value(1.0f).min(-10000.0f).max(10000.0f);
- b.add_output<decl::Vector>("Vector");
- b.add_output<decl::Float>("Value");
+ b.add_input<decl::Vector>(N_("Vector")).min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Vector>(N_("Vector"), "Vector_001").min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Vector>(N_("Vector"), "Vector_002").min(-10000.0f).max(10000.0f);
+ b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).min(-10000.0f).max(10000.0f);
+ b.add_output<decl::Vector>(N_("Vector"));
+ b.add_output<decl::Float>(N_("Value"));
+}
+
+static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "operation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
+
+class SocketSearchOp {
+ public:
+ std::string socket_name;
+ NodeVectorMathOperation mode = NODE_VECTOR_MATH_ADD;
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("ShaderNodeVectorMath");
+ node.custom1 = mode;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
};
-} // namespace blender::nodes
+static void sh_node_vector_math_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ if (!params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_VECTOR)) {
+ return;
+ }
+
+ const int weight = ELEM(params.other_socket().type, SOCK_VECTOR, SOCK_RGBA) ? 0 : -1;
+
+ for (const EnumPropertyItem *item = rna_enum_node_vec_math_items; item->identifier != nullptr;
+ item++) {
+ if (item->name != nullptr && item->identifier[0] != '\0') {
+ if ((params.in_out() == SOCK_OUT) && ELEM(item->value,
+ NODE_VECTOR_MATH_LENGTH,
+ NODE_VECTOR_MATH_DISTANCE,
+ NODE_VECTOR_MATH_DOT_PRODUCT)) {
+ params.add_item(IFACE_(item->name),
+ SocketSearchOp{"Value", (NodeVectorMathOperation)item->value},
+ weight);
+ }
+ else {
+ params.add_item(IFACE_(item->name),
+ SocketSearchOp{"Vector", (NodeVectorMathOperation)item->value},
+ weight);
+ }
+ }
+ }
+}
static const char *gpu_shader_get_name(int mode)
{
@@ -119,7 +169,7 @@ static int gpu_shader_vector_math(GPUMaterial *mat,
return 0;
}
-static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_vector_math(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sockB = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
bNodeSocket *sockC = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
@@ -128,7 +178,8 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector");
bNodeSocket *sockValue = nodeFindSocket(node, SOCK_OUT, "Value");
- nodeSetSocketAvailability(sockB,
+ nodeSetSocketAvailability(ntree,
+ sockB,
!ELEM(node->custom1,
NODE_VECTOR_MATH_SINE,
NODE_VECTOR_MATH_COSINE,
@@ -140,19 +191,22 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
NODE_VECTOR_MATH_ABSOLUTE,
NODE_VECTOR_MATH_FRACTION,
NODE_VECTOR_MATH_NORMALIZE));
- nodeSetSocketAvailability(sockC,
+ nodeSetSocketAvailability(ntree,
+ sockC,
ELEM(node->custom1,
NODE_VECTOR_MATH_WRAP,
NODE_VECTOR_MATH_FACEFORWARD,
NODE_VECTOR_MATH_MULTIPLY_ADD));
- nodeSetSocketAvailability(sockScale,
- ELEM(node->custom1, NODE_VECTOR_MATH_SCALE, NODE_VECTOR_MATH_REFRACT));
- nodeSetSocketAvailability(sockVector,
+ nodeSetSocketAvailability(
+ ntree, sockScale, ELEM(node->custom1, NODE_VECTOR_MATH_SCALE, NODE_VECTOR_MATH_REFRACT));
+ nodeSetSocketAvailability(ntree,
+ sockVector,
!ELEM(node->custom1,
NODE_VECTOR_MATH_LENGTH,
NODE_VECTOR_MATH_DISTANCE,
NODE_VECTOR_MATH_DOT_PRODUCT));
- nodeSetSocketAvailability(sockValue,
+ nodeSetSocketAvailability(ntree,
+ sockValue,
ELEM(node->custom1,
NODE_VECTOR_MATH_LENGTH,
NODE_VECTOR_MATH_DISTANCE,
@@ -197,8 +251,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) {
@@ -208,7 +262,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) {
@@ -218,7 +272,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) {
@@ -227,8 +281,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) {
@@ -237,8 +291,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) {
@@ -247,7 +301,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) {
@@ -256,7 +311,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) {
@@ -273,16 +329,22 @@ static void sh_node_vector_math_build_multi_function(
builder.set_matching_fn(fn);
}
-void register_node_type_sh_vect_math(void)
+} // namespace blender::nodes::node_shader_vector_math_cc
+
+void register_node_type_sh_vect_math()
{
+ namespace file_ns = blender::nodes::node_shader_vector_math_cc;
+
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);
- 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;
+ sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::sh_node_vector_math_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_vect_math;
+ ntype.labelfunc = node_vector_math_label;
+ node_type_gpu(&ntype, file_ns::gpu_shader_vector_math);
+ node_type_update(&ntype, file_ns::node_shader_update_vector_math);
+ ntype.build_multi_function = file_ns::sh_node_vector_math_build_multi_function;
+ ntype.gather_link_search_ops = file_ns::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 c9b26fa5199..d8dcd028c56 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
@@ -21,22 +21,29 @@
* \ingroup shdnodes
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-namespace blender::nodes {
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_vector_rotate_cc {
static void sh_node_vector_rotate_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").min(0.0f).max(1.0f).hide_value();
- b.add_input<decl::Vector>("Center");
- b.add_input<decl::Vector>("Axis").min(-1.0f).max(1.0f).default_value({0.0f, 0.0f, 1.0f});
- b.add_input<decl::Float>("Angle").subtype(PROP_ANGLE);
- b.add_input<decl::Vector>("Rotation").subtype(PROP_EULER);
- b.add_output<decl::Vector>("Vector");
-};
+ b.add_input<decl::Vector>(N_("Vector")).min(0.0f).max(1.0f).hide_value();
+ b.add_input<decl::Vector>(N_("Center"));
+ b.add_input<decl::Vector>(N_("Axis")).min(-1.0f).max(1.0f).default_value({0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Angle")).subtype(PROP_ANGLE);
+ b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER);
+ b.add_output<decl::Vector>(N_("Vector"));
+}
-} // namespace blender::nodes
+static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "rotation_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "invert", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+}
static const char *gpu_shader_get_name(int mode)
{
@@ -193,25 +200,32 @@ static void sh_node_vector_rotate_build_multi_function(
builder.set_matching_fn(fn);
}
-static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_shader_update_vector_rotate(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock_rotation = nodeFindSocket(node, SOCK_IN, "Rotation");
- nodeSetSocketAvailability(sock_rotation, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
+ nodeSetSocketAvailability(
+ ntree, sock_rotation, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
bNodeSocket *sock_axis = nodeFindSocket(node, SOCK_IN, "Axis");
- nodeSetSocketAvailability(sock_axis, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_AXIS));
+ nodeSetSocketAvailability(ntree, sock_axis, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_AXIS));
bNodeSocket *sock_angle = nodeFindSocket(node, SOCK_IN, "Angle");
- nodeSetSocketAvailability(sock_angle, !ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
+ nodeSetSocketAvailability(
+ ntree, sock_angle, !ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
}
-void register_node_type_sh_vector_rotate(void)
+} // namespace blender::nodes::node_shader_vector_rotate_cc
+
+void register_node_type_sh_vector_rotate()
{
+ namespace file_ns = blender::nodes::node_shader_vector_rotate_cc;
+
static bNodeType ntype;
- sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR, 0);
- ntype.declare = blender::nodes::sh_node_vector_rotate_declare;
- node_type_gpu(&ntype, gpu_shader_vector_rotate);
- node_type_update(&ntype, node_shader_update_vector_rotate);
- ntype.build_multi_function = sh_node_vector_rotate_build_multi_function;
+ sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::sh_node_vector_rotate_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_vector_rotate;
+ node_type_gpu(&ntype, file_ns::gpu_shader_vector_rotate);
+ node_type_update(&ntype, file_ns::node_shader_update_vector_rotate);
+ ntype.build_multi_function = file_ns::sh_node_vector_rotate_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
index 41e61da60d7..a8a6902e30c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_transform.cc
@@ -21,23 +21,37 @@
* \ingroup shdnodes
*/
-#include "BLI_string.h"
+#include "node_shader_util.hh"
-#include "../node_shader_util.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
-/* **************** Vector Transform ******************** */
-static bNodeSocketTemplate sh_node_vect_transform_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, {-1, ""}};
+namespace blender::nodes::node_shader_vector_transform_cc {
-static bNodeSocketTemplate sh_node_vect_transform_out[] = {
- {SOCK_VECTOR, N_("Vector")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector"))
+ .default_value({0.5f, 0.5f, 0.5f})
+ .min(-10000.0f)
+ .max(10000.0f);
+ b.add_output<decl::Vector>(N_("Vector"));
+}
+
+static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout,
+ ptr,
+ "vector_type",
+ UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND,
+ nullptr,
+ ICON_NONE);
+ uiItemR(layout, ptr, "convert_from", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+ uiItemR(layout, ptr, "convert_to", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
+}
static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderVectTransform *vect = MEM_callocN(sizeof(NodeShaderVectTransform),
- "NodeShaderVectTransform");
+ NodeShaderVectTransform *vect = MEM_cnew<NodeShaderVectTransform>("NodeShaderVectTransform");
/* Convert World into Object Space per default */
vect->convert_to = 1;
@@ -45,52 +59,42 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod
node->storage = vect;
}
-static void node_shader_exec_vect_transform(void *UNUSED(data),
- int UNUSED(thread),
- bNode *UNUSED(node),
- bNodeExecData *UNUSED(execdata),
- bNodeStack **UNUSED(in),
- bNodeStack **UNUSED(out))
-{
-}
-
-static const char *get_gpufn_name_from_to(short from, short to)
+static GPUNodeLink *get_gpulink_matrix_from_to(short from, short to)
{
switch (from) {
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return NULL;
+ return nullptr;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return "object_to_world";
+ return GPU_builtin(GPU_OBJECT_MATRIX);
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return "object_to_view";
+ return GPU_builtin(GPU_LOC_TO_VIEW_MATRIX);
}
break;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return NULL;
+ return nullptr;
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return "world_to_view";
+ return GPU_builtin(GPU_VIEW_MATRIX);
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return "world_to_object";
+ return GPU_builtin(GPU_INVERSE_OBJECT_MATRIX);
}
break;
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
switch (to) {
case SHD_VECT_TRANSFORM_SPACE_CAMERA:
- return NULL;
+ return nullptr;
case SHD_VECT_TRANSFORM_SPACE_WORLD:
- return "view_to_world";
+ return GPU_builtin(GPU_INVERSE_VIEW_MATRIX);
case SHD_VECT_TRANSFORM_SPACE_OBJECT:
- return "view_to_object";
+ return GPU_builtin(GPU_INVERSE_LOC_TO_VIEW_MATRIX);
}
break;
}
- return NULL;
+ return nullptr;
}
-
static int gpu_shader_vect_transform(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
@@ -98,6 +102,11 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
GPUNodeStack *out)
{
struct GPUNodeLink *inputlink;
+ struct GPUNodeLink *fromto;
+
+ const char *vtransform = "direction_transform_m4v3";
+ const char *ptransform = "point_transform_m4v3";
+ const char *func_name = nullptr;
NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage;
@@ -108,10 +117,9 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
inputlink = GPU_constant(in[0].vec);
}
- const char *xform = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? "point_transform_" :
- "direction_transform_";
- const char *fromto = get_gpufn_name_from_to(nodeprop->convert_from, nodeprop->convert_to);
+ fromto = get_gpulink_matrix_from_to(nodeprop->convert_from, nodeprop->convert_to);
+ func_name = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? ptransform : vtransform;
if (fromto) {
/* For cycles we have inverted Z */
/* TODO: pass here the correct matrices */
@@ -119,11 +127,7 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
nodeprop->convert_to != SHD_VECT_TRANSFORM_SPACE_CAMERA) {
GPU_link(mat, "invert_z", inputlink, &inputlink);
}
-
- char func_name[48];
- SNPRINTF(func_name, "%s%s", xform, fromto);
- GPU_link(mat, func_name, inputlink, &out[0].link);
-
+ GPU_link(mat, func_name, inputlink, fromto, &out[0].link);
if (nodeprop->convert_to == SHD_VECT_TRANSFORM_SPACE_CAMERA &&
nodeprop->convert_from != SHD_VECT_TRANSFORM_SPACE_CAMERA) {
GPU_link(mat, "invert_z", out[0].link, &out[0].link);
@@ -140,17 +144,21 @@ static int gpu_shader_vect_transform(GPUMaterial *mat,
return true;
}
-void register_node_type_sh_vect_transform(void)
+} // namespace blender::nodes::node_shader_vector_transform_cc
+
+void register_node_type_sh_vect_transform()
{
+ namespace file_ns = blender::nodes::node_shader_vector_transform_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_OP_VECTOR, 0);
- node_type_init(&ntype, node_shader_init_vect_transform);
- node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out);
+ sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_OP_VECTOR);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_vect_transform;
+ node_type_init(&ntype, file_ns::node_shader_init_vect_transform);
node_type_storage(
&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage);
- node_type_exec(&ntype, NULL, NULL, node_shader_exec_vect_transform);
- node_type_gpu(&ntype, gpu_shader_vect_transform);
+ node_type_gpu(&ntype, file_ns::gpu_shader_vect_transform);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
index 40576b68dd5..6501527ef5d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc
@@ -17,18 +17,44 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-static bNodeSocketTemplate sh_node_vertex_color_out[] = {
- {SOCK_RGBA, N_("Color")},
- {SOCK_FLOAT, N_("Alpha")},
- {-1, ""},
-};
+#include "BKE_context.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes::node_shader_vertex_color_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Alpha"));
+}
+
+static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
+ if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
+ PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
+
+ if (U.experimental.use_sculpt_vertex_colors &&
+ RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
+ uiItemPointerR(
+ layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
+ }
+ else {
+ uiItemPointerR(layout, ptr, "layer_name", &dataptr, "vertex_colors", "", ICON_GROUP_VCOL);
+ }
+ }
+ else {
+ uiItemL(layout, TIP_("No mesh in active object"), ICON_ERROR);
+ }
+}
static void node_shader_init_vertex_color(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeShaderVertexColor *vertexColor = MEM_callocN(sizeof(NodeShaderVertexColor),
- "NodeShaderVertexColor");
+ NodeShaderVertexColor *vertexColor = MEM_cnew<NodeShaderVertexColor>("NodeShaderVertexColor");
node->storage = vertexColor;
}
@@ -47,16 +73,21 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}
-void register_node_type_sh_vertex_color(void)
+} // namespace blender::nodes::node_shader_vertex_color_cc
+
+void register_node_type_sh_vertex_color()
{
+ namespace file_ns = blender::nodes::node_shader_vertex_color_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VERTEX_COLOR, "Vertex Color", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_vertex_color_out);
- node_type_init(&ntype, node_shader_init_vertex_color);
+ sh_node_type_base(&ntype, SH_NODE_VERTEX_COLOR, "Vertex Color", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_vertex_color;
+ node_type_init(&ntype, file_ns::node_shader_init_vertex_color);
node_type_storage(
&ntype, "NodeShaderVertexColor", node_free_standard_storage, node_copy_standard_storage);
- node_type_gpu(&ntype, node_shader_gpu_vertex_color);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_vertex_color);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_absorption.c b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc
index 3c9fab2401b..a31bfdb6543 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_absorption.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.cc
@@ -17,21 +17,16 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_volume_absorption_cc {
-static bNodeSocketTemplate sh_node_volume_absorption_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_volume_absorption_out[] = {
- {SOCK_SHADER, N_("Volume")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_output<decl::Shader>(N_("Volume"));
+}
static int node_shader_gpu_volume_absorption(GPUMaterial *mat,
bNode *node,
@@ -42,16 +37,18 @@ static int node_shader_gpu_volume_absorption(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_volume_absorption", in, out);
}
+} // namespace blender::nodes::node_shader_volume_absorption_cc
+
/* node type definition */
-void register_node_type_sh_volume_absorption(void)
+void register_node_type_sh_volume_absorption()
{
+ namespace file_ns = blender::nodes::node_shader_volume_absorption_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VOLUME_ABSORPTION, "Volume Absorption", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_volume_absorption_in, sh_node_volume_absorption_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_volume_absorption);
+ sh_node_type_base(&ntype, SH_NODE_VOLUME_ABSORPTION, "Volume Absorption", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_absorption);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_info.c b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc
index 6cafc991e13..6a973cdbad7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc
@@ -17,15 +17,17 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-static bNodeSocketTemplate sh_node_volume_info_out[] = {
- {SOCK_RGBA, N_("Color")},
- {SOCK_FLOAT, N_("Density")},
- {SOCK_FLOAT, N_("Flame")},
- {SOCK_FLOAT, N_("Temperature")},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_volume_info_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Color>(N_("Color"));
+ b.add_output<decl::Float>(N_("Density"));
+ b.add_output<decl::Float>(N_("Flame"));
+ b.add_output<decl::Float>(N_("Temperature"));
+}
static int node_shader_gpu_volume_info(GPUMaterial *mat,
bNode *UNUSED(node),
@@ -49,13 +51,17 @@ static int node_shader_gpu_volume_info(GPUMaterial *mat,
return true;
}
-void register_node_type_sh_volume_info(void)
+} // namespace blender::nodes::node_shader_volume_info_cc
+
+void register_node_type_sh_volume_info()
{
+ namespace file_ns = blender::nodes::node_shader_volume_info_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VOLUME_INFO, "Volume Info", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, NULL, sh_node_volume_info_out);
- node_type_gpu(&ntype, node_shader_gpu_volume_info);
+ sh_node_type_base(&ntype, SH_NODE_VOLUME_INFO, "Volume Info", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_info);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc
index 41c3abd7ca4..54e92eafcf6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc
@@ -17,31 +17,34 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_volume_principled_in[] = {
- {SOCK_RGBA, N_("Color"), 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f},
- {SOCK_STRING, N_("Color Attribute"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_STRING, N_("Density Attribute"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Absorption Color"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Emission Strength"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1000.0f},
- {SOCK_RGBA, N_("Emission Color"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Blackbody Intensity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_RGBA, N_("Blackbody Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Temperature"), 1000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6500.0f},
- {SOCK_STRING, N_("Temperature Attribute"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_volume_principled_out[] = {
- {SOCK_SHADER, N_("Volume")},
- {-1, ""},
-};
+#include "node_shader_util.hh"
+
+namespace blender::nodes::node_shader_volume_principled_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
+ b.add_input<decl::String>(N_("Color Attribute"));
+ b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::String>(N_("Density Attribute"));
+ b.add_input<decl::Float>(N_("Anisotropy"))
+ .default_value(0.0f)
+ .min(-1.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Absorption Color")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Emission Strength")).default_value(0.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Color>(N_("Emission Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Blackbody Intensity"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Color>(N_("Blackbody Tint")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_input<decl::Float>(N_("Temperature")).default_value(1000.0f).min(0.0f).max(6500.0f);
+ b.add_input<decl::String>(N_("Temperature Attribute"));
+ b.add_output<decl::Shader>(N_("Volume"));
+}
static void node_shader_init_volume_principled(bNodeTree *UNUSED(ntree), bNode *node)
{
@@ -65,14 +68,14 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat,
bool use_blackbody = (in[8].link || in[8].vec[0] != 0.0f);
/* Get volume attributes. */
- GPUNodeLink *density = NULL, *color = NULL, *temperature = NULL;
+ GPUNodeLink *density = nullptr, *color = nullptr, *temperature = nullptr;
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (sock->typeinfo->type != SOCK_STRING) {
continue;
}
- bNodeSocketValueString *value = sock->default_value;
+ bNodeSocketValueString *value = (bNodeSocketValueString *)sock->default_value;
const char *attribute_name = value->value;
if (attribute_name[0] == '\0') {
continue;
@@ -107,11 +110,11 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat,
const int size = CM_TABLE + 1;
float *data, layer;
if (use_blackbody) {
- data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
+ data = (float *)MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
}
else {
- data = MEM_callocN(sizeof(float) * size * 4, "blackbody black");
+ data = (float *)MEM_callocN(sizeof(float) * size * 4, "blackbody black");
}
GPUNodeLink *spectrummap = GPU_color_band(mat, size, data, &layer);
@@ -127,17 +130,20 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat,
GPU_constant(&layer));
}
+} // namespace blender::nodes::node_shader_volume_principled_cc
+
/* node type definition */
-void register_node_type_sh_volume_principled(void)
+void register_node_type_sh_volume_principled()
{
+ namespace file_ns = blender::nodes::node_shader_volume_principled_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_volume_principled_in, sh_node_volume_principled_out);
+ sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, node_shader_init_volume_principled);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_volume_principled);
+ node_type_init(&ntype, file_ns::node_shader_init_volume_principled);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_principled);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_scatter.c b/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc
index 282a49dc944..abd10cfcbcf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_scatter.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_scatter.cc
@@ -17,22 +17,21 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** OUTPUT ******************** */
+namespace blender::nodes::node_shader_volume_scatter_cc {
-static bNodeSocketTemplate sh_node_volume_scatter_in[] = {
- {SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_FLOAT, N_("Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- {SOCK_FLOAT, N_("Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Weight"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_UNAVAIL},
- {-1, ""},
-};
-
-static bNodeSocketTemplate sh_node_volume_scatter_out[] = {
- {SOCK_SHADER, N_("Volume")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
+ b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f).max(1000.0f);
+ b.add_input<decl::Float>(N_("Anisotropy"))
+ .default_value(0.0f)
+ .min(-1.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_output<decl::Shader>(N_("Volume"));
+}
static int node_shader_gpu_volume_scatter(GPUMaterial *mat,
bNode *node,
@@ -43,16 +42,18 @@ static int node_shader_gpu_volume_scatter(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_volume_scatter", in, out);
}
+} // namespace blender::nodes::node_shader_volume_scatter_cc
+
/* node type definition */
-void register_node_type_sh_volume_scatter(void)
+void register_node_type_sh_volume_scatter()
{
+ namespace file_ns = blender::nodes::node_shader_volume_scatter_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VOLUME_SCATTER, "Volume Scatter", NODE_CLASS_SHADER, 0);
- node_type_socket_templates(&ntype, sh_node_volume_scatter_in, sh_node_volume_scatter_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_volume_scatter);
+ sh_node_type_base(&ntype, SH_NODE_VOLUME_SCATTER, "Volume Scatter", NODE_CLASS_SHADER);
+ ntype.declare = file_ns::node_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_volume_scatter);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_wavelength.c b/source/blender/nodes/shader/nodes/node_shader_wavelength.cc
index f978537ee85..a67c7830edd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wavelength.c
+++ b/source/blender/nodes/shader/nodes/node_shader_wavelength.cc
@@ -17,18 +17,15 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Wavelength ******************** */
-static bNodeSocketTemplate sh_node_wavelength_in[] = {
- {SOCK_FLOAT, N_("Wavelength"), 500.0f, 0.0f, 0.0f, 0.0f, 380.0f, 780.0f},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_wavelength_cc {
-static bNodeSocketTemplate sh_node_wavelength_out[] = {
- {SOCK_RGBA, N_("Color")},
- {-1, ""},
-};
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Wavelength")).default_value(500.0f).min(380.0f).max(780.0f);
+ b.add_output<decl::Color>(N_("Color"));
+}
static int node_shader_gpu_wavelength(GPUMaterial *mat,
bNode *node,
@@ -37,7 +34,7 @@ static int node_shader_gpu_wavelength(GPUMaterial *mat,
GPUNodeStack *out)
{
const int size = CM_TABLE + 1;
- float *data = MEM_mallocN(sizeof(float) * size * 4, "cie_xyz texture");
+ float *data = static_cast<float *>(MEM_mallocN(sizeof(float) * size * 4, "cie_xyz texture"));
wavelength_to_xyz_table(data, size);
@@ -57,17 +54,19 @@ static int node_shader_gpu_wavelength(GPUMaterial *mat,
GPU_uniform(xyz_to_rgb.b));
}
+} // namespace blender::nodes::node_shader_wavelength_cc
+
/* node type definition */
-void register_node_type_sh_wavelength(void)
+void register_node_type_sh_wavelength()
{
+ namespace file_ns = blender::nodes::node_shader_wavelength_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_WAVELENGTH, "Wavelength", NODE_CLASS_CONVERTER, 0);
+ sh_node_type_base(&ntype, SH_NODE_WAVELENGTH, "Wavelength", NODE_CLASS_CONVERTER);
+ ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_socket_templates(&ntype, sh_node_wavelength_in, sh_node_wavelength_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_wavelength);
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_wavelength);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_wireframe.c b/source/blender/nodes/shader/nodes/node_shader_wireframe.cc
index e8c2b6971bc..c4771cc13e9 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wireframe.c
+++ b/source/blender/nodes/shader/nodes/node_shader_wireframe.cc
@@ -17,18 +17,23 @@
* All rights reserved.
*/
-#include "../node_shader_util.h"
+#include "node_shader_util.hh"
-/* **************** Wireframe ******************** */
-static bNodeSocketTemplate sh_node_wireframe_in[] = {
- {SOCK_FLOAT, N_("Size"), 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, 100.0f},
- {-1, ""},
-};
+#include "UI_interface.h"
+#include "UI_resources.h"
-static bNodeSocketTemplate sh_node_wireframe_out[] = {
- {SOCK_FLOAT, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {-1, ""},
-};
+namespace blender::nodes::node_shader_wireframe_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Size")).default_value(0.01f).min(0.0f).max(100.0f);
+ b.add_output<decl::Float>(N_("Fac"));
+}
+
+static void node_shader_buts_wireframe(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_pixel_size", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
+}
static int node_shader_gpu_wireframe(GPUMaterial *mat,
bNode *node,
@@ -46,16 +51,19 @@ static int node_shader_gpu_wireframe(GPUMaterial *mat,
}
}
+} // namespace blender::nodes::node_shader_wireframe_cc
+
/* node type definition */
-void register_node_type_sh_wireframe(void)
+void register_node_type_sh_wireframe()
{
+ namespace file_ns = blender::nodes::node_shader_wireframe_cc;
+
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_WIREFRAME, "Wireframe", NODE_CLASS_INPUT, 0);
- node_type_socket_templates(&ntype, sh_node_wireframe_in, sh_node_wireframe_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_wireframe);
+ sh_node_type_base(&ntype, SH_NODE_WIREFRAME, "Wireframe", NODE_CLASS_INPUT);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_shader_buts_wireframe;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_wireframe);
nodeRegisterType(&ntype);
}