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