Blender  V3.3
node_shader_tex_sky.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 #include "sky_model.h"
6 
7 #include "BKE_context.h"
8 #include "BKE_scene.h"
9 
10 #include "UI_interface.h"
11 #include "UI_resources.h"
12 
14 
16 
18 {
19  b.add_input<decl::Vector>(N_("Vector")).hide_value();
20  b.add_output<decl::Color>(N_("Color")).no_muted_links();
21 }
22 
24 {
25  uiItemR(layout, ptr, "sky_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
26 
27  if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) {
28  uiItemR(layout, ptr, "sun_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
29  uiItemR(layout, ptr, "turbidity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
30  }
31  if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) {
32  uiItemR(layout, ptr, "sun_direction", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
33  uiItemR(layout, ptr, "turbidity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
34  uiItemR(layout, ptr, "ground_albedo", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
35  }
36  if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
39  uiItemL(layout, TIP_("Nishita not available in Eevee"), ICON_ERROR);
40  }
41  uiItemR(layout, ptr, "sun_disc", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, 0);
42 
43  uiLayout *col;
44  if (RNA_boolean_get(ptr, "sun_disc")) {
45  col = uiLayoutColumn(layout, true);
46  uiItemR(col, ptr, "sun_size", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
47  uiItemR(col, ptr, "sun_intensity", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
48  }
49 
50  col = uiLayoutColumn(layout, true);
51  uiItemR(col, ptr, "sun_elevation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
52  uiItemR(col, ptr, "sun_rotation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
53 
54  uiItemR(layout, ptr, "altitude", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
55 
56  col = uiLayoutColumn(layout, true);
57  uiItemR(col, ptr, "air_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
58  uiItemR(col, ptr, "dust_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
59  uiItemR(col, ptr, "ozone_density", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
60  }
61 }
62 
64 {
65  NodeTexSky *tex = MEM_cnew<NodeTexSky>("NodeTexSky");
67  BKE_texture_colormapping_default(&tex->base.color_mapping);
68  tex->sun_direction[0] = 0.0f;
69  tex->sun_direction[1] = 0.0f;
70  tex->sun_direction[2] = 1.0f;
71  tex->turbidity = 2.2f;
72  tex->ground_albedo = 0.3f;
73  tex->sun_disc = true;
74  tex->sun_size = DEG2RADF(0.545f);
75  tex->sun_intensity = 1.0f;
76  tex->sun_elevation = DEG2RADF(15.0f);
77  tex->sun_rotation = 0.0f;
78  tex->altitude = 0.0f;
79  tex->air_density = 1.0f;
80  tex->dust_density = 1.0f;
81  tex->ozone_density = 1.0f;
82  tex->sky_model = SHD_SKY_NISHITA;
83  node->storage = tex;
84 }
85 
87  float config_Y[5], config_x[5], config_y[5]; /* named after xyY color space */
88  float radiance[3];
89 };
90 
91 static float sky_perez_function(const float *lam, float theta, float gamma)
92 {
93  float ctheta = cosf(theta);
94  float cgamma = cosf(gamma);
95 
96  return (1.0 + lam[0] * expf(lam[1] / ctheta)) *
97  (1.0 + lam[2] * expf(lam[3] * gamma) + lam[4] * cgamma * cgamma);
98 }
99 
100 static void sky_precompute_old(SkyModelPreetham *sunsky, const float sun_angles[], float turbidity)
101 {
102  float theta = sun_angles[0];
103  float theta2 = theta * theta;
104  float theta3 = theta2 * theta;
105  float T = turbidity;
106  float T2 = T * T;
107  float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI - 2.0f * theta);
108 
109  sunsky->radiance[0] = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
110  sunsky->radiance[0] *= 0.06f;
111 
112  sunsky->radiance[1] = (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
113  (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) *
114  T +
115  (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
116 
117  sunsky->radiance[2] = (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
118  (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) *
119  T +
120  (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
121 
122  sunsky->config_Y[0] = (0.1787f * T - 1.4630f);
123  sunsky->config_Y[1] = (-0.3554f * T + 0.4275f);
124  sunsky->config_Y[2] = (-0.0227f * T + 5.3251f);
125  sunsky->config_Y[3] = (0.1206f * T - 2.5771f);
126  sunsky->config_Y[4] = (-0.0670f * T + 0.3703f);
127 
128  sunsky->config_x[0] = (-0.0193f * T - 0.2592f);
129  sunsky->config_x[1] = (-0.0665f * T + 0.0008f);
130  sunsky->config_x[2] = (-0.0004f * T + 0.2125f);
131  sunsky->config_x[3] = (-0.0641f * T - 0.8989f);
132  sunsky->config_x[4] = (-0.0033f * T + 0.0452f);
133 
134  sunsky->config_y[0] = (-0.0167f * T - 0.2608f);
135  sunsky->config_y[1] = (-0.0950f * T + 0.0092f);
136  sunsky->config_y[2] = (-0.0079f * T + 0.2102f);
137  sunsky->config_y[3] = (-0.0441f * T - 1.6537f);
138  sunsky->config_y[4] = (-0.0109f * T + 0.0529f);
139 
140  sunsky->radiance[0] /= sky_perez_function(sunsky->config_Y, 0, theta);
141  sunsky->radiance[1] /= sky_perez_function(sunsky->config_x, 0, theta);
142  sunsky->radiance[2] /= sky_perez_function(sunsky->config_y, 0, theta);
143 }
144 
146  bNode *node,
147  bNodeExecData *UNUSED(execdata),
148  GPUNodeStack *in,
149  GPUNodeStack *out)
150 {
151  node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
153  NodeTexSky *tex = (NodeTexSky *)node->storage;
154  float sun_angles[2]; /* [0]=theta=zenith angle [1]=phi=azimuth */
155  sun_angles[0] = acosf(tex->sun_direction[2]);
156  sun_angles[1] = atan2f(tex->sun_direction[0], tex->sun_direction[1]);
157 
158  if (tex->sky_model == 0) {
159  /* Preetham */
160  SkyModelPreetham sunsky;
161  sky_precompute_old(&sunsky, sun_angles, tex->turbidity);
164  return GPU_stack_link(mat,
165  node,
166  "node_tex_sky_preetham",
167  in,
168  out,
169  /* Pass config_Y/x/y as 3x(vec4+float) */
170  GPU_uniform(&sunsky.config_Y[0]),
171  GPU_uniform(&sunsky.config_Y[4]),
172  GPU_uniform(&sunsky.config_x[0]),
173  GPU_uniform(&sunsky.config_x[4]),
174  GPU_uniform(&sunsky.config_y[0]),
175  GPU_uniform(&sunsky.config_y[4]),
176  GPU_uniform(sun_angles),
177  GPU_uniform(sunsky.radiance),
181  }
182  if (tex->sky_model == 1) {
183  /* Hosek / Wilkie */
184  sun_angles[0] = fmin(M_PI_2, sun_angles[0]); /* clamp to horizon */
186  tex->turbidity, tex->ground_albedo, fmax(0.0, M_PI_2 - sun_angles[0]));
187  /* Pass sky_state->configs[3][9] as 3*(vec4+vec4)+vec3 */
188  float config_x07[8], config_y07[8], config_z07[8], config_xyz8[3];
189  for (int i = 0; i < 8; ++i) {
190  config_x07[i] = (float)sky_state->configs[0][i];
191  config_y07[i] = (float)sky_state->configs[1][i];
192  config_z07[i] = (float)sky_state->configs[2][i];
193  }
194  for (int i = 0; i < 3; ++i) {
195  config_xyz8[i] = (float)sky_state->configs[i][8];
196  }
197  float radiance[3];
198  for (int i = 0; i < 3; i++) {
199  radiance[i] = sky_state->radiances[i] * (2 * M_PI / 683);
200  }
204  return GPU_stack_link(mat,
205  node,
206  "node_tex_sky_hosekwilkie",
207  in,
208  out,
209  GPU_uniform(&config_x07[0]),
210  GPU_uniform(&config_x07[4]),
211  GPU_uniform(&config_y07[0]),
212  GPU_uniform(&config_y07[4]),
213  GPU_uniform(&config_z07[0]),
214  GPU_uniform(&config_z07[4]),
215  GPU_uniform(config_xyz8),
216  GPU_uniform(sun_angles),
217  GPU_uniform(radiance),
221  }
222 
223  return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
224 }
225 
227 {
228  bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
229 
230  NodeTexSky *tex = (NodeTexSky *)node->storage;
231  nodeSetSocketAvailability(ntree, sockVector, !(tex->sky_model == 2 && tex->sun_disc == 1));
232 }
233 
235 {
236  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
237  if (params.in_out() == SOCK_OUT) {
239  return;
240  }
241  if (params.node_tree().typeinfo->validate_link(
242  static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
243  params.add_item(IFACE_("Vector"), [](LinkSearchOpParams &params) {
244  bNode &node = params.add_node("ShaderNodeTexSky");
245  NodeTexSky *tex = (NodeTexSky *)node.storage;
246  tex->sun_disc = false;
247  params.update_and_connect_available_socket(node, "Vector");
248  });
249  }
250 }
251 
252 } // namespace blender::nodes::node_shader_tex_sky_cc
253 
254 /* node type definition */
256 {
257  namespace file_ns = blender::nodes::node_shader_tex_sky_cc;
258 
259  static bNodeType ntype;
260 
261  sh_node_type_base(&ntype, SH_NODE_TEX_SKY, "Sky Texture", NODE_CLASS_TEXTURE);
268  /* Remove vector input for Nishita sky model. */
271 
272  nodeRegisterType(&ntype);
273 }
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
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
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:355
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
@ NODE_SIZE_MIDDLE
Definition: BKE_node.h:366
bool BKE_scene_uses_blender_eevee(const struct Scene *scene)
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 M_PI_2
Definition: BLI_math_base.h:23
#define M_PI
Definition: BLI_math_base.h:20
#define DEG2RADF(_deg)
#define UNUSED(x)
#define TIP_(msgid)
#define IFACE_(msgid)
#define SHD_SKY_NISHITA
#define SHD_SKY_PREETHAM
@ SOCK_OUT
@ SOCK_IN
eNodeSocketDatatype
@ SOCK_FLOAT
#define SHD_SKY_HOSEK
#define TEXMAP_TYPE_POINT
GPUNodeLink * GPU_uniform(const float *num)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
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 Image Sample an image file as a texture SH_NODE_TEX_SKY
#define C
Definition: RandGen.cpp:25
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemL(uiLayout *layout, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
Span< SocketDeclarationPtr > outputs() const
#define cosf(x)
Definition: cuda/compat.h:101
#define expf(x)
Definition: cuda/compat.h:106
#define tanf(x)
Definition: cuda/compat.h:104
OperationNode * node
Scene scene
bNodeTree * ntree
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define T
#define T2
Definition: md5.cpp:18
#define atan2f(x, y)
Definition: metal/compat.h:227
#define acosf(x)
Definition: metal/compat.h:222
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void sky_precompute_old(SkyModelPreetham *sunsky, const float sun_angles[], float turbidity)
static int node_shader_gpu_tex_sky(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
static float sky_perez_function(const float *lam, float theta, float gamma)
static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_buts_tex_sky(uiLayout *layout, bContext *C, PointerRNA *ptr)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclarationPtr > declarations)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
color xyz_to_rgb(float x, float y, float z)
Definition: node_color.h:63
void register_node_type_sh_tex_sky()
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out))
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
void get_XYZ_to_RGB_for_gpu(XYZ_to_RGB *data)
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
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state)
Definition: sky_model.cpp:267
SKY_ArHosekSkyModelState * SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity, const double albedo, const double elevation)
Definition: sky_model.cpp:305
SKY_ArHosekSkyModelConfiguration configs[11]
Definition: sky_model.h:316
Defines a node type.
Definition: BKE_node.h:226
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480