Blender V4.3
node_shader_volume_principled.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "node_shader_util.hh"
6
8
10
12{
13 b.add_input<decl::Color>("Color").default_value({0.5f, 0.5f, 0.5f, 1.0f});
14#define SOCK_COLOR_ID 0
15 b.add_input<decl::String>("Color Attribute");
16#define SOCK_COLOR_ATTR_ID 1
17 b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f).max(1000.0f);
18#define SOCK_DENSITY_ID 2
19 b.add_input<decl::String>("Density Attribute").default_value("density");
20#define SOCK_DENSITY_ATTR_ID 3
21 b.add_input<decl::Float>("Anisotropy")
22 .default_value(0.0f)
23 .min(-1.0f)
24 .max(1.0f)
26#define SOCK_ANISOTROPY_ID 4
27 b.add_input<decl::Color>("Absorption Color").default_value({0.0f, 0.0f, 0.0f, 1.0f});
28#define SOCK_ABSORPTION_COLOR_ID 5
29 b.add_input<decl::Float>("Emission Strength").default_value(0.0f).min(0.0f).max(1000.0f);
30#define SOCK_EMISSION_ID 6
31 b.add_input<decl::Color>("Emission Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
32#define SOCK_EMISSION_COLOR_ID 7
33 b.add_input<decl::Float>("Blackbody Intensity")
34 .default_value(0.0f)
35 .min(0.0f)
36 .max(1.0f)
38#define SOCK_BLACKBODY_INTENSITY_ID 8
39 b.add_input<decl::Color>("Blackbody Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
40#define SOCK_BLACKBODY_TINT_ID 8
41 b.add_input<decl::Float>("Temperature")
42 .default_value(1000.0f)
43 .min(0.0f)
44 .max(6500.0f)
46 b.add_input<decl::String>("Temperature Attribute").default_value("temperature");
47 b.add_input<decl::Float>("Weight").available(false);
48 b.add_output<decl::Shader>("Volume").translation_context(BLT_I18NCONTEXT_ID_ID);
49}
50
52 const char *attribute_name,
53 GPUNodeLink **attribute_link)
54{
55 if (STREQ(attribute_name, "color")) {
56 GPU_link(mat, "node_attribute_color", *attribute_link, attribute_link);
57 }
58 else if (STREQ(attribute_name, "temperature")) {
59 GPU_link(mat, "node_attribute_temperature", *attribute_link, attribute_link);
60 }
61}
62
64 bNode *node,
65 bNodeExecData * /*execdata*/,
66 GPUNodeStack *in,
67 GPUNodeStack *out)
68{
69 /* Test if blackbody intensity is enabled. */
70 bool use_blackbody = node_socket_not_zero(in[SOCK_BLACKBODY_INTENSITY_ID]);
71
73 /* Consider there is absorption phenomenon when there is scattering since
74 * `extinction = scattering + absorption`. */
76 }
79 {
81 }
82
83 /* Get volume attributes. */
84 GPUNodeLink *density = nullptr, *color = nullptr, *temperature = nullptr;
85
86 LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
87 if (sock->typeinfo->type != SOCK_STRING) {
88 continue;
89 }
90
91 bNodeSocketValueString *value = (bNodeSocketValueString *)sock->default_value;
92 const char *attribute_name = value->value;
93 if (attribute_name[0] == '\0') {
94 continue;
95 }
96
97 if (STREQ(sock->name, "Density Attribute")) {
98 density = GPU_attribute_with_default(mat, CD_AUTO_FROM_NAME, attribute_name, GPU_DEFAULT_1);
99 attribute_post_process(mat, attribute_name, &density);
100 }
101 else if (STREQ(sock->name, "Color Attribute")) {
102 color = GPU_attribute_with_default(mat, CD_AUTO_FROM_NAME, attribute_name, GPU_DEFAULT_1);
103 attribute_post_process(mat, attribute_name, &color);
104 }
105 else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) {
106 temperature = GPU_attribute(mat, CD_AUTO_FROM_NAME, attribute_name);
107 attribute_post_process(mat, attribute_name, &temperature);
108 }
109 }
110
111 /* Default values if attributes not found. */
112 static const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
113 if (!density) {
114 density = GPU_constant(white);
115 }
116 if (!color) {
117 color = GPU_constant(white);
118 }
119 if (!temperature) {
120 temperature = GPU_constant(white);
121 }
122
123 /* Create blackbody spectrum. */
124 const int size = CM_TABLE + 1;
125 float *data, layer;
126 if (use_blackbody) {
127 data = (float *)MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
128 IMB_colormanagement_blackbody_temperature_to_rgb_table(data, size, 800.0f, 12000.0f);
129 }
130 else {
131 data = (float *)MEM_callocN(sizeof(float) * size * 4, "blackbody black");
132 }
133 GPUNodeLink *spectrummap = GPU_color_band(mat, size, data, &layer);
134
135 return GPU_stack_link(mat,
136 node,
137 "node_volume_principled",
138 in,
139 out,
140 density,
141 color,
142 temperature,
143 spectrummap,
144 GPU_constant(&layer));
145}
146
147#undef SOCK_COLOR_ID
148#undef SOCK_COLOR_ATTR_ID
149#undef SOCK_DENSITY_ID
150#undef SOCK_DENSITY_ATTR_ID
151#undef SOCK_ANISOTROPY_ID
152#undef SOCK_ABSORPTION_COLOR_ID
153#undef SOCK_EMISSION_ID
154#undef SOCK_EMISSION_COLOR_ID
155#undef SOCK_BLACKBODY_INTENSITY_ID
156#undef SOCK_BLACKBODY_TINT_ID
157
158} // namespace blender::nodes::node_shader_volume_principled_cc
159
160/* node type definition */
162{
164
165 static blender::bke::bNodeType ntype;
166
167 sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER);
168 ntype.declare = file_ns::node_declare;
170 ntype.gpu_fn = file_ns::node_shader_gpu_volume_principled;
171
173}
#define NODE_CLASS_SHADER
Definition BKE_node.hh:417
#define LISTBASE_FOREACH(type, var, list)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_ID
#define CM_TABLE
@ CD_AUTO_FROM_NAME
@ SOCK_STRING
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
@ GPU_DEFAULT_1
GPUNodeLink * GPU_constant(const float *num)
GPUNodeLink * GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *r_row)
@ GPU_MATFLAG_VOLUME_SCATTER
@ GPU_MATFLAG_VOLUME_ABSORPTION
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
GPUNodeLink * GPU_attribute_with_default(GPUMaterial *mat, eCustomDataType type, const char *name, eGPUDefaultValue default_value)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_link(GPUMaterial *mat, const char *name,...)
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:193
@ PROP_FACTOR
Definition RNA_types.hh:154
local_group_size(16, 16) .push_constant(Type b
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void node_type_size_preset(bNodeType *ntype, eNodeSizePreset size)
Definition node.cc:4614
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void attribute_post_process(GPUMaterial *mat, const char *attribute_name, GPUNodeLink **attribute_link)
void sh_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
bool node_socket_not_white(const GPUNodeStack &socket)
bool node_socket_not_black(const GPUNodeStack &socket)
bool node_socket_not_zero(const GPUNodeStack &socket)
#define SOCK_DENSITY_ID
#define SOCK_COLOR_ID
void register_node_type_sh_volume_principled()
#define SOCK_ABSORPTION_COLOR_ID
#define SOCK_BLACKBODY_INTENSITY_ID
Defines a node type.
Definition BKE_node.hh:218
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:318
NodeDeclareFunction declare
Definition BKE_node.hh:347