Blender  V3.3
node_shader_volume_principled.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
4 #include "node_shader_util.hh"
5 
6 #include "IMB_colormanagement.h"
7 
9 
11 {
12  b.add_input<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
13  b.add_input<decl::String>(N_("Color Attribute"));
14  b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f).max(1000.0f);
15  b.add_input<decl::String>(N_("Density Attribute"));
16  b.add_input<decl::Float>(N_("Anisotropy"))
17  .default_value(0.0f)
18  .min(-1.0f)
19  .max(1.0f)
20  .subtype(PROP_FACTOR);
21  b.add_input<decl::Color>(N_("Absorption Color")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
22  b.add_input<decl::Float>(N_("Emission Strength")).default_value(0.0f).min(0.0f).max(1000.0f);
23  b.add_input<decl::Color>(N_("Emission Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
24  b.add_input<decl::Float>(N_("Blackbody Intensity"))
25  .default_value(0.0f)
26  .min(0.0f)
27  .max(1.0f)
28  .subtype(PROP_FACTOR);
29  b.add_input<decl::Color>(N_("Blackbody Tint")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
30  b.add_input<decl::Float>(N_("Temperature")).default_value(1000.0f).min(0.0f).max(6500.0f);
31  b.add_input<decl::String>(N_("Temperature Attribute"));
32  b.add_input<decl::Float>(N_("Weight")).unavailable();
33  b.add_output<decl::Shader>(N_("Volume"));
34 }
35 
37 {
38  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
39  if (STREQ(sock->name, "Density Attribute")) {
40  strcpy(((bNodeSocketValueString *)sock->default_value)->value, "density");
41  }
42  else if (STREQ(sock->name, "Temperature Attribute")) {
43  strcpy(((bNodeSocketValueString *)sock->default_value)->value, "temperature");
44  }
45  }
46 }
47 
49  const char *attribute_name,
50  GPUNodeLink **attribute_link)
51 {
52  if (STREQ(attribute_name, "color")) {
53  GPU_link(mat, "node_attribute_color", *attribute_link, attribute_link);
54  }
55  else if (STREQ(attribute_name, "temperature")) {
56  GPU_link(mat, "node_attribute_temperature", *attribute_link, attribute_link);
57  }
58 }
59 
61  bNode *node,
62  bNodeExecData *UNUSED(execdata),
63  GPUNodeStack *in,
65 {
66  /* Test if blackbody intensity is enabled. */
67  bool use_blackbody = (in[8].link || in[8].vec[0] != 0.0f);
68 
69  /* Get volume attributes. */
70  GPUNodeLink *density = nullptr, *color = nullptr, *temperature = nullptr;
71 
72  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
73  if (sock->typeinfo->type != SOCK_STRING) {
74  continue;
75  }
76 
77  bNodeSocketValueString *value = (bNodeSocketValueString *)sock->default_value;
78  const char *attribute_name = value->value;
79  if (attribute_name[0] == '\0') {
80  continue;
81  }
82 
83  if (STREQ(sock->name, "Density Attribute")) {
85  attribute_post_process(mat, attribute_name, &density);
86  }
87  else if (STREQ(sock->name, "Color Attribute")) {
89  attribute_post_process(mat, attribute_name, &color);
90  }
91  else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) {
92  temperature = GPU_attribute(mat, CD_AUTO_FROM_NAME, attribute_name);
93  attribute_post_process(mat, attribute_name, &temperature);
94  }
95  }
96 
97  /* Default values if attributes not found. */
98  static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
99  if (!density) {
100  density = GPU_constant(white);
101  }
102  if (!color) {
103  color = GPU_constant(white);
104  }
105  if (!temperature) {
106  temperature = GPU_constant(white);
107  }
108 
109  /* Create blackbody spectrum. */
110  const int size = CM_TABLE + 1;
111  float *data, layer;
112  if (use_blackbody) {
113  data = (float *)MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
115  }
116  else {
117  data = (float *)MEM_callocN(sizeof(float) * size * 4, "blackbody black");
118  }
119  GPUNodeLink *spectrummap = GPU_color_band(mat, size, data, &layer);
120 
121  return GPU_stack_link(mat,
122  node,
123  "node_volume_principled",
124  in,
125  out,
126  density,
127  color,
128  temperature,
129  spectrummap,
130  GPU_constant(&layer));
131 }
132 
133 } // namespace blender::nodes::node_shader_volume_principled_cc
134 
135 /* node type definition */
137 {
139 
140  static bNodeType ntype;
141 
142  sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER);
147 
148  nodeRegisterType(&ntype);
149 }
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
Definition: node.cc:4408
#define SH_NODE_VOLUME_PRINCIPLED
Definition: BKE_node.h:1170
#define NODE_CLASS_SHADER
Definition: BKE_node.h:358
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
@ NODE_SIZE_LARGE
Definition: BKE_node.h:367
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define UNUSED(x)
#define STREQ(a, b)
#define CM_TABLE
@ CD_AUTO_FROM_NAME
@ SOCK_STRING
@ GPU_DEFAULT_1
Definition: GPU_material.h:122
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
GPUNodeLink * GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
GPUNodeLink * GPU_attribute_with_default(GPUMaterial *mat, eCustomDataType type, const char *name, eGPUDefaultValue default_value)
GPUNodeLink * GPU_constant(const float *num)
bool GPU_link(GPUMaterial *mat, const char *name,...)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ PROP_FACTOR
Definition: RNA_types.h:144
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
OperationNode * node
bNodeTree * ntree
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void attribute_post_process(GPUMaterial *mat, const char *attribute_name, GPUNodeLink **attribute_link)
static void node_shader_init_volume_principled(bNodeTree *UNUSED(ntree), bNode *node)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
void register_node_type_sh_volume_principled()
struct GPUNodeLink * link
Definition: GPU_material.h:106
float vec[4]
Definition: GPU_material.h:105
Defines a node type.
Definition: BKE_node.h:226
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)