Blender  V3.3
blender/light.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include "scene/light.h"
5 
6 #include "blender/sync.h"
7 #include "blender/util.h"
8 
9 #include "util/hash.h"
10 
12 
13 void BlenderSync::sync_light(BL::Object &b_parent,
14  int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
15  BObjectInfo &b_ob_info,
16  int random_id,
17  Transform &tfm,
18  bool *use_portal)
19 {
20  /* test if we need to sync */
21  ObjectKey key(b_parent, persistent_id, b_ob_info.real_object, false);
22  BL::Light b_light(b_ob_info.object_data);
23 
24  Light *light = light_map.find(key);
25 
26  /* Check if the transform was modified, in case a linked collection is moved we do not get a
27  * specific depsgraph update (T88515). This also mimics the behavior for Objects. */
28  const bool tfm_updated = (light && light->get_tfm() != tfm);
29 
30  /* Update if either object or light data changed. */
31  if (!light_map.add_or_update(&light, b_ob_info.real_object, b_parent, key) && !tfm_updated) {
32  Shader *shader;
33  if (!shader_map.add_or_update(&shader, b_light)) {
34  if (light->get_is_portal())
35  *use_portal = true;
36  return;
37  }
38  }
39 
40  /* type */
41  switch (b_light.type()) {
42  case BL::Light::type_POINT: {
43  BL::PointLight b_point_light(b_light);
44  light->set_size(b_point_light.shadow_soft_size());
45  light->set_light_type(LIGHT_POINT);
46  break;
47  }
48  case BL::Light::type_SPOT: {
49  BL::SpotLight b_spot_light(b_light);
50  light->set_size(b_spot_light.shadow_soft_size());
51  light->set_light_type(LIGHT_SPOT);
52  light->set_spot_angle(b_spot_light.spot_size());
53  light->set_spot_smooth(b_spot_light.spot_blend());
54  break;
55  }
56  /* Hemi were removed from 2.8 */
57  // case BL::Light::type_HEMI: {
58  // light->type = LIGHT_DISTANT;
59  // light->size = 0.0f;
60  // break;
61  // }
62  case BL::Light::type_SUN: {
63  BL::SunLight b_sun_light(b_light);
64  light->set_angle(b_sun_light.angle());
65  light->set_light_type(LIGHT_DISTANT);
66  break;
67  }
68  case BL::Light::type_AREA: {
69  BL::AreaLight b_area_light(b_light);
70  light->set_size(1.0f);
71  light->set_axisu(transform_get_column(&tfm, 0));
72  light->set_axisv(transform_get_column(&tfm, 1));
73  light->set_sizeu(b_area_light.size());
74  light->set_spread(b_area_light.spread());
75  switch (b_area_light.shape()) {
76  case BL::AreaLight::shape_SQUARE:
77  light->set_sizev(light->get_sizeu());
78  light->set_round(false);
79  break;
80  case BL::AreaLight::shape_RECTANGLE:
81  light->set_sizev(b_area_light.size_y());
82  light->set_round(false);
83  break;
84  case BL::AreaLight::shape_DISK:
85  light->set_sizev(light->get_sizeu());
86  light->set_round(true);
87  break;
88  case BL::AreaLight::shape_ELLIPSE:
89  light->set_sizev(b_area_light.size_y());
90  light->set_round(true);
91  break;
92  }
93  light->set_light_type(LIGHT_AREA);
94  break;
95  }
96  }
97 
98  /* strength */
99  float3 strength = get_float3(b_light.color()) * BL::PointLight(b_light).energy();
100  light->set_strength(strength);
101 
102  /* location and (inverted!) direction */
103  light->set_co(transform_get_column(&tfm, 3));
104  light->set_dir(-transform_get_column(&tfm, 2));
105  light->set_tfm(tfm);
106 
107  /* shader */
108  array<Node *> used_shaders;
109  find_shader(b_light, used_shaders, scene->default_light);
110  light->set_shader(static_cast<Shader *>(used_shaders[0]));
111 
112  /* shadow */
113  PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
114  light->set_cast_shadow(get_boolean(clight, "cast_shadow"));
115  light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling"));
116 
117  /* caustics light */
118  light->set_use_caustics(get_boolean(clight, "is_caustics_light"));
119 
120  light->set_max_bounces(get_int(clight, "max_bounces"));
121 
122  if (b_ob_info.real_object != b_ob_info.iter_object) {
123  light->set_random_id(random_id);
124  }
125  else {
126  light->set_random_id(hash_uint2(hash_string(b_ob_info.real_object.name().c_str()), 0));
127  }
128 
129  if (light->get_light_type() == LIGHT_AREA)
130  light->set_is_portal(get_boolean(clight, "is_portal"));
131  else
132  light->set_is_portal(false);
133 
134  if (light->get_is_portal())
135  *use_portal = true;
136 
137  /* visibility */
138  uint visibility = object_ray_visibility(b_ob_info.real_object);
139  light->set_use_camera((visibility & PATH_RAY_CAMERA) != 0);
140  light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0);
141  light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0);
142  light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0);
143  light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0);
144  light->set_is_shadow_catcher(b_ob_info.real_object.is_shadow_catcher());
145 
146  /* lightgroup */
147  light->set_lightgroup(ustring(b_ob_info.real_object.lightgroup()));
148 
149  /* tag */
150  light->tag_update(scene);
151 }
152 
153 void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
154 {
155  BL::World b_world = b_scene.world();
156 
157  if (b_world) {
158  PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
159 
160  enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
161  int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
162  bool sample_as_light = (sampling_method != SAMPLING_NONE);
163 
164  if (sample_as_light || use_portal) {
165  /* test if we need to sync */
166  Light *light;
167  ObjectKey key(b_world, 0, b_world, false);
168 
169  if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc ||
170  b_world.ptr.data != world_map) {
171  light->set_light_type(LIGHT_BACKGROUND);
172  if (sampling_method == SAMPLING_MANUAL) {
173  light->set_map_resolution(get_int(cworld, "sample_map_resolution"));
174  }
175  else {
176  light->set_map_resolution(0);
177  }
178  light->set_shader(scene->default_background);
179  light->set_use_mis(sample_as_light);
180  light->set_max_bounces(get_int(cworld, "max_bounces"));
181 
182  /* force enable light again when world is resynced */
183  light->set_is_enabled(true);
184 
185  /* caustic light */
186  light->set_use_caustics(get_boolean(cworld, "is_caustics_light"));
187 
188  light->tag_update(scene);
189  light_map.set_recalc(b_world);
190  }
191  }
192  }
193 
194  world_map = b_world.ptr.data;
195  world_recalc = false;
196  viewport_parameters = BlenderViewportParameters(b_v3d, use_developer_ui);
197 }
198 
unsigned int uint
Definition: BLI_sys_types.h:67
struct Light Light
struct Object Object
struct World World
bool add_or_update(T **r_data, const BL::ID &id)
Definition: id_map.h:100
void set_recalc(const BL::ID &id)
Definition: id_map.h:56
T * find(const BL::ID &id)
Definition: id_map.h:41
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
static uint object_ray_visibility(BL::Object &b_ob)
static bool get_boolean(PointerRNA &ptr, const char *name)
static int get_int(PointerRNA &ptr, const char *name)
static float3 get_float3(const BL::Array< float, 2 > &array)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
static uint hash_string(const char *str)
Definition: hash.h:363
ccl_device_inline uint hash_uint2(uint kx, uint ky)
Definition: hash.h:70
@ OBJECT_PERSISTENT_ID_SIZE
Definition: id_map.h:186
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
@ PATH_RAY_TRANSMIT
Definition: kernel/types.h:196
@ PATH_RAY_VOLUME_SCATTER
Definition: kernel/types.h:201
@ PATH_RAY_GLOSSY
Definition: kernel/types.h:198
@ PATH_RAY_DIFFUSE
Definition: kernel/types.h:197
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
@ LIGHT_AREA
Definition: kernel/types.h:459
@ LIGHT_DISTANT
Definition: kernel/types.h:457
@ LIGHT_SPOT
Definition: kernel/types.h:460
@ LIGHT_BACKGROUND
Definition: kernel/types.h:458
@ LIGHT_POINT
Definition: kernel/types.h:456
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
BL::Object real_object
BL::Object iter_object
void tag_update(Scene *scene)
Shader * default_background
Definition: scene.h:235
Shader * default_light
Definition: scene.h:234