Blender  V3.3
scene/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 "device/device.h"
5 
6 #include "scene/background.h"
7 #include "scene/film.h"
8 #include "scene/integrator.h"
9 #include "scene/light.h"
10 #include "scene/mesh.h"
11 #include "scene/object.h"
12 #include "scene/scene.h"
13 #include "scene/shader.h"
14 #include "scene/shader_graph.h"
15 #include "scene/shader_nodes.h"
16 #include "scene/stats.h"
17 
18 #include "integrator/shader_eval.h"
19 
20 #include "util/foreach.h"
21 #include "util/hash.h"
22 #include "util/log.h"
23 #include "util/path.h"
24 #include "util/progress.h"
25 #include "util/task.h"
26 
28 
29 static void shade_background_pixels(Device *device,
30  DeviceScene *dscene,
31  int width,
32  int height,
33  vector<float3> &pixels,
34  Progress &progress)
35 {
36  /* Needs to be up to data for attribute access. */
37  device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
38 
39  const int size = width * height;
40  const int num_channels = 3;
41  pixels.resize(size);
42 
43  /* Evaluate shader on device. */
44  ShaderEval shader_eval(device, progress);
45  shader_eval.eval(
47  size,
48  num_channels,
50  /* Fill coordinates for shading. */
51  KernelShaderEvalInput *d_input_data = d_input.data();
52 
53  for (int y = 0; y < height; y++) {
54  for (int x = 0; x < width; x++) {
55  float u = (x + 0.5f) / width;
56  float v = (y + 0.5f) / height;
57 
59  in.object = OBJECT_NONE;
60  in.prim = PRIM_NONE;
61  in.u = u;
62  in.v = v;
63  d_input_data[x + y * width] = in;
64  }
65  }
66 
67  return size;
68  },
69  [&](device_vector<float> &d_output) {
70  /* Copy output to pixel buffer. */
71  float *d_output_data = d_output.data();
72 
73  for (int y = 0; y < height; y++) {
74  for (int x = 0; x < width; x++) {
75  pixels[y * width + x].x = d_output_data[(y * width + x) * num_channels + 0];
76  pixels[y * width + x].y = d_output_data[(y * width + x) * num_channels + 1];
77  pixels[y * width + x].z = d_output_data[(y * width + x) * num_channels + 2];
78  }
79  }
80  });
81 }
82 
83 /* Light */
84 
86 {
87  NodeType *type = NodeType::add("light", create);
88 
89  static NodeEnum type_enum;
90  type_enum.insert("point", LIGHT_POINT);
91  type_enum.insert("distant", LIGHT_DISTANT);
92  type_enum.insert("background", LIGHT_BACKGROUND);
93  type_enum.insert("area", LIGHT_AREA);
94  type_enum.insert("spot", LIGHT_SPOT);
95  SOCKET_ENUM(light_type, "Type", type_enum, LIGHT_POINT);
96 
97  SOCKET_COLOR(strength, "Strength", one_float3());
98 
99  SOCKET_POINT(co, "Co", zero_float3());
100 
101  SOCKET_VECTOR(dir, "Dir", zero_float3());
102  SOCKET_FLOAT(size, "Size", 0.0f);
103  SOCKET_FLOAT(angle, "Angle", 0.0f);
104 
105  SOCKET_VECTOR(axisu, "Axis U", zero_float3());
106  SOCKET_FLOAT(sizeu, "Size U", 1.0f);
107  SOCKET_VECTOR(axisv, "Axis V", zero_float3());
108  SOCKET_FLOAT(sizev, "Size V", 1.0f);
109  SOCKET_BOOLEAN(round, "Round", false);
110  SOCKET_FLOAT(spread, "Spread", M_PI_F);
111 
112  SOCKET_INT(map_resolution, "Map Resolution", 0);
113 
114  SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
115  SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
116 
117  SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
118 
119  SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true);
120  SOCKET_BOOLEAN(use_mis, "Use Mis", false);
121  SOCKET_BOOLEAN(use_camera, "Use Camera", true);
122  SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true);
123  SOCKET_BOOLEAN(use_glossy, "Use Glossy", true);
124  SOCKET_BOOLEAN(use_transmission, "Use Transmission", true);
125  SOCKET_BOOLEAN(use_scatter, "Use Scatter", true);
126  SOCKET_BOOLEAN(use_caustics, "Shadow Caustics", false);
127 
128  SOCKET_INT(max_bounces, "Max Bounces", 1024);
129  SOCKET_UINT(random_id, "Random ID", 0);
130 
131  SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", true);
132  SOCKET_BOOLEAN(is_portal, "Is Portal", false);
133  SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
134 
135  SOCKET_NODE(shader, "Shader", Shader::get_node_type());
136 
137  SOCKET_STRING(lightgroup, "Light Group", ustring());
138 
139  return type;
140 }
141 
142 Light::Light() : Node(get_node_type())
143 {
145 }
146 
148 {
149  if (is_modified()) {
151  }
152 }
153 
155 {
156  if (strength == zero_float3()) {
157  return false;
158  }
159  if (is_portal) {
160  return false;
161  }
162  if (light_type == LIGHT_BACKGROUND) {
163  return true;
164  }
165  return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
166 }
167 
168 /* Light Manager */
169 
171 {
173  need_update_background = true;
174  last_background_enabled = false;
176 }
177 
179 {
180  foreach (IESSlot *slot, ies_slots) {
181  delete slot;
182  }
183 }
184 
186 {
187  foreach (Light *light, scene->lights) {
188  if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) {
189  return true;
190  }
191  }
192  return false;
193 }
194 
196 {
197  /* Make all lights enabled by default, and perform some preliminary checks
198  * needed for finer-tuning of settings (for example, check whether we've
199  * got portals or not).
200  */
201  bool has_portal = false, has_background = false;
202  foreach (Light *light, scene->lights) {
203  light->is_enabled = light->has_contribution(scene);
204  has_portal |= light->is_portal;
205  has_background |= light->light_type == LIGHT_BACKGROUND;
206  }
207 
208  bool background_enabled = false;
209  int background_resolution = 0;
210 
211  if (has_background) {
212  /* Ignore background light if:
213  * - If unsupported on a device
214  * - If we don't need it (no HDRs etc.)
215  */
216  Shader *shader = scene->background->get_shader(scene);
217  const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
218  if (disable_mis) {
219  VLOG_INFO << "Background MIS has been disabled.\n";
220  }
221  foreach (Light *light, scene->lights) {
222  if (light->light_type == LIGHT_BACKGROUND) {
223  light->is_enabled = !disable_mis;
224  background_enabled = !disable_mis;
225  background_resolution = light->map_resolution;
226  }
227  }
228  }
229 
230  if (last_background_enabled != background_enabled ||
231  last_background_resolution != background_resolution) {
232  last_background_enabled = background_enabled;
233  last_background_resolution = background_resolution;
234  need_update_background = true;
235  }
236 }
237 
239 {
240  Geometry *geom = object->get_geometry();
241  if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
242  return false;
243  }
244  /* Skip objects with NaNs */
245  if (!object->bounds.valid()) {
246  return false;
247  }
248  /* Skip if we are not visible for BSDFs. */
249  if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
250  return false;
251  }
252  /* Skip if we have no emission shaders. */
253  /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
254  * iterate all geometry shaders twice (when counting and when calculating
255  * triangle area.
256  */
257  foreach (Node *node, geom->get_used_shaders()) {
258  Shader *shader = static_cast<Shader *>(node);
259  if (shader->get_use_mis() && shader->has_surface_emission) {
260  return true;
261  }
262  }
263  return false;
264 }
265 
267  DeviceScene *dscene,
268  Scene *scene,
269  Progress &progress)
270 {
271  progress.set_status("Updating Lights", "Computing distribution");
272 
273  /* count */
274  size_t num_lights = 0;
275  size_t num_portals = 0;
276  size_t num_background_lights = 0;
277  size_t num_triangles = 0;
278 
279  bool background_mis = false;
280 
281  foreach (Light *light, scene->lights) {
282  if (light->is_enabled) {
283  num_lights++;
284  }
285  if (light->is_portal) {
286  num_portals++;
287  }
288  }
289 
290  foreach (Object *object, scene->objects) {
291  if (progress.get_cancel())
292  return;
293 
294  if (!object_usable_as_light(object)) {
295  continue;
296  }
297 
298  /* Count triangles. */
299  Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
300  size_t mesh_num_triangles = mesh->num_triangles();
301  for (size_t i = 0; i < mesh_num_triangles; i++) {
302  int shader_index = mesh->get_shader()[i];
303  Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
304  static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
306 
307  if (shader->get_use_mis() && shader->has_surface_emission) {
308  num_triangles++;
309  }
310  }
311  }
312 
313  size_t num_distribution = num_triangles + num_lights;
314  VLOG_INFO << "Total " << num_distribution << " of light distribution primitives.";
315 
316  /* emission area */
317  KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
318  float totarea = 0.0f;
319 
320  /* triangles */
321  size_t offset = 0;
322  int j = 0;
323 
324  foreach (Object *object, scene->objects) {
325  if (progress.get_cancel())
326  return;
327 
328  if (!object_usable_as_light(object)) {
329  j++;
330  continue;
331  }
332  /* Sum area. */
333  Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
334  bool transform_applied = mesh->transform_applied;
335  Transform tfm = object->get_tfm();
336  int object_id = j;
337  int shader_flag = 0;
338 
339  if (!(object->get_visibility() & PATH_RAY_CAMERA)) {
340  shader_flag |= SHADER_EXCLUDE_CAMERA;
341  }
342  if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) {
343  shader_flag |= SHADER_EXCLUDE_DIFFUSE;
344  }
345  if (!(object->get_visibility() & PATH_RAY_GLOSSY)) {
346  shader_flag |= SHADER_EXCLUDE_GLOSSY;
347  }
348  if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) {
349  shader_flag |= SHADER_EXCLUDE_TRANSMIT;
350  }
351  if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) {
352  shader_flag |= SHADER_EXCLUDE_SCATTER;
353  }
354  if (!(object->get_is_shadow_catcher())) {
355  shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER;
356  }
357 
358  size_t mesh_num_triangles = mesh->num_triangles();
359  for (size_t i = 0; i < mesh_num_triangles; i++) {
360  int shader_index = mesh->get_shader()[i];
361  Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
362  static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
364 
365  if (shader->get_use_mis() && shader->has_surface_emission) {
366  distribution[offset].totarea = totarea;
367  distribution[offset].prim = i + mesh->prim_offset;
368  distribution[offset].mesh_light.shader_flag = shader_flag;
369  distribution[offset].mesh_light.object_id = object_id;
370  offset++;
371 
373  if (!t.valid(&mesh->get_verts()[0])) {
374  continue;
375  }
376  float3 p1 = mesh->get_verts()[t.v[0]];
377  float3 p2 = mesh->get_verts()[t.v[1]];
378  float3 p3 = mesh->get_verts()[t.v[2]];
379 
380  if (!transform_applied) {
381  p1 = transform_point(&tfm, p1);
382  p2 = transform_point(&tfm, p2);
383  p3 = transform_point(&tfm, p3);
384  }
385 
386  totarea += triangle_area(p1, p2, p3);
387  }
388  }
389 
390  j++;
391  }
392 
393  float trianglearea = totarea;
394  /* point lights */
395  bool use_lamp_mis = false;
396  int light_index = 0;
397 
398  if (num_lights > 0) {
399  float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
400  foreach (Light *light, scene->lights) {
401  if (!light->is_enabled)
402  continue;
403 
404  distribution[offset].totarea = totarea;
405  distribution[offset].prim = ~light_index;
406  distribution[offset].lamp.pad = 1.0f;
407  distribution[offset].lamp.size = light->size;
408  totarea += lightarea;
409 
410  if (light->light_type == LIGHT_DISTANT) {
411  use_lamp_mis |= (light->angle > 0.0f && light->use_mis);
412  }
413  else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) {
414  use_lamp_mis |= (light->size > 0.0f && light->use_mis);
415  }
416  else if (light->light_type == LIGHT_AREA) {
417  use_lamp_mis |= light->use_mis;
418  }
419  else if (light->light_type == LIGHT_BACKGROUND) {
420  num_background_lights++;
421  background_mis |= light->use_mis;
422  }
423 
424  light_index++;
425  offset++;
426  }
427  }
428 
429  /* normalize cumulative distribution functions */
430  distribution[num_distribution].totarea = totarea;
431  distribution[num_distribution].prim = 0.0f;
432  distribution[num_distribution].lamp.pad = 0.0f;
433  distribution[num_distribution].lamp.size = 0.0f;
434 
435  if (totarea > 0.0f) {
436  for (size_t i = 0; i < num_distribution; i++)
437  distribution[i].totarea /= totarea;
438  distribution[num_distribution].totarea = 1.0f;
439  }
440 
441  if (progress.get_cancel())
442  return;
443 
444  /* update device */
445  KernelIntegrator *kintegrator = &dscene->data.integrator;
446  KernelBackground *kbackground = &dscene->data.background;
447  KernelFilm *kfilm = &dscene->data.film;
448  kintegrator->use_direct_light = (totarea > 0.0f);
449 
450  if (kintegrator->use_direct_light) {
451  /* number of emissives */
452  kintegrator->num_distribution = num_distribution;
453 
454  /* precompute pdfs */
455  kintegrator->pdf_triangles = 0.0f;
456  kintegrator->pdf_lights = 0.0f;
457 
458  /* sample one, with 0.5 probability of light or triangle */
459  kintegrator->num_all_lights = num_lights;
460 
461  if (trianglearea > 0.0f) {
462  kintegrator->pdf_triangles = 1.0f / trianglearea;
463  if (num_lights)
464  kintegrator->pdf_triangles *= 0.5f;
465  }
466 
467  if (num_lights) {
468  kintegrator->pdf_lights = 1.0f / num_lights;
469  if (trianglearea > 0.0f)
470  kintegrator->pdf_lights *= 0.5f;
471  }
472 
473  kintegrator->use_lamp_mis = use_lamp_mis;
474 
475  /* bit of an ugly hack to compensate for emitting triangles influencing
476  * amount of samples we get for this pass */
477  kfilm->pass_shadow_scale = 1.0f;
478 
479  if (kintegrator->pdf_triangles != 0.0f)
480  kfilm->pass_shadow_scale /= 0.5f;
481 
482  if (num_background_lights < num_lights)
483  kfilm->pass_shadow_scale /= (float)(num_lights - num_background_lights) / (float)num_lights;
484 
485  /* CDF */
487 
488  /* Portals */
489  if (num_portals > 0) {
490  kbackground->portal_offset = light_index;
491  kbackground->num_portals = num_portals;
492  kbackground->portal_weight = 1.0f;
493  }
494  else {
495  kbackground->num_portals = 0;
496  kbackground->portal_offset = 0;
497  kbackground->portal_weight = 0.0f;
498  }
499 
500  /* Map */
501  kbackground->map_weight = background_mis ? 1.0f : 0.0f;
502  }
503  else {
504  dscene->light_distribution.free();
505 
506  kintegrator->num_distribution = 0;
507  kintegrator->num_all_lights = 0;
508  kintegrator->pdf_triangles = 0.0f;
509  kintegrator->pdf_lights = 0.0f;
510  kintegrator->use_lamp_mis = false;
511 
512  kbackground->num_portals = 0;
513  kbackground->portal_offset = 0;
514  kbackground->portal_weight = 0.0f;
515  kbackground->sun_weight = 0.0f;
516  kbackground->map_weight = 0.0f;
517 
518  kfilm->pass_shadow_scale = 1.0f;
519  }
520 }
521 
522 static void background_cdf(
523  int start, int end, int res_x, int res_y, const vector<float3> *pixels, float2 *cond_cdf)
524 {
525  int cdf_width = res_x + 1;
526  /* Conditional CDFs (rows, U direction). */
527  for (int i = start; i < end; i++) {
528  float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
529  float3 env_color = (*pixels)[i * res_x];
530  float ave_luminance = average(env_color);
531 
532  cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
533  cond_cdf[i * cdf_width].y = 0.0f;
534 
535  for (int j = 1; j < res_x; j++) {
536  env_color = (*pixels)[i * res_x + j];
537  ave_luminance = average(env_color);
538 
539  cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
540  cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y +
541  cond_cdf[i * cdf_width + j - 1].x / res_x;
542  }
543 
544  const float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y +
545  cond_cdf[i * cdf_width + res_x - 1].x / res_x;
546 
547  /* stuff the total into the brightness value for the last entry, because
548  * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
549  cond_cdf[i * cdf_width + res_x].x = cdf_total;
550 
551  if (cdf_total > 0.0f) {
552  const float cdf_total_inv = 1.0f / cdf_total;
553  for (int j = 1; j < res_x; j++) {
554  cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
555  }
556  }
557 
558  cond_cdf[i * cdf_width + res_x].y = 1.0f;
559  }
560 }
561 
563  DeviceScene *dscene,
564  Scene *scene,
565  Progress &progress)
566 {
567  KernelBackground *kbackground = &dscene->data.background;
568  Light *background_light = NULL;
569 
570  /* find background light */
571  foreach (Light *light, scene->lights) {
572  if (light->light_type == LIGHT_BACKGROUND) {
573  background_light = light;
574  break;
575  }
576  }
577 
578  /* no background light found, signal renderer to skip sampling */
579  if (!background_light || !background_light->is_enabled) {
580  kbackground->map_res_x = 0;
581  kbackground->map_res_y = 0;
582  kbackground->map_weight = 0.0f;
583  kbackground->sun_weight = 0.0f;
584  kbackground->use_mis = (kbackground->portal_weight > 0.0f);
585  return;
586  }
587 
588  progress.set_status("Updating Lights", "Importance map");
589 
590  assert(dscene->data.integrator.use_direct_light);
591 
592  int2 environment_res = make_int2(0, 0);
593  Shader *shader = scene->background->get_shader(scene);
594  int num_suns = 0;
595  foreach (ShaderNode *node, shader->graph->nodes) {
596  if (node->type == EnvironmentTextureNode::get_node_type()) {
598  ImageMetaData metadata;
599  if (!env->handle.empty()) {
600  ImageMetaData metadata = env->handle.metadata();
601  environment_res.x = max(environment_res.x, (int)metadata.width);
602  environment_res.y = max(environment_res.y, (int)metadata.height);
603  }
604  }
605  if (node->type == SkyTextureNode::get_node_type()) {
607  if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) {
608  /* Ensure that the input coordinates aren't transformed before they reach the node.
609  * If that is the case, the logic used for sampling the sun's location does not work
610  * and we have to fall back to map-based sampling. */
611  const ShaderInput *vec_in = sky->input("Vector");
612  if (vec_in && vec_in->link && vec_in->link->parent) {
613  ShaderNode *vec_src = vec_in->link->parent;
614  if ((vec_src->type != TextureCoordinateNode::get_node_type()) ||
615  (vec_in->link != vec_src->output("Generated"))) {
616  environment_res.x = max(environment_res.x, 4096);
617  environment_res.y = max(environment_res.y, 2048);
618  continue;
619  }
620  }
621 
622  /* Determine sun direction from lat/long and texture mapping. */
623  float latitude = sky->get_sun_elevation();
624  float longitude = M_2PI_F - sky->get_sun_rotation() + M_PI_2_F;
625  float3 sun_direction = make_float3(
626  cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude));
628  sun_direction = transform_direction(&sky_transform, sun_direction);
629 
630  /* Pack sun direction and size. */
631  float half_angle = sky->get_sun_size() * 0.5f;
632  kbackground->sun = make_float4(
633  sun_direction.x, sun_direction.y, sun_direction.z, half_angle);
634 
635  kbackground->sun_weight = 4.0f;
636  environment_res.x = max(environment_res.x, 512);
637  environment_res.y = max(environment_res.y, 256);
638  num_suns++;
639  }
640  }
641  }
642 
643  /* If there's more than one sun, fall back to map sampling instead. */
644  if (num_suns != 1) {
645  kbackground->sun_weight = 0.0f;
646  environment_res.x = max(environment_res.x, 4096);
647  environment_res.y = max(environment_res.y, 2048);
648  }
649 
650  /* Enable MIS for background sampling if any strategy is active. */
651  kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
652  kbackground->sun_weight) > 0.0f;
653 
654  /* get the resolution from the light's size (we stuff it in there) */
655  int2 res = make_int2(background_light->map_resolution, background_light->map_resolution / 2);
656  /* If the resolution isn't set manually, try to find an environment texture. */
657  if (res.x == 0) {
658  res = environment_res;
659  if (res.x > 0 && res.y > 0) {
660  VLOG_INFO << "Automatically set World MIS resolution to " << res.x << " by " << res.y
661  << "\n";
662  }
663  }
664  /* If it's still unknown, just use the default. */
665  if (res.x == 0 || res.y == 0) {
666  res = make_int2(1024, 512);
667  VLOG_INFO << "Setting World MIS resolution to default\n";
668  }
669  kbackground->map_res_x = res.x;
670  kbackground->map_res_y = res.y;
671 
672  vector<float3> pixels;
673  shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
674 
675  if (progress.get_cancel())
676  return;
677 
678  /* build row distributions and column distribution for the infinite area environment light */
679  int cdf_width = res.x + 1;
680  float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
681  float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
682 
683  double time_start = time_dt();
684 
685  /* Create CDF in parallel. */
686  const int rows_per_task = divide_up(10240, res.x);
687  parallel_for(blocked_range<size_t>(0, res.y, rows_per_task),
688  [&](const blocked_range<size_t> &r) {
689  background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
690  });
691 
692  /* marginal CDFs (column, V direction, sum of rows) */
693  marg_cdf[0].x = cond_cdf[res.x].x;
694  marg_cdf[0].y = 0.0f;
695 
696  for (int i = 1; i < res.y; i++) {
697  marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
698  marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
699  }
700 
701  float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
702  marg_cdf[res.y].x = cdf_total;
703 
704  if (cdf_total > 0.0f)
705  for (int i = 1; i < res.y; i++)
706  marg_cdf[i].y /= cdf_total;
707 
708  marg_cdf[res.y].y = 1.0f;
709 
710  VLOG_WORK << "Background MIS build time " << time_dt() - time_start << "\n";
711 
712  /* update device */
715 }
716 
718 {
719  int num_scene_lights = scene->lights.size();
720 
721  int num_lights = 0;
722  foreach (Light *light, scene->lights) {
723  if (light->is_enabled || light->is_portal) {
724  num_lights++;
725  }
726  }
727 
728  KernelLight *klights = dscene->lights.alloc(num_lights);
729 
730  if (num_lights == 0) {
731  VLOG_WORK << "No effective light, ignoring points update.";
732  return;
733  }
734 
735  int light_index = 0;
736 
737  foreach (Light *light, scene->lights) {
738  if (!light->is_enabled) {
739  continue;
740  }
741 
742  float3 co = light->co;
743  Shader *shader = (light->shader) ? light->shader : scene->default_light;
744  int shader_id = scene->shader_manager->get_shader_id(shader);
745  int max_bounces = light->max_bounces;
746  float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF);
747 
748  if (!light->cast_shadow)
749  shader_id &= ~SHADER_CAST_SHADOW;
750 
751  if (!light->use_camera) {
752  shader_id |= SHADER_EXCLUDE_CAMERA;
753  }
754  if (!light->use_diffuse) {
755  shader_id |= SHADER_EXCLUDE_DIFFUSE;
756  }
757  if (!light->use_glossy) {
758  shader_id |= SHADER_EXCLUDE_GLOSSY;
759  }
760  if (!light->use_transmission) {
761  shader_id |= SHADER_EXCLUDE_TRANSMIT;
762  }
763  if (!light->use_scatter) {
764  shader_id |= SHADER_EXCLUDE_SCATTER;
765  }
766  if (!light->is_shadow_catcher) {
767  shader_id |= SHADER_EXCLUDE_SHADOW_CATCHER;
768  }
769 
770  klights[light_index].type = light->light_type;
771  klights[light_index].strength[0] = light->strength.x;
772  klights[light_index].strength[1] = light->strength.y;
773  klights[light_index].strength[2] = light->strength.z;
774 
775  if (light->light_type == LIGHT_POINT) {
776  shader_id &= ~SHADER_AREA_LIGHT;
777 
778  float radius = light->size;
779  float invarea = (radius > 0.0f) ? 1.0f / (M_PI_F * radius * radius) : 1.0f;
780 
781  if (light->use_mis && radius > 0.0f)
782  shader_id |= SHADER_USE_MIS;
783 
784  klights[light_index].co[0] = co.x;
785  klights[light_index].co[1] = co.y;
786  klights[light_index].co[2] = co.z;
787 
788  klights[light_index].spot.radius = radius;
789  klights[light_index].spot.invarea = invarea;
790  }
791  else if (light->light_type == LIGHT_DISTANT) {
792  shader_id &= ~SHADER_AREA_LIGHT;
793 
794  float angle = light->angle / 2.0f;
795  float radius = tanf(angle);
796  float cosangle = cosf(angle);
797  float area = M_PI_F * radius * radius;
798  float invarea = (area > 0.0f) ? 1.0f / area : 1.0f;
799  float3 dir = light->dir;
800 
801  dir = safe_normalize(dir);
802 
803  if (light->use_mis && area > 0.0f)
804  shader_id |= SHADER_USE_MIS;
805 
806  klights[light_index].co[0] = dir.x;
807  klights[light_index].co[1] = dir.y;
808  klights[light_index].co[2] = dir.z;
809 
810  klights[light_index].distant.invarea = invarea;
811  klights[light_index].distant.radius = radius;
812  klights[light_index].distant.cosangle = cosangle;
813  }
814  else if (light->light_type == LIGHT_BACKGROUND) {
815  uint visibility = scene->background->get_visibility();
816 
817  shader_id &= ~SHADER_AREA_LIGHT;
818  shader_id |= SHADER_USE_MIS;
819 
820  if (!(visibility & PATH_RAY_DIFFUSE)) {
821  shader_id |= SHADER_EXCLUDE_DIFFUSE;
822  }
823  if (!(visibility & PATH_RAY_GLOSSY)) {
824  shader_id |= SHADER_EXCLUDE_GLOSSY;
825  }
826  if (!(visibility & PATH_RAY_TRANSMIT)) {
827  shader_id |= SHADER_EXCLUDE_TRANSMIT;
828  }
829  if (!(visibility & PATH_RAY_VOLUME_SCATTER)) {
830  shader_id |= SHADER_EXCLUDE_SCATTER;
831  }
832  }
833  else if (light->light_type == LIGHT_AREA) {
834  float3 axisu = light->axisu * (light->sizeu * light->size);
835  float3 axisv = light->axisv * (light->sizev * light->size);
836  float area = len(axisu) * len(axisv);
837  if (light->round) {
838  area *= -M_PI_4_F;
839  }
840  float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
841  float3 dir = light->dir;
842 
843  /* Convert from spread angle 0..180 to 90..0, clamping to a minimum
844  * angle to avoid excessive noise. */
845  const float min_spread_angle = 1.0f * M_PI_F / 180.0f;
846  const float spread_angle = 0.5f * (M_PI_F - max(light->spread, min_spread_angle));
847  /* Normalization computed using:
848  * integrate cos(x) * (1 - tan(x) * tan(a)) * sin(x) from x = 0 to pi/2 - a. */
849  const float tan_spread = tanf(spread_angle);
850  const float normalize_spread = 2.0f / (2.0f + (2.0f * spread_angle - M_PI_F) * tan_spread);
851 
852  dir = safe_normalize(dir);
853 
854  if (light->use_mis && area != 0.0f)
855  shader_id |= SHADER_USE_MIS;
856 
857  klights[light_index].co[0] = co.x;
858  klights[light_index].co[1] = co.y;
859  klights[light_index].co[2] = co.z;
860 
861  klights[light_index].area.axisu[0] = axisu.x;
862  klights[light_index].area.axisu[1] = axisu.y;
863  klights[light_index].area.axisu[2] = axisu.z;
864  klights[light_index].area.axisv[0] = axisv.x;
865  klights[light_index].area.axisv[1] = axisv.y;
866  klights[light_index].area.axisv[2] = axisv.z;
867  klights[light_index].area.invarea = invarea;
868  klights[light_index].area.dir[0] = dir.x;
869  klights[light_index].area.dir[1] = dir.y;
870  klights[light_index].area.dir[2] = dir.z;
871  klights[light_index].area.tan_spread = tan_spread;
872  klights[light_index].area.normalize_spread = normalize_spread;
873  }
874  else if (light->light_type == LIGHT_SPOT) {
875  shader_id &= ~SHADER_AREA_LIGHT;
876 
877  float radius = light->size;
878  float invarea = (radius > 0.0f) ? 1.0f / (M_PI_F * radius * radius) : 1.0f;
879  float spot_angle = cosf(light->spot_angle * 0.5f);
880  float spot_smooth = (1.0f - spot_angle) * light->spot_smooth;
881  float3 dir = light->dir;
882 
883  dir = safe_normalize(dir);
884 
885  if (light->use_mis && radius > 0.0f)
886  shader_id |= SHADER_USE_MIS;
887 
888  klights[light_index].co[0] = co.x;
889  klights[light_index].co[1] = co.y;
890  klights[light_index].co[2] = co.z;
891 
892  klights[light_index].spot.radius = radius;
893  klights[light_index].spot.invarea = invarea;
894  klights[light_index].spot.spot_angle = spot_angle;
895  klights[light_index].spot.spot_smooth = spot_smooth;
896  klights[light_index].spot.dir[0] = dir.x;
897  klights[light_index].spot.dir[1] = dir.y;
898  klights[light_index].spot.dir[2] = dir.z;
899  }
900 
901  klights[light_index].shader_id = shader_id;
902 
903  klights[light_index].max_bounces = max_bounces;
904  klights[light_index].random = random;
905  klights[light_index].use_caustics = light->use_caustics;
906 
907  klights[light_index].tfm = light->tfm;
908  klights[light_index].itfm = transform_inverse(light->tfm);
909 
910  auto it = scene->lightgroups.find(light->lightgroup);
911  if (it != scene->lightgroups.end()) {
912  klights[light_index].lightgroup = it->second;
913  }
914  else {
915  klights[light_index].lightgroup = LIGHTGROUP_NONE;
916  }
917 
918  light_index++;
919  }
920 
921  /* TODO(sergey): Consider moving portals update to their own function
922  * keeping this one more manageable.
923  */
924  foreach (Light *light, scene->lights) {
925  if (!light->is_portal)
926  continue;
927  assert(light->light_type == LIGHT_AREA);
928 
929  float3 co = light->co;
930  float3 axisu = light->axisu * (light->sizeu * light->size);
931  float3 axisv = light->axisv * (light->sizev * light->size);
932  float area = len(axisu) * len(axisv);
933  if (light->round) {
934  area *= -M_PI_4_F;
935  }
936  float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
937  float3 dir = light->dir;
938 
939  dir = safe_normalize(dir);
940 
941  klights[light_index].co[0] = co.x;
942  klights[light_index].co[1] = co.y;
943  klights[light_index].co[2] = co.z;
944 
945  klights[light_index].area.axisu[0] = axisu.x;
946  klights[light_index].area.axisu[1] = axisu.y;
947  klights[light_index].area.axisu[2] = axisu.z;
948  klights[light_index].area.axisv[0] = axisv.x;
949  klights[light_index].area.axisv[1] = axisv.y;
950  klights[light_index].area.axisv[2] = axisv.z;
951  klights[light_index].area.invarea = invarea;
952  klights[light_index].area.dir[0] = dir.x;
953  klights[light_index].area.dir[1] = dir.y;
954  klights[light_index].area.dir[2] = dir.z;
955  klights[light_index].tfm = light->tfm;
956  klights[light_index].itfm = transform_inverse(light->tfm);
957 
958  light_index++;
959  }
960 
961  VLOG_INFO << "Number of lights sent to the device: " << light_index;
962 
963  VLOG_INFO << "Number of lights without contribution: " << num_scene_lights - light_index;
964 
965  dscene->lights.copy_to_device();
966 }
967 
969  DeviceScene *dscene,
970  Scene *scene,
971  Progress &progress)
972 {
973  if (!need_update())
974  return;
975 
976  scoped_callback_timer timer([scene](double time) {
977  if (scene->update_stats) {
978  scene->update_stats->light.times.add_entry({"device_update", time});
979  }
980  });
981 
982  VLOG_INFO << "Total " << scene->lights.size() << " lights.";
983 
984  /* Detect which lights are enabled, also determines if we need to update the background. */
985  test_enabled_lights(scene);
986 
987  device_free(device, dscene, need_update_background);
988 
989  device_update_points(device, dscene, scene);
990  if (progress.get_cancel())
991  return;
992 
993  device_update_distribution(device, dscene, scene, progress);
994  if (progress.get_cancel())
995  return;
996 
997  if (need_update_background) {
998  device_update_background(device, dscene, scene, progress);
999  if (progress.get_cancel())
1000  return;
1001  }
1002 
1003  device_update_ies(dscene);
1004  if (progress.get_cancel())
1005  return;
1006 
1007  update_flags = UPDATE_NONE;
1008  need_update_background = false;
1009 }
1010 
1011 void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background)
1012 {
1013  dscene->light_distribution.free();
1014  dscene->lights.free();
1015  if (free_background) {
1018  }
1019  dscene->ies_lights.free();
1020 }
1021 
1022 void LightManager::tag_update(Scene * /*scene*/, uint32_t flag)
1023 {
1024  update_flags |= flag;
1025 }
1026 
1028 {
1029  return update_flags != UPDATE_NONE;
1030 }
1031 
1032 int LightManager::add_ies_from_file(const string &filename)
1033 {
1034  string content;
1035 
1036  /* If the file can't be opened, call with an empty line */
1037  if (filename.empty() || !path_read_text(filename.c_str(), content)) {
1038  content = "\n";
1039  }
1040 
1041  return add_ies(content);
1042 }
1043 
1044 int LightManager::add_ies(const string &content)
1045 {
1046  uint hash = hash_string(content.c_str());
1047 
1048  thread_scoped_lock ies_lock(ies_mutex);
1049 
1050  /* Check whether this IES already has a slot. */
1051  size_t slot;
1052  for (slot = 0; slot < ies_slots.size(); slot++) {
1053  if (ies_slots[slot]->hash == hash) {
1054  ies_slots[slot]->users++;
1055  return slot;
1056  }
1057  }
1058 
1059  /* Try to find an empty slot for the new IES. */
1060  for (slot = 0; slot < ies_slots.size(); slot++) {
1061  if (ies_slots[slot]->users == 0 && ies_slots[slot]->hash == 0) {
1062  break;
1063  }
1064  }
1065 
1066  /* If there's no free slot, add one. */
1067  if (slot == ies_slots.size()) {
1068  ies_slots.push_back(new IESSlot());
1069  }
1070 
1071  ies_slots[slot]->ies.load(content);
1072  ies_slots[slot]->users = 1;
1073  ies_slots[slot]->hash = hash;
1074 
1076  need_update_background = true;
1077 
1078  return slot;
1079 }
1080 
1082 {
1083  thread_scoped_lock ies_lock(ies_mutex);
1084 
1085  if (slot < 0 || slot >= ies_slots.size()) {
1086  assert(false);
1087  return;
1088  }
1089 
1090  assert(ies_slots[slot]->users > 0);
1091  ies_slots[slot]->users--;
1092 
1093  /* If the slot has no more users, update the device to remove it. */
1094  if (ies_slots[slot]->users == 0) {
1096  need_update_background = true;
1097  }
1098 }
1099 
1101 {
1102  /* Clear empty slots. */
1103  foreach (IESSlot *slot, ies_slots) {
1104  if (slot->users == 0) {
1105  slot->hash = 0;
1106  slot->ies.clear();
1107  }
1108  }
1109 
1110  /* Shrink the slot table by removing empty slots at the end. */
1111  int slot_end;
1112  for (slot_end = ies_slots.size(); slot_end; slot_end--) {
1113  if (ies_slots[slot_end - 1]->users > 0) {
1114  /* If the preceding slot has users, we found the new end of the table. */
1115  break;
1116  }
1117  else {
1118  /* The slot will be past the new end of the table, so free it. */
1119  delete ies_slots[slot_end - 1];
1120  }
1121  }
1122  ies_slots.resize(slot_end);
1123 
1124  if (ies_slots.size() > 0) {
1125  int packed_size = 0;
1126  foreach (IESSlot *slot, ies_slots) {
1127  packed_size += slot->ies.packed_size();
1128  }
1129 
1130  /* ies_lights starts with an offset table that contains the offset of every slot,
1131  * or -1 if the slot is invalid.
1132  * Following that table, the packed valid IES lights are stored. */
1133  float *data = dscene->ies_lights.alloc(ies_slots.size() + packed_size);
1134 
1135  int offset = ies_slots.size();
1136  for (int i = 0; i < ies_slots.size(); i++) {
1137  int size = ies_slots[i]->ies.packed_size();
1138  if (size > 0) {
1139  data[i] = __int_as_float(offset);
1140  ies_slots[i]->ies.pack(data + offset);
1141  offset += size;
1142  }
1143  else {
1144  data[i] = __int_as_float(-1);
1145  }
1146  }
1147 
1148  dscene->ies_lights.copy_to_device();
1149  }
1150 }
1151 
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Shader * get_shader(const Scene *scene)
device_vector< float2 > light_background_marginal_cdf
Definition: scene.h:111
device_vector< float > ies_lights
Definition: scene.h:128
device_vector< float2 > light_background_conditional_cdf
Definition: scene.h:112
device_vector< KernelLightDistribution > light_distribution
Definition: scene.h:109
KernelData data
Definition: scene.h:130
device_vector< KernelLight > lights
Definition: scene.h:110
virtual void const_copy_to(const char *name, void *host, size_t size)=0
Type geometry_type
bool transform_applied
size_t prim_offset
int packed_size()
Definition: ies.cpp:37
void clear()
Definition: ies.cpp:30
bool empty() const
ImageMetaData metadata()
ImageHandle handle
Definition: shader_nodes.h:87
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_ies(DeviceScene *dscene)
int add_ies(const string &ies)
vector< IESSlot * > ies_slots
Definition: scene/light.h:150
int add_ies_from_file(const string &filename)
void test_enabled_lights(Scene *scene)
uint32_t update_flags
Definition: scene/light.h:156
void device_free(Device *device, DeviceScene *dscene, const bool free_background=true)
void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
bool need_update_background
Definition: scene/light.h:103
void device_update_points(Device *device, DeviceScene *dscene, Scene *scene)
bool need_update() const
void remove_ies(int slot)
void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
int last_background_resolution
Definition: scene/light.h:154
thread_mutex ies_mutex
Definition: scene/light.h:151
bool has_background_light(Scene *scene)
bool object_usable_as_light(Object *object)
void tag_update(Scene *scene, uint32_t flag)
bool last_background_enabled
Definition: scene/light.h:153
bool get_cancel() const
Definition: progress.h:90
void set_status(const string &status_, const string &substatus_="")
Definition: progress.h:248
bool eval(const ShaderEvalType type, const int max_num_inputs, const int num_channels, const function< int(device_vector< KernelShaderEvalInput > &)> &fill_input, const function< void(device_vector< float > &)> &read_output)
Definition: shader_eval.cpp:23
list< ShaderNode * > nodes
Definition: shader_graph.h:299
ShaderOutput * link
Definition: shader_graph.h:103
int get_shader_id(Shader *shader, bool smooth=false)
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
ShaderNode * parent
Definition: shader_graph.h:134
bool has_surface_spatial_varying
Definition: scene/shader.h:112
NODE_DECLARE ShaderGraph * graph
Definition: scene/shader.h:71
bool has_surface_emission
Definition: scene/shader.h:104
float get_sun_size()
Definition: shader_nodes.h:172
Transform compute_transform()
TextureMapping tex_mapping
Definition: shader_nodes.h:59
T * alloc(size_t width, size_t height=0, size_t depth=0)
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
#define tanf(x)
Definition: cuda/compat.h:104
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
double time
Scene scene
int len
Definition: draw_manager.c:108
int users
Definition: editfont_undo.c:76
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
Definition: frames.inl:1282
static uint hash_string(const char *str)
Definition: hash.h:363
@ SHADER_EVAL_BACKGROUND
ccl_device_inline Transform transform_identity()
ccl_device_inline Transform transform_inverse(const Transform tfm)
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
@ NODE_SKY_NISHITA
#define PRIM_NONE
Definition: kernel/types.h:41
@ 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
#define OBJECT_NONE
Definition: kernel/types.h:40
@ SHADER_EXCLUDE_SHADOW_CATCHER
Definition: kernel/types.h:444
@ SHADER_EXCLUDE_CAMERA
Definition: kernel/types.h:442
@ SHADER_EXCLUDE_DIFFUSE
Definition: kernel/types.h:439
@ SHADER_USE_MIS
Definition: kernel/types.h:438
@ SHADER_EXCLUDE_SCATTER
Definition: kernel/types.h:443
@ SHADER_EXCLUDE_GLOSSY
Definition: kernel/types.h:440
@ SHADER_AREA_LIGHT
Definition: kernel/types.h:437
@ SHADER_EXCLUDE_TRANSMIT
Definition: kernel/types.h:441
@ SHADER_CAST_SHADOW
Definition: kernel/types.h:436
#define LIGHTGROUP_NONE
Definition: kernel/types.h:45
@ 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
#define VLOG_INFO
Definition: log.h:77
#define VLOG_WORK
Definition: log.h:80
ccl_device_inline float2 safe_normalize(const float2 &a)
Definition: math_float2.h:201
ccl_device_inline float average(const float2 &a)
Definition: math_float2.h:170
ccl_device_inline float3 one_float3()
Definition: math_float3.h:89
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
#define make_float4(x, y, z, w)
Definition: metal/compat.h:205
#define make_int2(x, y)
Definition: metal/compat.h:206
#define make_float3(x, y, z)
Definition: metal/compat.h:204
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
static void area(int d1, int d2, int e1, int e2, float weights[2])
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
#define SOCKET_POINT(name, ui_name, default_value,...)
Definition: node_type.h:197
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:191
#define SOCKET_INT(name, ui_name, default_value,...)
Definition: node_type.h:187
#define SOCKET_NODE(name, ui_name, node_type,...)
Definition: node_type.h:220
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition: node_type.h:205
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition: node_type.h:189
#define SOCKET_VECTOR(name, ui_name, default_value,...)
Definition: node_type.h:195
#define SOCKET_COLOR(name, ui_name, default_value,...)
Definition: node_type.h:193
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:185
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition: node_type.h:203
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition: node_type.h:207
#define hash
Definition: noise.c:153
bool path_read_text(const string &path, string &text)
Definition: path.cpp:701
static void background_cdf(int start, int end, int res_x, int res_y, const vector< float3 > *pixels, float2 *cond_cdf)
NODE_DEFINE(Light)
Definition: scene/light.cpp:85
static CCL_NAMESPACE_BEGIN void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector< float3 > &pixels, Progress &progress)
Definition: scene/light.cpp:29
unsigned int uint32_t
Definition: stdint.h:80
__forceinline bool valid() const
Definition: boundbox.h:129
struct KernelLightDistribution::@1252::@1254 mesh_light
struct KernelLightDistribution::@1252::@1255 lamp
float co[3]
Transform itfm
float strength[3]
float max_bounces
KernelSpotLight spot
Transform tfm
KernelDistantLight distant
KernelAreaLight area
void tag_update(Scene *scene)
bool has_contribution(Scene *scene)
float size[3]
Triangle get_triangle(size_t i) const
Definition: scene/mesh.h:73
size_t num_triangles() const
Definition: scene/mesh.h:79
void insert(const char *x, int y)
Definition: node_enum.h:20
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition: graph/node.h:175
void dereference_all_used_nodes()
Definition: graph/node.cpp:779
bool is_modified() const
Definition: graph/node.cpp:804
NODE_DECLARE BoundBox bounds
Definition: scene/object.h:43
vector< Light * > lights
Definition: scene.h:216
Shader * default_surface
Definition: scene.h:232
vector< Object * > objects
Definition: scene.h:213
Background * background
Definition: scene.h:209
ShaderManager * shader_manager
Definition: scene.h:224
LightManager * light_manager
Definition: scene.h:223
Shader * default_light
Definition: scene.h:234
map< ustring, int > lightgroups
Definition: scene.h:201
SceneUpdateStats * update_stats
Definition: scene.h:249
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
float z
float y
float x
int x
Definition: types_int2.h:15
int y
Definition: types_int2.h:15
std::unique_lock< std::mutex > thread_scoped_lock
Definition: thread.h:28
CCL_NAMESPACE_BEGIN double time_dt()
Definition: time.cpp:35
float max
#define M_PI_2_F
Definition: util/math.h:37
#define M_PI_4_F
Definition: util/math.h:40
ccl_device_inline float triangle_area(ccl_private const float3 &v1, ccl_private const float3 &v2, ccl_private const float3 &v3)
Definition: util/math.h:557
#define M_2PI_F
Definition: util/math.h:60
#define M_PI_F
Definition: util/math.h:34
ccl_device_inline float __int_as_float(int i)
Definition: util/math.h:253
ccl_device_inline size_t divide_up(size_t x, size_t y)
Definition: util/types.h:51