Blender  V3.3
node_shader_tex_image.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 
7 
9 {
10  b.is_function_node();
11  b.add_input<decl::Vector>(N_("Vector")).implicit_field();
12  b.add_output<decl::Color>(N_("Color")).no_muted_links();
13  b.add_output<decl::Float>(N_("Alpha")).no_muted_links();
14 }
15 
17 {
18  NodeTexImage *tex = MEM_cnew<NodeTexImage>(__func__);
20  BKE_texture_colormapping_default(&tex->base.color_mapping);
22 
23  node->storage = tex;
24 }
25 
27  bNode *node,
28  bNodeExecData *UNUSED(execdata),
29  GPUNodeStack *in,
31 {
32  Image *ima = (Image *)node->id;
33  NodeTexImage *tex = (NodeTexImage *)node->storage;
34 
35  /* We get the image user from the original node, since GPU image keeps
36  * a pointer to it and the dependency refreshes the original. */
37  bNode *node_original = node->original ? node->original : node;
38  NodeTexImage *tex_original = (NodeTexImage *)node_original->storage;
39  ImageUser *iuser = &tex_original->iuser;
40 
41  if (!ima) {
42  return GPU_stack_link(mat, node, "node_tex_image_empty", in, out);
43  }
44 
45  GPUNodeLink **texco = &in[0].link;
46  if (!*texco) {
47  *texco = GPU_attribute(mat, CD_AUTO_FROM_NAME, "");
49  }
50 
52 
53  eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT;
54 
55  switch (tex->extension) {
57  sampler_state |= GPU_SAMPLER_REPEAT;
58  break;
60  sampler_state |= GPU_SAMPLER_CLAMP_BORDER;
61  break;
62  default:
63  break;
64  }
65 
66  if (tex->interpolation != SHD_INTERP_CLOSEST) {
67  sampler_state |= GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
68  /* TODO(fclem): For now assume mipmap is always enabled. */
69  sampler_state |= GPU_SAMPLER_MIPMAP;
70  }
71  const bool use_cubic = ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART);
72 
73  if (ima->source == IMA_SRC_TILED) {
74  const char *gpu_node_name = use_cubic ? "node_tex_tile_cubic" : "node_tex_tile_linear";
75  GPUNodeLink *gpu_image = GPU_image_tiled(mat, ima, iuser, sampler_state);
76  GPUNodeLink *gpu_image_tile_mapping = GPU_image_tiled_mapping(mat, ima, iuser);
77  /* UDIM tiles needs a `sampler2DArray` and `sampler1DArray` for tile mapping. */
78  GPU_stack_link(mat, node, gpu_node_name, in, out, gpu_image, gpu_image_tile_mapping);
79  }
80  else {
81  const char *gpu_node_name = use_cubic ? "node_tex_image_cubic" : "node_tex_image_linear";
82 
83  switch (tex->projection) {
84  case SHD_PROJ_FLAT: {
85  GPUNodeLink *gpu_image = GPU_image(mat, ima, iuser, sampler_state);
86  GPU_stack_link(mat, node, gpu_node_name, in, out, gpu_image);
87  break;
88  }
89  case SHD_PROJ_BOX: {
90  gpu_node_name = use_cubic ? "tex_box_sample_cubic" : "tex_box_sample_linear";
91  GPUNodeLink *vnor, *wnor, *col1, *col2, *col3;
92  GPUNodeLink *blend = GPU_uniform(&tex->projection_blend);
93  GPUNodeLink *gpu_image = GPU_image(mat, ima, iuser, sampler_state);
94  GPU_link(mat, "world_normals_get", &vnor);
95  GPU_link(mat, "normal_transform_world_to_object", vnor, &wnor);
96  GPU_link(mat, gpu_node_name, in[0].link, wnor, gpu_image, &col1, &col2, &col3);
97  GPU_link(mat, "tex_box_blend", wnor, col1, col2, col3, blend, &out[0].link, &out[1].link);
98  break;
99  }
100  case SHD_PROJ_SPHERE: {
101  /* This projection is known to have a derivative discontinuity.
102  * Hide it by turning off mipmapping. */
103  sampler_state &= ~GPU_SAMPLER_MIPMAP;
104  GPUNodeLink *gpu_image = GPU_image(mat, ima, iuser, sampler_state);
105  GPU_link(mat, "point_texco_remap_square", *texco, texco);
106  GPU_link(mat, "point_map_to_sphere", *texco, texco);
107  GPU_stack_link(mat, node, gpu_node_name, in, out, gpu_image);
108  break;
109  }
110  case SHD_PROJ_TUBE: {
111  /* This projection is known to have a derivative discontinuity.
112  * Hide it by turning off mipmapping. */
113  sampler_state &= ~GPU_SAMPLER_MIPMAP;
114  GPUNodeLink *gpu_image = GPU_image(mat, ima, iuser, sampler_state);
115  GPU_link(mat, "point_texco_remap_square", *texco, texco);
116  GPU_link(mat, "point_map_to_tube", *texco, texco);
117  GPU_stack_link(mat, node, gpu_node_name, in, out, gpu_image);
118  break;
119  }
120  }
121  }
122 
123  if (out[0].hasoutput) {
126  /* Don't let alpha affect color output in these cases. */
127  GPU_link(mat, "color_alpha_clear", out[0].link, &out[0].link);
128  }
129  else {
130  /* Output premultiplied alpha depending on alpha socket usage. This makes
131  * it so that if we blend the color with a transparent shader using alpha as
132  * a factor, we don't multiply alpha into the color twice. And if we do
133  * not, then there will be no artifacts from zero alpha areas. */
134  if (ima->alpha_mode == IMA_ALPHA_PREMUL) {
135  if (out[1].hasoutput) {
136  GPU_link(mat, "color_alpha_unpremultiply", out[0].link, &out[0].link);
137  }
138  else {
139  GPU_link(mat, "color_alpha_clear", out[0].link, &out[0].link);
140  }
141  }
142  else {
143  if (out[1].hasoutput) {
144  GPU_link(mat, "color_alpha_clear", out[0].link, &out[0].link);
145  }
146  else {
147  GPU_link(mat, "color_alpha_premultiply", out[0].link, &out[0].link);
148  }
149  }
150  }
151  }
152 
153  return true;
154 }
155 
156 } // namespace blender::nodes::node_shader_tex_image_cc
157 
159 {
160  namespace file_ns = blender::nodes::node_shader_tex_image_cc;
161 
162  static bNodeType ntype;
163 
164  sh_node_type_base(&ntype, SH_NODE_TEX_IMAGE, "Image Texture", NODE_CLASS_TEXTURE);
168  &ntype, "NodeTexImage", node_free_standard_storage, node_copy_standard_storage);
170  ntype.labelfunc = node_image_label;
172 
173  nodeRegisterType(&ntype);
174 }
void BKE_imageuser_default(struct ImageUser *iuser)
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
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:355
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
@ NODE_SIZE_LARGE
Definition: BKE_node.h:367
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition: texture.c:238
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition: texture.c:340
#define UNUSED(x)
#define ELEM(...)
@ CD_AUTO_FROM_NAME
@ IMA_ALPHA_IGNORE
@ IMA_ALPHA_PREMUL
@ IMA_ALPHA_CHANNEL_PACKED
@ IMA_SRC_TILED
#define SHD_PROJ_SPHERE
#define SHD_PROJ_BOX
#define SHD_IMAGE_EXTENSION_CLIP
#define SHD_INTERP_SMART
#define SHD_IMAGE_EXTENSION_REPEAT
#define SHD_PROJ_FLAT
#define SHD_PROJ_TUBE
#define SHD_INTERP_CLOSEST
#define SHD_INTERP_CUBIC
#define TEXMAP_TYPE_POINT
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
GPUNodeLink * GPU_image(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser, eGPUSamplerState sampler_state)
GPUNodeLink * GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser)
GPUNodeLink * GPU_uniform(const float *num)
GPUNodeLink * GPU_image_tiled(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser, eGPUSamplerState sampler_state)
bool GPU_link(GPUMaterial *mat, const char *name,...)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
eGPUSamplerState
Definition: GPU_texture.h:25
@ GPU_SAMPLER_ANISO
Definition: GPU_texture.h:34
@ GPU_SAMPLER_REPEAT
Definition: GPU_texture.h:37
@ GPU_SAMPLER_MIPMAP
Definition: GPU_texture.h:28
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:27
@ GPU_SAMPLER_CLAMP_BORDER
Definition: GPU_texture.h:32
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:26
bool IMB_colormanagement_space_name_is_data(const char *name)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block SH_NODE_TEX_IMAGE
ColorManagedColorspaceSettings colorspace_settings
short source
char alpha_mode
OperationNode * node
bNodeTree * ntree
static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void sh_node_tex_image_declare(NodeDeclarationBuilder &b)
static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_sh_tex_image()
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out))
void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeLink **link)
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
void node_image_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
Definition: node_util.c:189
struct GPUNodeLink * link
Definition: GPU_material.h:106
ImageUser iuser
struct ImageUser iuser
Defines a node type.
Definition: BKE_node.h:226
void(* labelfunc)(const struct bNodeTree *ntree, const struct bNode *node, char *label, int maxlen)
Definition: BKE_node.h:256
NodeDeclareFunction declare
Definition: BKE_node.h:324
void * storage
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
#define N_(msgid)