Blender V4.3
scene/light.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "device/device.h"
6
7#include "scene/background.h"
8#include "scene/film.h"
9#include "scene/integrator.h"
10#include "scene/light.h"
11#include "scene/light_tree.h"
12#include "scene/mesh.h"
13#include "scene/object.h"
14#include "scene/scene.h"
15#include "scene/shader.h"
16#include "scene/shader_graph.h"
17#include "scene/shader_nodes.h"
18#include "scene/stats.h"
19
21
22#include "util/foreach.h"
23#include "util/hash.h"
24#include "util/log.h"
25#include "util/path.h"
26#include "util/progress.h"
27#include "util/task.h"
28#include <stack>
29
31
32static void shade_background_pixels(Device *device,
33 DeviceScene *dscene,
34 int width,
35 int height,
36 vector<float3> &pixels,
37 Progress &progress)
38{
39 /* Needs to be up to data for attribute access. */
40 device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
41
42 const int size = width * height;
43 const int num_channels = 3;
44 pixels.resize(size);
45
46 /* Evaluate shader on device. */
47 ShaderEval shader_eval(device, progress);
48 shader_eval.eval(
50 size,
51 num_channels,
53 /* Fill coordinates for shading. */
54 KernelShaderEvalInput *d_input_data = d_input.data();
55
56 for (int y = 0; y < height; y++) {
57 for (int x = 0; x < width; x++) {
58 float u = (x + 0.5f) / width;
59 float v = (y + 0.5f) / height;
60
63 in.prim = PRIM_NONE;
64 in.u = u;
65 in.v = v;
66 d_input_data[x + y * width] = in;
67 }
68 }
69
70 return size;
71 },
72 [&](device_vector<float> &d_output) {
73 /* Copy output to pixel buffer. */
74 float *d_output_data = d_output.data();
75
76 for (int y = 0; y < height; y++) {
77 for (int x = 0; x < width; x++) {
78 pixels[y * width + x].x = d_output_data[(y * width + x) * num_channels + 0];
79 pixels[y * width + x].y = d_output_data[(y * width + x) * num_channels + 1];
80 pixels[y * width + x].z = d_output_data[(y * width + x) * num_channels + 2];
81 }
82 }
83 });
84}
85
86/* Light */
87
89{
90 NodeType *type = NodeType::add("light", create);
91
92 static NodeEnum type_enum;
93 type_enum.insert("point", LIGHT_POINT);
94 type_enum.insert("distant", LIGHT_DISTANT);
95 type_enum.insert("background", LIGHT_BACKGROUND);
96 type_enum.insert("area", LIGHT_AREA);
97 type_enum.insert("spot", LIGHT_SPOT);
98 SOCKET_ENUM(light_type, "Type", type_enum, LIGHT_POINT);
99
100 SOCKET_COLOR(strength, "Strength", one_float3());
101
102 SOCKET_FLOAT(size, "Size", 0.0f);
103 SOCKET_FLOAT(angle, "Angle", 0.0f);
104
105 SOCKET_FLOAT(sizeu, "Size U", 1.0f);
106 SOCKET_FLOAT(sizev, "Size V", 1.0f);
107 SOCKET_BOOLEAN(ellipse, "Ellipse", false);
108 SOCKET_FLOAT(spread, "Spread", M_PI_F);
109
110 SOCKET_INT(map_resolution, "Map Resolution", 0);
111 SOCKET_FLOAT(average_radiance, "Average Radiance", 0.0f);
112
113 SOCKET_BOOLEAN(is_sphere, "Is Sphere", true);
114
115 SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
116 SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
117
118 SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
119
120 SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true);
121 SOCKET_BOOLEAN(use_mis, "Use Mis", false);
122 SOCKET_BOOLEAN(use_camera, "Use Camera", true);
123 SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true);
124 SOCKET_BOOLEAN(use_glossy, "Use Glossy", true);
125 SOCKET_BOOLEAN(use_transmission, "Use Transmission", true);
126 SOCKET_BOOLEAN(use_scatter, "Use Scatter", true);
127 SOCKET_BOOLEAN(use_caustics, "Shadow Caustics", false);
128
129 SOCKET_INT(max_bounces, "Max Bounces", 1024);
130 SOCKET_UINT(random_id, "Random ID", 0);
131
132 SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", true);
133 SOCKET_BOOLEAN(is_portal, "Is Portal", false);
134 SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
135
136 SOCKET_NODE(shader, "Shader", Shader::get_node_type());
137
138 SOCKET_STRING(lightgroup, "Light Group", ustring());
139 SOCKET_UINT64(light_set_membership, "Light Set Membership", LIGHT_LINK_MASK_ALL);
140 SOCKET_UINT64(shadow_set_membership, "Shadow Set Membership", LIGHT_LINK_MASK_ALL);
141
142 SOCKET_BOOLEAN(normalize, "Normalize", true);
143
144 return type;
145}
146
147Light::Light() : Node(get_node_type())
148{
150}
151
153{
154 if (is_modified()) {
155 scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED);
156 }
157}
158
160{
161 if (strength == zero_float3()) {
162 return false;
163 }
164 if (is_portal) {
165 return false;
166 }
167 if (light_type == LIGHT_BACKGROUND) {
168 return true;
169 }
170
171 const Shader *effective_shader = (shader) ? shader : scene->default_light;
172 return !is_zero(effective_shader->emission_estimate);
173}
174
176{
177 if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
178 return true;
179 }
180
181 return false;
182}
183
185{
186 if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
187 return true;
188 }
189
190 return false;
191}
192
194{
195 return transform_get_column(&tfm, 3);
196}
197
199{
200 return -transform_get_column(&tfm, 2);
201}
202
204{
205 return transform_get_column(&tfm, 0);
206}
207
209{
210 return transform_get_column(&tfm, 1);
211}
212
213/* Light Manager */
214
222
224{
225 foreach (IESSlot *slot, ies_slots) {
226 delete slot;
227 }
228}
229
231{
232 foreach (Light *light, scene->lights) {
233 if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) {
234 return true;
235 }
236 }
237 return false;
238}
239
241{
242 /* Make all lights enabled by default, and perform some preliminary checks
243 * needed for finer-tuning of settings (for example, check whether we've
244 * got portals or not).
245 */
246 bool has_portal = false, has_background = false;
247 foreach (Light *light, scene->lights) {
248 light->is_enabled = light->has_contribution(scene);
249 has_portal |= light->is_portal;
250 has_background |= light->light_type == LIGHT_BACKGROUND;
251 }
252
253 bool background_enabled = false;
254 int background_resolution = 0;
255
256 if (has_background) {
257 /* Ignore background light if:
258 * - If unsupported on a device
259 * - If we don't need it (no HDRs etc.)
260 */
261 Shader *shader = scene->background->get_shader(scene);
262 const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
263 if (disable_mis) {
264 VLOG_INFO << "Background MIS has been disabled.\n";
265 }
266 foreach (Light *light, scene->lights) {
267 if (light->light_type == LIGHT_BACKGROUND) {
268 light->is_enabled = !disable_mis;
269 background_enabled = !disable_mis;
270 background_resolution = light->map_resolution;
271 }
272 }
273 }
274
275 if (last_background_enabled != background_enabled ||
276 last_background_resolution != background_resolution)
277 {
278 last_background_enabled = background_enabled;
279 last_background_resolution = background_resolution;
281 }
282}
283
285 DeviceScene *dscene,
286 Scene *scene,
287 Progress &progress)
288{
289 KernelIntegrator *kintegrator = &dscene->data.integrator;
290 if (kintegrator->use_light_tree) {
291 dscene->light_distribution.free();
292 return;
293 }
294
295 /* Update CDF over lights. */
296 progress.set_status("Updating Lights", "Computing distribution");
297
298 /* Counts emissive triangles in the scene. */
299 size_t num_triangles = 0;
300
301 const int num_lights = kintegrator->num_lights;
302 const size_t max_num_triangles = std::numeric_limits<int>::max() - 1 - kintegrator->num_lights;
303 foreach (Object *object, scene->objects) {
304 if (progress.get_cancel()) {
305 return;
306 }
307
308 if (!object->usable_as_light()) {
309 continue;
310 }
311
312 /* Count emissive triangles. */
313 Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
314 int mesh_num_triangles = static_cast<int>(mesh->num_triangles());
315
316 for (int i = 0; i < mesh_num_triangles; i++) {
317 int shader_index = mesh->get_shader()[i];
318 Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
319 static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
320 scene->default_surface;
321
322 if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
323 num_triangles++;
324 }
325 }
326
327 if (num_triangles > max_num_triangles) {
328 progress.set_error(
329 "Number of emissive triangles exceeds the limit, consider using Light Tree or disabling "
330 "Emission Sampling on some emissive materials");
331 }
332 }
333
334 const size_t num_distribution = num_triangles + num_lights;
335
336 /* Distribution size. */
337 kintegrator->num_distribution = num_distribution;
338
339 VLOG_INFO << "Use light distribution with " << num_distribution << " emitters.";
340
341 /* Emission area. */
342 KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
343 float totarea = 0.0f;
344
345 /* Triangles. */
346 size_t offset = 0;
347 int j = 0;
348
349 foreach (Object *object, scene->objects) {
350 if (progress.get_cancel()) {
351 return;
352 }
353
354 if (!object->usable_as_light()) {
355 j++;
356 continue;
357 }
358 /* Sum area. */
359 Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
360 bool transform_applied = mesh->transform_applied;
361 Transform tfm = object->get_tfm();
362 int object_id = j;
363 int shader_flag = 0;
364
365 if (!(object->get_visibility() & PATH_RAY_CAMERA)) {
366 shader_flag |= SHADER_EXCLUDE_CAMERA;
367 }
368 if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) {
369 shader_flag |= SHADER_EXCLUDE_DIFFUSE;
370 }
371 if (!(object->get_visibility() & PATH_RAY_GLOSSY)) {
372 shader_flag |= SHADER_EXCLUDE_GLOSSY;
373 }
374 if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) {
375 shader_flag |= SHADER_EXCLUDE_TRANSMIT;
376 }
377 if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) {
378 shader_flag |= SHADER_EXCLUDE_SCATTER;
379 }
380 if (!(object->get_is_shadow_catcher())) {
381 shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER;
382 }
383
384 size_t mesh_num_triangles = mesh->num_triangles();
385 for (size_t i = 0; i < mesh_num_triangles; i++) {
386 int shader_index = mesh->get_shader()[i];
387 Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
388 static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) :
389 scene->default_surface;
390
391 if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
392 distribution[offset].totarea = totarea;
393 distribution[offset].prim = i + mesh->prim_offset;
394 distribution[offset].mesh_light.shader_flag = shader_flag;
395 distribution[offset].mesh_light.object_id = object_id;
396 offset++;
397
398 Mesh::Triangle t = mesh->get_triangle(i);
399 if (!t.valid(&mesh->get_verts()[0])) {
400 continue;
401 }
402 float3 p1 = mesh->get_verts()[t.v[0]];
403 float3 p2 = mesh->get_verts()[t.v[1]];
404 float3 p3 = mesh->get_verts()[t.v[2]];
405
406 if (!transform_applied) {
407 p1 = transform_point(&tfm, p1);
408 p2 = transform_point(&tfm, p2);
409 p3 = transform_point(&tfm, p3);
410 }
411
412 totarea += triangle_area(p1, p2, p3);
413 }
414 }
415
416 j++;
417 }
418
419 const float trianglearea = totarea;
420
421 /* Lights. */
422 int light_index = 0;
423
424 if (num_lights > 0) {
425 float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
426 foreach (Light *light, scene->lights) {
427 if (!light->is_enabled) {
428 continue;
429 }
430
431 distribution[offset].totarea = totarea;
432 distribution[offset].prim = ~light_index;
433 distribution[offset].mesh_light.object_id = OBJECT_NONE;
434 distribution[offset].mesh_light.shader_flag = 0;
435 totarea += lightarea;
436
437 light_index++;
438 offset++;
439 }
440 }
441
442 /* normalize cumulative distribution functions */
443 distribution[num_distribution].totarea = totarea;
444 distribution[num_distribution].prim = 0;
445 distribution[num_distribution].mesh_light.object_id = OBJECT_NONE;
446 distribution[num_distribution].mesh_light.shader_flag = 0;
447
448 if (totarea > 0.0f) {
449 for (size_t i = 0; i < num_distribution; i++) {
450 distribution[i].totarea /= totarea;
451 }
452 distribution[num_distribution].totarea = 1.0f;
453 }
454
455 if (progress.get_cancel()) {
456 return;
457 }
458
459 /* Update integrator state. */
460 kintegrator->use_direct_light = (totarea > 0.0f);
461
462 /* Precompute pdfs for distribution sampling.
463 * Sample one, with 0.5 probability of light or triangle. */
464 kintegrator->distribution_pdf_triangles = 0.0f;
465 kintegrator->distribution_pdf_lights = 0.0f;
466
467 if (trianglearea > 0.0f) {
468 kintegrator->distribution_pdf_triangles = 1.0f / trianglearea;
469 if (num_lights) {
470 kintegrator->distribution_pdf_triangles *= 0.5f;
471 }
472 }
473
474 if (num_lights) {
475 kintegrator->distribution_pdf_lights = 1.0f / num_lights;
476 if (trianglearea > 0.0f) {
477 kintegrator->distribution_pdf_lights *= 0.5f;
478 }
479 }
480
481 /* Copy distribution to device. */
483}
484
485/* Arguments for functions to convert the light tree to the kernel representation. */
487 const Scene *scene;
493
494 /* Map from instance node to its node index. */
495 std::unordered_map<LightTreeNode *, int> instances;
496};
497
499 const LightTreeNode &node,
500 const int left_child,
501 const int right_child)
502{
503 /* Convert node to kernel representation. */
504 knode.energy = node.measure.energy;
505
506 knode.bbox.min = node.measure.bbox.min;
507 knode.bbox.max = node.measure.bbox.max;
508
509 knode.bcone.axis = node.measure.bcone.axis;
510 knode.bcone.theta_o = node.measure.bcone.theta_o;
511 knode.bcone.theta_e = node.measure.bcone.theta_e;
512
513 knode.bit_trail = node.bit_trail;
514 knode.bit_skip = 0;
515 knode.type = static_cast<LightTreeNodeType>(node.type);
516
517 if (node.is_leaf() || node.is_distant()) {
518 knode.num_emitters = node.get_leaf().num_emitters;
519 knode.leaf.first_emitter = node.get_leaf().first_emitter_index;
520 }
521 else if (node.is_inner()) {
522 knode.num_emitters = -1;
523 knode.inner.left_child = left_child;
524 knode.inner.right_child = right_child;
525 }
526}
527
528static int light_tree_flatten(LightTreeFlatten &flatten,
529 const LightTreeNode *node,
530 KernelLightTreeNode *knodes,
531 KernelLightTreeEmitter *kemitters,
532 int &next_node_index);
533
535 const LightTreeNode &node,
536 KernelLightTreeNode *knodes,
537 KernelLightTreeEmitter *kemitters,
538 int &next_node_index)
539{
540 /* Convert emitters to kernel representation. */
541 for (int i = 0; i < node.get_leaf().num_emitters; i++) {
542 int emitter_index = i + node.get_leaf().first_emitter_index;
543 const LightTreeEmitter &emitter = flatten.emitters[emitter_index];
544 KernelLightTreeEmitter &kemitter = kemitters[emitter_index];
545
546 kemitter.energy = emitter.measure.energy;
547 kemitter.theta_o = emitter.measure.bcone.theta_o;
548 kemitter.theta_e = emitter.measure.bcone.theta_e;
549
550 if (emitter.is_triangle()) {
551 /* Triangle. */
552 int shader_flag = 0;
553 Object *object = flatten.scene->objects[emitter.object_id];
554 Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
555 Shader *shader = static_cast<Shader *>(
556 mesh->get_used_shaders()[mesh->get_shader()[emitter.prim_id]]);
557
558 if (!(object->get_visibility() & PATH_RAY_CAMERA)) {
559 shader_flag |= SHADER_EXCLUDE_CAMERA;
560 }
561 if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) {
562 shader_flag |= SHADER_EXCLUDE_DIFFUSE;
563 }
564 if (!(object->get_visibility() & PATH_RAY_GLOSSY)) {
565 shader_flag |= SHADER_EXCLUDE_GLOSSY;
566 }
567 if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) {
568 shader_flag |= SHADER_EXCLUDE_TRANSMIT;
569 }
570 if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) {
571 shader_flag |= SHADER_EXCLUDE_SCATTER;
572 }
573 if (!(object->get_is_shadow_catcher())) {
574 shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER;
575 }
576
577 kemitter.triangle.id = emitter.prim_id + mesh->prim_offset;
578 kemitter.mesh_light.shader_flag = shader_flag;
579 kemitter.mesh_light.object_id = emitter.object_id;
580 kemitter.triangle.emission_sampling = shader->emission_sampling;
581 flatten.triangle_array[emitter.prim_id + flatten.object_lookup_offset[emitter.object_id]] =
582 emitter_index;
583 }
584 else if (emitter.is_light()) {
585 /* Light object. */
586 kemitter.light.id = emitter.light_id;
587 kemitter.mesh_light.shader_flag = 0;
588 kemitter.mesh_light.object_id = OBJECT_NONE;
589 flatten.light_array[~emitter.light_id] = emitter_index;
590 }
591 else {
592 /* Mesh instance. */
593 assert(emitter.is_mesh());
594 kemitter.mesh.object_id = emitter.object_id;
595 kemitter.mesh_light.shader_flag = 0;
596 kemitter.mesh_light.object_id = OBJECT_NONE;
597 flatten.mesh_array[emitter.object_id] = emitter_index;
598
599 /* Create instance node. One instance node will be the same as the
600 * reference node, and for that it will recursively build the subtree. */
601 LightTreeNode *instance_node = emitter.root.get();
602 LightTreeNode *reference_node = instance_node->get_reference();
603
604 auto map_it = flatten.instances.find(reference_node);
605 if (map_it == flatten.instances.end()) {
606 if (instance_node != reference_node) {
607 /* Flatten the node with the subtree first so the subsequent instances know the index. */
608 std::swap(instance_node->type, reference_node->type);
609 std::swap(instance_node->variant_type, reference_node->variant_type);
610 }
611 instance_node->type &= ~LIGHT_TREE_INSTANCE;
612 }
613
615 flatten, instance_node, knodes, kemitters, next_node_index);
616
617 KernelLightTreeNode &kinstance_node = knodes[kemitter.mesh.node_id];
618 kinstance_node.bit_trail = node.bit_trail;
619
620 if (map_it != flatten.instances.end()) {
621 kinstance_node.instance.reference = map_it->second;
622 }
623 else {
624 flatten.instances[reference_node] = kemitter.mesh.node_id;
625 }
626 }
627 kemitter.bit_trail = node.bit_trail;
628 }
629}
630
632 const LightTreeNode *node,
633 KernelLightTreeNode *knodes,
634 KernelLightTreeEmitter *kemitters,
635 int &next_node_index)
636{
637 /* Convert both inner nodes and primitives to device representation. */
638 const int node_index = next_node_index++;
639 int left_child = -1, right_child = -1;
640
641 if (node->is_leaf() || node->is_distant()) {
642 light_tree_leaf_emitters_copy_and_flatten(flatten, *node, knodes, kemitters, next_node_index);
643 }
644 else if (node->is_inner()) {
645 left_child = light_tree_flatten(flatten,
646 node->get_inner().children[LightTree::left].get(),
647 knodes,
648 kemitters,
649 next_node_index);
650 right_child = light_tree_flatten(flatten,
651 node->get_inner().children[LightTree::right].get(),
652 knodes,
653 kemitters,
654 next_node_index);
655 }
656 else {
657 /* Instance node that is not inner or leaf, but just references another. */
658 assert(node->is_instance());
659 }
660
661 light_tree_node_copy_to_device(knodes[node_index], *node, left_child, right_child);
662
663 return node_index;
664}
665
667 const LightTreeNode *node,
668 KernelLightTreeNode *knodes,
669 KernelLightTreeEmitter *kemitters,
670 int &next_node_index)
671{
672 /* Convert only emitters to device representation. */
673 if (node->is_leaf() || node->is_distant()) {
674 light_tree_leaf_emitters_copy_and_flatten(flatten, *node, knodes, kemitters, next_node_index);
675 }
676 else {
677 assert(node->is_inner());
678
680 node->get_inner().children[LightTree::left].get(),
681 knodes,
682 kemitters,
683 next_node_index);
685 node->get_inner().children[LightTree::right].get(),
686 knodes,
687 kemitters,
688 next_node_index);
689 }
690}
691
692static std::pair<int, LightTreeMeasure> light_tree_specialize_nodes_flatten(
693 const LightTreeFlatten &flatten,
694 LightTreeNode *node,
695 const uint64_t light_link_mask,
696 const int depth,
698 int &next_node_index)
699{
700 assert(!node->is_instance());
701
702 /* Convert inner nodes to device representation, specialized for light linking. */
703 int node_index, left_child = -1, right_child = -1;
704
705 LightTreeNode new_node(LightTreeMeasure::empty, node->bit_trail);
706
707 if (depth == 0 && !(node->light_link.set_membership & light_link_mask)) {
708 /* Ensure there is always a root node. */
709 node_index = next_node_index++;
710 new_node.make_leaf(-1, 0);
711 }
712 else if (node->light_link.shareable && node->light_link.shared_node_index != -1) {
713 /* Share subtree already built for another light link set. */
714 return std::make_pair(node->light_link.shared_node_index, node->measure);
715 }
716 else if (node->is_leaf() || node->is_distant()) {
717 /* Specialize leaf node. */
718 node_index = next_node_index++;
719 int first_emitter = -1;
720 int num_emitters = 0;
721
722 for (int i = 0; i < node->get_leaf().num_emitters; i++) {
723 const LightTreeEmitter &emitter = flatten.emitters[node->get_leaf().first_emitter_index + i];
724 if (emitter.light_set_membership & light_link_mask) {
725 /* Assumes emitters are consecutive due to LighTree::sort_leaf. */
726 if (first_emitter == -1) {
727 first_emitter = node->get_leaf().first_emitter_index + i;
728 }
729 num_emitters++;
730 new_node.measure.add(emitter.measure);
731 }
732 }
733
734 assert(first_emitter != -1);
735
736 /* Preserve the type of the node, so that the kernel can do proper decision when sampling node
737 * with multiple distant lights in it. */
738 if (node->is_leaf()) {
739 new_node.make_leaf(first_emitter, num_emitters);
740 }
741 else {
742 new_node.make_distant(first_emitter, num_emitters);
743 }
744 }
745 else {
746 assert(node->is_inner());
747 assert(new_node.is_inner());
748
749 /* Specialize inner node. */
750 LightTreeNode *left_node = node->get_inner().children[LightTree::left].get();
751 LightTreeNode *right_node = node->get_inner().children[LightTree::right].get();
752
753 /* Skip nodes that have only one child. We have a single bit trail for each
754 * primitive, bit_skip is incremented in the child node to skip the bit for
755 * this parent node. */
756 LightTreeNode *only_node = nullptr;
757 if (!(left_node->light_link.set_membership & light_link_mask)) {
758 only_node = right_node;
759 }
760 else if (!(right_node->light_link.set_membership & light_link_mask)) {
761 only_node = left_node;
762 }
763 if (only_node) {
764 const auto [only_index, only_measure] = light_tree_specialize_nodes_flatten(
765 flatten, only_node, light_link_mask, depth + 1, knodes, next_node_index);
766
767 assert(only_index != -1);
768 knodes[only_index].bit_skip++;
769 return std::make_pair(only_index, only_measure);
770 }
771
772 /* Create inner node. */
773 node_index = next_node_index++;
774
775 const auto [left_index, left_measure] = light_tree_specialize_nodes_flatten(
776 flatten, left_node, light_link_mask, depth + 1, knodes, next_node_index);
777 const auto [right_index, right_measure] = light_tree_specialize_nodes_flatten(
778 flatten, right_node, light_link_mask, depth + 1, knodes, next_node_index);
779
780 new_node.measure = left_measure;
781 new_node.measure.add(right_measure);
782
783 left_child = left_index;
784 right_child = right_index;
785 }
786
787 /* Convert to kernel node. */
788 if (knodes.size() <= node_index) {
789 knodes.resize(node_index + 1);
790 }
791 light_tree_node_copy_to_device(knodes[node_index], new_node, left_child, right_child);
792
793 if (node->light_link.shareable) {
794 node->light_link.shared_node_index = node_index;
795 }
796
797 return std::make_pair(node_index, new_node.measure);
798}
799
801 DeviceScene *dscene,
802 Scene *scene,
803 Progress &progress)
804{
805 KernelIntegrator *kintegrator = &dscene->data.integrator;
806
807 if (!kintegrator->use_light_tree) {
808 return;
809 }
810
811 /* Update light tree. */
812 progress.set_status("Updating Lights", "Computing tree");
813
814 /* TODO: For now, we'll start with a smaller number of max lights in a node.
815 * More benchmarking is needed to determine what number works best. */
816 LightTree light_tree(scene, dscene, progress, 8);
817 LightTreeNode *root = light_tree.build(scene, dscene);
818 if (progress.get_cancel()) {
819 return;
820 }
821
822 /* Create arguments for recursive tree flatten. */
823 LightTreeFlatten flatten;
824 flatten.scene = scene;
825 flatten.emitters = light_tree.get_emitters();
827 /* We want to create separate arrays corresponding to triangles and lights,
828 * which will be used to index back into the light tree for PDF calculations. */
829 flatten.light_array = dscene->light_to_tree.alloc(kintegrator->num_lights);
830 flatten.mesh_array = dscene->object_to_tree.alloc(scene->objects.size());
831 flatten.triangle_array = dscene->triangle_to_tree.alloc(light_tree.num_triangles);
832
833 /* Allocate emitters */
834 const size_t num_emitters = light_tree.num_emitters();
835 KernelLightTreeEmitter *kemitters = dscene->light_tree_emitters.alloc(num_emitters);
836
837 /* Update integrator state. */
838 kintegrator->use_direct_light = num_emitters > 0;
839
840 /* Test if light linking is used. */
841 const bool use_light_linking = root && (light_tree.light_link_receiver_used != 1);
842 KernelLightLinkSet *klight_link_sets = dscene->data.light_link_sets;
843 memset(klight_link_sets, 0, sizeof(dscene->data.light_link_sets));
844
845 VLOG_INFO << "Use light tree with " << num_emitters << " emitters and " << light_tree.num_nodes
846 << " nodes.";
847
848 if (!use_light_linking) {
849 /* Regular light tree without linking. */
850 KernelLightTreeNode *knodes = dscene->light_tree_nodes.alloc(light_tree.num_nodes);
851
852 if (root) {
853 int next_node_index = 0;
854 light_tree_flatten(flatten, root, knodes, kemitters, next_node_index);
855 }
856 }
857 else {
858 int next_node_index = 0;
859
860 vector<KernelLightTreeNode> light_link_nodes;
861
862 /* Write primitives, and any subtrees for instances. */
863 if (root) {
864 /* Reserve enough size of all instance subtrees, then shrink back to
865 * actual number of nodes used. */
866 light_link_nodes.resize(light_tree.num_nodes);
868 flatten, root, light_link_nodes.data(), kemitters, next_node_index);
869 light_link_nodes.resize(next_node_index);
870 }
871
872 /* Specialized light trees for linking. */
873 for (uint64_t tree_index = 0; tree_index < LIGHT_LINK_SET_MAX; tree_index++) {
874 const uint64_t tree_mask = uint64_t(1) << tree_index;
875 if (!(light_tree.light_link_receiver_used & tree_mask)) {
876 continue;
877 }
878
879 if (root) {
880 klight_link_sets[tree_index].light_tree_root =
882 flatten, root, tree_mask, 0, light_link_nodes, next_node_index)
883 .first;
884 }
885 }
886
887 /* Allocate and copy nodes into device array. */
888 KernelLightTreeNode *knodes = dscene->light_tree_nodes.alloc(light_link_nodes.size());
889 memcpy(knodes, light_link_nodes.data(), light_link_nodes.size() * sizeof(*knodes));
890
891 VLOG_INFO << "Specialized light tree for light linking, with "
892 << light_link_nodes.size() - light_tree.num_nodes << " additional nodes.";
893 }
894
895 /* Copy arrays to device. */
902}
903
904static void background_cdf(
905 int start, int end, int res_x, int res_y, const vector<float3> *pixels, float2 *cond_cdf)
906{
907 int cdf_width = res_x + 1;
908 /* Conditional CDFs (rows, U direction). */
909 for (int i = start; i < end; i++) {
910 float sin_theta = sinf(M_PI_F * (i + 0.5f) / res_y);
911 float3 env_color = (*pixels)[i * res_x];
912 float ave_luminance = average(fabs(env_color));
913
914 cond_cdf[i * cdf_width].x = ave_luminance * sin_theta;
915 cond_cdf[i * cdf_width].y = 0.0f;
916
917 for (int j = 1; j < res_x; j++) {
918 env_color = (*pixels)[i * res_x + j];
919 ave_luminance = average(fabs(env_color));
920
921 cond_cdf[i * cdf_width + j].x = ave_luminance * sin_theta;
922 cond_cdf[i * cdf_width + j].y = cond_cdf[i * cdf_width + j - 1].y +
923 cond_cdf[i * cdf_width + j - 1].x / res_x;
924 }
925
926 const float cdf_total = cond_cdf[i * cdf_width + res_x - 1].y +
927 cond_cdf[i * cdf_width + res_x - 1].x / res_x;
928
929 /* stuff the total into the brightness value for the last entry, because
930 * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
931 cond_cdf[i * cdf_width + res_x].x = cdf_total;
932
933 if (cdf_total > 0.0f) {
934 const float cdf_total_inv = 1.0f / cdf_total;
935 for (int j = 1; j < res_x; j++) {
936 cond_cdf[i * cdf_width + j].y *= cdf_total_inv;
937 }
938 }
939
940 cond_cdf[i * cdf_width + res_x].y = 1.0f;
941 }
942}
943
945 DeviceScene *dscene,
946 Scene *scene,
947 Progress &progress)
948{
949 KernelIntegrator *kintegrator = &dscene->data.integrator;
950 KernelBackground *kbackground = &dscene->data.background;
951 Light *background_light = NULL;
952
953 bool background_mis = false;
954
955 /* find background light */
956 foreach (Light *light, scene->lights) {
957 if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) {
958 background_light = light;
959 background_mis |= light->use_mis;
960 }
961 }
962
963 kbackground->portal_weight = kintegrator->num_portals > 0 ? 1.0f : 0.0f;
964 kbackground->map_weight = background_mis ? 1.0f : 0.0f;
965 kbackground->sun_weight = 0.0f;
966
967 /* no background light found, signal renderer to skip sampling */
968 if (!background_light || !background_light->is_enabled) {
969 kbackground->map_res_x = 0;
970 kbackground->map_res_y = 0;
971 kbackground->use_mis = (kbackground->portal_weight > 0.0f);
972 return;
973 }
974
975 progress.set_status("Updating Lights", "Importance map");
976
977 int2 environment_res = make_int2(0, 0);
978 Shader *shader = scene->background->get_shader(scene);
979 int num_suns = 0;
980 float sun_average_radiance = 0.0f;
981 foreach (ShaderNode *node, shader->graph->nodes) {
982 if (node->type == EnvironmentTextureNode::get_node_type()) {
984 if (!env->handle.empty()) {
985 ImageMetaData metadata = env->handle.metadata();
986 environment_res.x = max(environment_res.x, (int)metadata.width);
987 environment_res.y = max(environment_res.y, (int)metadata.height);
988 }
989 }
990 if (node->type == SkyTextureNode::get_node_type()) {
991 SkyTextureNode *sky = (SkyTextureNode *)node;
992 if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) {
993 /* Ensure that the input coordinates aren't transformed before they reach the node.
994 * If that is the case, the logic used for sampling the sun's location does not work
995 * and we have to fall back to map-based sampling. */
996 const ShaderInput *vec_in = sky->input("Vector");
997 if (vec_in && vec_in->link && vec_in->link->parent) {
998 ShaderNode *vec_src = vec_in->link->parent;
999 if ((vec_src->type != TextureCoordinateNode::get_node_type()) ||
1000 (vec_in->link != vec_src->output("Generated")))
1001 {
1002 environment_res.x = max(environment_res.x, 4096);
1003 environment_res.y = max(environment_res.y, 2048);
1004 continue;
1005 }
1006 }
1007
1008 /* Determine sun direction from lat/long and texture mapping. */
1009 float latitude = sky->get_sun_elevation();
1010 float longitude = sky->get_sun_rotation() + M_PI_2_F;
1011 float3 sun_direction = make_float3(
1012 cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude));
1014 sun_direction = transform_direction(&sky_transform, sun_direction);
1015
1016 /* Pack sun direction and size. */
1017 float half_angle = sky->get_sun_size() * 0.5f;
1018 kbackground->sun = make_float4(
1019 sun_direction.x, sun_direction.y, sun_direction.z, half_angle);
1020
1021 /* empirical value */
1022 kbackground->sun_weight = 4.0f;
1023 sun_average_radiance = sky->get_sun_average_radiance();
1024 environment_res.x = max(environment_res.x, 512);
1025 environment_res.y = max(environment_res.y, 256);
1026 num_suns++;
1027 }
1028 }
1029 }
1030
1031 /* If there's more than one sun, fall back to map sampling instead. */
1032 kbackground->use_sun_guiding = (num_suns == 1);
1033 if (!kbackground->use_sun_guiding) {
1034 kbackground->sun_weight = 0.0f;
1035 environment_res.x = max(environment_res.x, 4096);
1036 environment_res.y = max(environment_res.y, 2048);
1037 }
1038
1039 /* Enable MIS for background sampling if any strategy is active. */
1040 kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
1041 kbackground->sun_weight) > 0.0f;
1042
1043 /* get the resolution from the light's size (we stuff it in there) */
1044 int2 res = make_int2(background_light->map_resolution, background_light->map_resolution / 2);
1045 /* If the resolution isn't set manually, try to find an environment texture. */
1046 if (res.x == 0) {
1047 res = environment_res;
1048 if (res.x > 0 && res.y > 0) {
1049 VLOG_INFO << "Automatically set World MIS resolution to " << res.x << " by " << res.y
1050 << "\n";
1051 }
1052 }
1053 /* If it's still unknown, just use the default. */
1054 if (res.x == 0 || res.y == 0) {
1055 res = make_int2(1024, 512);
1056 VLOG_INFO << "Setting World MIS resolution to default\n";
1057 }
1058 kbackground->map_res_x = res.x;
1059 kbackground->map_res_y = res.y;
1060
1061 vector<float3> pixels;
1062 shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
1063
1064 if (progress.get_cancel()) {
1065 return;
1066 }
1067
1068 /* build row distributions and column distribution for the infinite area environment light */
1069 int cdf_width = res.x + 1;
1070 float2 *marg_cdf = dscene->light_background_marginal_cdf.alloc(res.y + 1);
1071 float2 *cond_cdf = dscene->light_background_conditional_cdf.alloc(cdf_width * res.y);
1072
1073 double time_start = time_dt();
1074
1075 /* Create CDF in parallel. */
1076 const int rows_per_task = divide_up(10240, res.x);
1077 parallel_for(blocked_range<size_t>(0, res.y, rows_per_task),
1078 [&](const blocked_range<size_t> &r) {
1079 background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
1080 });
1081
1082 /* marginal CDFs (column, V direction, sum of rows) */
1083 marg_cdf[0].x = cond_cdf[res.x].x;
1084 marg_cdf[0].y = 0.0f;
1085
1086 for (int i = 1; i < res.y; i++) {
1087 marg_cdf[i].x = cond_cdf[i * cdf_width + res.x].x;
1088 marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res.y;
1089 }
1090
1091 float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y;
1092 marg_cdf[res.y].x = cdf_total;
1093
1094 float map_average_radiance = cdf_total * M_PI_2_F;
1095 if (sun_average_radiance > 0.0f) {
1096 /* The weighting here is just a heuristic that was empirically determined.
1097 * The sun's average radiance is much higher than the map's average radiance,
1098 * but we don't want to weight the background light too much because
1099 * visibility is not accounted for anyway. */
1100 background_light->set_average_radiance(0.8f * map_average_radiance +
1101 0.2f * sun_average_radiance);
1102 }
1103 else {
1104 background_light->set_average_radiance(map_average_radiance);
1105 }
1106
1107 if (cdf_total > 0.0f) {
1108 for (int i = 1; i < res.y; i++) {
1109 marg_cdf[i].y /= cdf_total;
1110 }
1111 }
1112
1113 marg_cdf[res.y].y = 1.0f;
1114
1115 VLOG_WORK << "Background MIS build time " << time_dt() - time_start << "\n";
1116
1117 /* update device */
1120}
1121
1123{
1124 /* Counts lights in the scene. */
1125 size_t num_lights = 0;
1126 size_t num_portals = 0;
1127 size_t num_background_lights = 0;
1128 size_t num_distant_lights = 0;
1129 bool use_light_mis = false;
1130
1131 foreach (Light *light, scene->lights) {
1132 if (light->is_enabled) {
1133 num_lights++;
1134
1135 if (light->light_type == LIGHT_DISTANT) {
1136 num_distant_lights++;
1137 }
1138 else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) {
1139 use_light_mis |= (light->size > 0.0f && light->use_mis);
1140 }
1141 else if (light->light_type == LIGHT_AREA) {
1142 use_light_mis |= light->use_mis;
1143 }
1144 else if (light->light_type == LIGHT_BACKGROUND) {
1145 num_distant_lights++;
1146 num_background_lights++;
1147 }
1148 }
1149 if (light->is_portal) {
1150 num_portals++;
1151 }
1152 }
1153
1154 /* Update integrator settings. */
1155 KernelIntegrator *kintegrator = &dscene->data.integrator;
1156 kintegrator->use_light_tree = scene->integrator->get_use_light_tree();
1157 kintegrator->num_lights = num_lights;
1158 kintegrator->num_distant_lights = num_distant_lights;
1159 kintegrator->num_background_lights = num_background_lights;
1160 kintegrator->use_light_mis = use_light_mis;
1161
1162 kintegrator->num_portals = num_portals;
1163 kintegrator->portal_offset = num_lights;
1164
1165 /* Create KernelLight for every portal and enabled light in the scene. */
1166 KernelLight *klights = dscene->lights.alloc(num_lights + num_portals);
1167
1168 int light_index = 0;
1169 int portal_index = num_lights;
1170
1171 foreach (Light *light, scene->lights) {
1172 /* Consider moving portals update to their own function
1173 * keeping this one more manageable. */
1174 if (light->is_portal) {
1175 assert(light->light_type == LIGHT_AREA);
1176
1177 float3 extentu = light->get_axisu() * (light->sizeu * light->size);
1178 float3 extentv = light->get_axisv() * (light->sizev * light->size);
1179
1180 float len_u, len_v;
1181 float3 axis_u = normalize_len(extentu, &len_u);
1182 float3 axis_v = normalize_len(extentv, &len_v);
1183 float area = len_u * len_v;
1184 if (light->ellipse) {
1185 area *= M_PI_4_F;
1186 }
1187 float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
1188 if (light->ellipse) {
1189 /* Negative inverse area indicates ellipse. */
1190 invarea = -invarea;
1191 }
1192
1193 float3 dir = safe_normalize(light->get_dir());
1194
1195 klights[portal_index].co = light->get_co();
1196 klights[portal_index].area.axis_u = axis_u;
1197 klights[portal_index].area.len_u = len_u;
1198 klights[portal_index].area.axis_v = axis_v;
1199 klights[portal_index].area.len_v = len_v;
1200 klights[portal_index].area.invarea = invarea;
1201 klights[portal_index].area.dir = dir;
1202 klights[portal_index].tfm = light->tfm;
1203 klights[portal_index].itfm = transform_inverse(light->tfm);
1204
1205 portal_index++;
1206 continue;
1207 }
1208
1209 if (!light->is_enabled) {
1210 continue;
1211 }
1212
1213 Shader *shader = (light->shader) ? light->shader : scene->default_light;
1214 int shader_id = scene->shader_manager->get_shader_id(shader);
1215 float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF);
1216
1217 if (!light->cast_shadow) {
1218 shader_id &= ~SHADER_CAST_SHADOW;
1219 }
1220
1221 if (!light->use_camera) {
1222 shader_id |= SHADER_EXCLUDE_CAMERA;
1223 }
1224 if (!light->use_diffuse) {
1225 shader_id |= SHADER_EXCLUDE_DIFFUSE;
1226 }
1227 if (!light->use_glossy) {
1228 shader_id |= SHADER_EXCLUDE_GLOSSY;
1229 }
1230 if (!light->use_transmission) {
1231 shader_id |= SHADER_EXCLUDE_TRANSMIT;
1232 }
1233 if (!light->use_scatter) {
1234 shader_id |= SHADER_EXCLUDE_SCATTER;
1235 }
1236 if (!light->is_shadow_catcher) {
1237 shader_id |= SHADER_EXCLUDE_SHADOW_CATCHER;
1238 }
1239
1240 klights[light_index].type = light->light_type;
1241 klights[light_index].strength[0] = light->strength.x;
1242 klights[light_index].strength[1] = light->strength.y;
1243 klights[light_index].strength[2] = light->strength.z;
1244
1245 if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) {
1246 shader_id &= ~SHADER_AREA_LIGHT;
1247
1248 float radius = light->size;
1249 float invarea = (radius == 0.0f) ? 1.0f / 4.0f :
1250 (light->normalize) ? 1.0f / (4.0f * M_PI_F * radius * radius) :
1251 1.0f;
1252
1253 /* Convert radiant flux to radiance or radiant intensity. */
1254 float eval_fac = invarea * M_1_PI_F;
1255
1256 if (light->use_mis && radius > 0.0f) {
1257 shader_id |= SHADER_USE_MIS;
1258 }
1259
1260 klights[light_index].co = light->get_co();
1261 klights[light_index].spot.radius = radius;
1262 klights[light_index].spot.eval_fac = eval_fac;
1263 klights[light_index].spot.is_sphere = light->get_is_sphere() && radius != 0.0f;
1264 }
1265 else if (light->light_type == LIGHT_DISTANT) {
1266 shader_id &= ~SHADER_AREA_LIGHT;
1267
1268 float3 dir = safe_normalize(light->get_dir());
1269 float angle = light->angle / 2.0f;
1270
1271 if (light->use_mis && angle > 0.0f) {
1272 shader_id |= SHADER_USE_MIS;
1273 }
1274
1275 const float one_minus_cosangle = 2.0f * sqr(sinf(0.5f * angle));
1276 const float pdf = (angle > 0.0f) ? (M_1_2PI_F / one_minus_cosangle) : 1.0f;
1277
1278 klights[light_index].co = dir;
1279 klights[light_index].distant.angle = angle;
1280 klights[light_index].distant.one_minus_cosangle = one_minus_cosangle;
1281 klights[light_index].distant.pdf = pdf;
1282 klights[light_index].distant.eval_fac = (light->normalize && angle > 0) ?
1283 M_1_PI_F / sqr(sinf(angle)) :
1284 1.0f;
1285 klights[light_index].distant.half_inv_sin_half_angle = (angle == 0.0f) ?
1286 0.0f :
1287 0.5f / sinf(0.5f * angle);
1288 }
1289 else if (light->light_type == LIGHT_BACKGROUND) {
1290 uint visibility = scene->background->get_visibility();
1291
1292 dscene->data.background.light_index = light_index;
1293
1294 shader_id &= ~SHADER_AREA_LIGHT;
1295 shader_id |= SHADER_USE_MIS;
1296
1297 if (!(visibility & PATH_RAY_DIFFUSE)) {
1298 shader_id |= SHADER_EXCLUDE_DIFFUSE;
1299 }
1300 if (!(visibility & PATH_RAY_GLOSSY)) {
1301 shader_id |= SHADER_EXCLUDE_GLOSSY;
1302 }
1303 if (!(visibility & PATH_RAY_TRANSMIT)) {
1304 shader_id |= SHADER_EXCLUDE_TRANSMIT;
1305 }
1306 if (!(visibility & PATH_RAY_VOLUME_SCATTER)) {
1307 shader_id |= SHADER_EXCLUDE_SCATTER;
1308 }
1309 }
1310 else if (light->light_type == LIGHT_AREA) {
1311 float light_size = light->size;
1312 float3 extentu = light->get_axisu() * (light->sizeu * light_size);
1313 float3 extentv = light->get_axisv() * (light->sizev * light_size);
1314
1315 float len_u, len_v;
1316 float3 axis_u = normalize_len(extentu, &len_u);
1317 float3 axis_v = normalize_len(extentv, &len_v);
1318 float area = len_u * len_v;
1319 if (light->ellipse) {
1320 area *= M_PI_4_F;
1321 }
1322 float invarea = (light->normalize && area != 0.0f) ? 1.0f / area : 1.0f;
1323 if (light->ellipse) {
1324 /* Negative inverse area indicates ellipse. */
1325 invarea = -invarea;
1326 }
1327
1328 const float half_spread = 0.5f * light->spread;
1329 const float tan_half_spread = light->spread == M_PI_F ? FLT_MAX : tanf(half_spread);
1330 /* Normalization computed using:
1331 * integrate cos(x) * (1 - tan(x) / tan(a)) * sin(x) from x = 0 to a, a being half_spread.
1332 * Divided by tan_half_spread to simplify the attenuation computation in `area.h`. */
1333 /* Using third-order Taylor expansion at small angles for better accuracy. */
1334 const float normalize_spread = half_spread > 0.05f ? 1.0f / (tan_half_spread - half_spread) :
1335 3.0f / powf(half_spread, 3.0f);
1336
1337 float3 dir = safe_normalize(light->get_dir());
1338
1339 if (light->use_mis && area != 0.0f && light->spread > 0.0f) {
1340 shader_id |= SHADER_USE_MIS;
1341 }
1342
1343 klights[light_index].co = light->get_co();
1344 klights[light_index].area.axis_u = axis_u;
1345 klights[light_index].area.len_u = len_u;
1346 klights[light_index].area.axis_v = axis_v;
1347 klights[light_index].area.len_v = len_v;
1348 klights[light_index].area.invarea = invarea;
1349 klights[light_index].area.dir = dir;
1350 klights[light_index].area.tan_half_spread = tan_half_spread;
1351 klights[light_index].area.normalize_spread = normalize_spread;
1352 }
1353 if (light->light_type == LIGHT_SPOT) {
1354 const float cos_half_spot_angle = cosf(light->spot_angle * 0.5f);
1355 const float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
1356 const float tan_half_spot_angle = tanf(light->spot_angle * 0.5f);
1357
1358 const float len_w_sq = len_squared(light->get_dir());
1359 const float len_u_sq = len_squared(light->get_axisu());
1360 const float len_v_sq = len_squared(light->get_axisv());
1361 const float tan_sq = sqr(tan_half_spot_angle);
1362
1363 klights[light_index].spot.dir = safe_normalize(light->get_dir());
1364 klights[light_index].spot.cos_half_spot_angle = cos_half_spot_angle;
1365 klights[light_index].spot.half_cot_half_spot_angle = 0.5f / tan_half_spot_angle;
1366 klights[light_index].spot.spot_smooth = spot_smooth;
1367 /* Choose the angle which spans a larger cone. */
1368 klights[light_index].spot.cos_half_larger_spread = inversesqrtf(
1369 1.0f + tan_sq * fmaxf(len_u_sq, len_v_sq) / len_w_sq);
1370 /* radius / sin(half_angle_small) */
1371 klights[light_index].spot.ray_segment_dp =
1372 light->size * sqrtf(1.0f + len_w_sq / (tan_sq * fminf(len_u_sq, len_v_sq)));
1373 }
1374
1375 klights[light_index].shader_id = shader_id;
1376
1377 klights[light_index].max_bounces = light->max_bounces;
1378 klights[light_index].random = random;
1379 klights[light_index].use_caustics = light->use_caustics;
1380
1381 klights[light_index].tfm = light->tfm;
1382 klights[light_index].itfm = transform_inverse(light->tfm);
1383
1384 /* Light group. */
1385 if (light->light_type == LIGHT_BACKGROUND) {
1386 klights[light_index].lightgroup = dscene->data.background.lightgroup;
1387 }
1388 else {
1389 auto it = scene->lightgroups.find(light->lightgroup);
1390 if (it != scene->lightgroups.end()) {
1391 klights[light_index].lightgroup = it->second;
1392 }
1393 else {
1394 klights[light_index].lightgroup = LIGHTGROUP_NONE;
1395 }
1396 }
1397
1398 klights[light_index].light_set_membership = light->light_set_membership;
1399 klights[light_index].shadow_set_membership = light->shadow_set_membership;
1400
1401 light_index++;
1402 }
1403
1404 VLOG_INFO << "Number of lights sent to the device: " << num_lights;
1405
1406 dscene->lights.copy_to_device();
1407}
1408
1410 DeviceScene *dscene,
1411 Scene *scene,
1412 Progress &progress)
1413{
1414 if (!need_update()) {
1415 return;
1416 }
1417
1418 scoped_callback_timer timer([scene](double time) {
1419 if (scene->update_stats) {
1420 scene->update_stats->light.times.add_entry({"device_update", time});
1421 }
1422 });
1423
1424 VLOG_INFO << "Total " << scene->lights.size() << " lights.";
1425
1426 /* Detect which lights are enabled, also determines if we need to update the background. */
1427 test_enabled_lights(scene);
1428
1429 device_free(device, dscene, need_update_background);
1430
1431 device_update_lights(dscene, scene);
1432 if (progress.get_cancel()) {
1433 return;
1434 }
1435
1436 if (need_update_background) {
1437 device_update_background(device, dscene, scene, progress);
1438 if (progress.get_cancel()) {
1439 return;
1440 }
1441 }
1442
1443 device_update_distribution(device, dscene, scene, progress);
1444 if (progress.get_cancel()) {
1445 return;
1446 }
1447
1448 device_update_tree(device, dscene, scene, progress);
1449 if (progress.get_cancel()) {
1450 return;
1451 }
1452
1453 device_update_ies(dscene);
1454 if (progress.get_cancel()) {
1455 return;
1456 }
1457
1458 update_flags = UPDATE_NONE;
1459 need_update_background = false;
1460}
1461
1462void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background)
1463{
1464 dscene->light_tree_nodes.free();
1465 dscene->light_tree_emitters.free();
1466 dscene->light_to_tree.free();
1467 dscene->object_to_tree.free();
1468 dscene->object_lookup_offset.free();
1469 dscene->triangle_to_tree.free();
1470
1471 dscene->light_distribution.free();
1472 dscene->lights.free();
1473 if (free_background) {
1476 }
1477 dscene->ies_lights.free();
1478}
1479
1481{
1482 update_flags |= flag;
1483}
1484
1486{
1487 return update_flags != UPDATE_NONE;
1488}
1489
1490int LightManager::add_ies_from_file(const string &filename)
1491{
1492 string content;
1493
1494 /* If the file can't be opened, call with an empty line */
1495 if (filename.empty() || !path_read_text(filename.c_str(), content)) {
1496 content = "\n";
1497 }
1498
1499 return add_ies(content);
1500}
1501
1502int LightManager::add_ies(const string &content)
1503{
1504 uint hash = hash_string(content.c_str());
1505
1506 thread_scoped_lock ies_lock(ies_mutex);
1507
1508 /* Check whether this IES already has a slot. */
1509 size_t slot;
1510 for (slot = 0; slot < ies_slots.size(); slot++) {
1511 if (ies_slots[slot]->hash == hash) {
1512 ies_slots[slot]->users++;
1513 return slot;
1514 }
1515 }
1516
1517 /* Try to find an empty slot for the new IES. */
1518 for (slot = 0; slot < ies_slots.size(); slot++) {
1519 if (ies_slots[slot]->users == 0 && ies_slots[slot]->hash == 0) {
1520 break;
1521 }
1522 }
1523
1524 /* If there's no free slot, add one. */
1525 if (slot == ies_slots.size()) {
1526 ies_slots.push_back(new IESSlot());
1527 }
1528
1529 ies_slots[slot]->ies.load(content);
1530 ies_slots[slot]->users = 1;
1531 ies_slots[slot]->hash = hash;
1532
1535
1536 return slot;
1537}
1538
1540{
1541 thread_scoped_lock ies_lock(ies_mutex);
1542
1543 if (slot < 0 || slot >= ies_slots.size()) {
1544 assert(false);
1545 return;
1546 }
1547
1548 assert(ies_slots[slot]->users > 0);
1549 ies_slots[slot]->users--;
1550
1551 /* If the slot has no more users, update the device to remove it. */
1552 if (ies_slots[slot]->users == 0) {
1555 }
1556}
1557
1559{
1560 /* Clear empty slots. */
1561 foreach (IESSlot *slot, ies_slots) {
1562 if (slot->users == 0) {
1563 slot->hash = 0;
1564 slot->ies.clear();
1565 }
1566 }
1567
1568 /* Shrink the slot table by removing empty slots at the end. */
1569 int slot_end;
1570 for (slot_end = ies_slots.size(); slot_end; slot_end--) {
1571 if (ies_slots[slot_end - 1]->users > 0) {
1572 /* If the preceding slot has users, we found the new end of the table. */
1573 break;
1574 }
1575 else {
1576 /* The slot will be past the new end of the table, so free it. */
1577 delete ies_slots[slot_end - 1];
1578 }
1579 }
1580 ies_slots.resize(slot_end);
1581
1582 if (ies_slots.size() > 0) {
1583 int packed_size = 0;
1584 foreach (IESSlot *slot, ies_slots) {
1585 packed_size += slot->ies.packed_size();
1586 }
1587
1588 /* ies_lights starts with an offset table that contains the offset of every slot,
1589 * or -1 if the slot is invalid.
1590 * Following that table, the packed valid IES lights are stored. */
1591 float *data = dscene->ies_lights.alloc(ies_slots.size() + packed_size);
1592
1593 int offset = ies_slots.size();
1594 for (int i = 0; i < ies_slots.size(); i++) {
1595 int size = ies_slots[i]->ies.packed_size();
1596 if (size > 0) {
1597 data[i] = __int_as_float(offset);
1598 ies_slots[i]->ies.pack(data + offset);
1599 offset += size;
1600 }
1601 else {
1602 data[i] = __int_as_float(-1);
1603 }
1604 }
1605
1606 dscene->ies_lights.copy_to_device();
1607 }
1608}
1609
unsigned int uint
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float sin_theta(const float3 w)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
device_vector< KernelLightTreeEmitter > light_tree_emitters
Definition devicescene.h:73
device_vector< KernelLightTreeNode > light_tree_nodes
Definition devicescene.h:72
device_vector< uint > object_to_tree
Definition devicescene.h:75
device_vector< float2 > light_background_marginal_cdf
Definition devicescene.h:68
device_vector< uint > object_lookup_offset
Definition devicescene.h:76
device_vector< float > ies_lights
Definition devicescene.h:93
device_vector< float2 > light_background_conditional_cdf
Definition devicescene.h:69
device_vector< KernelLightDistribution > light_distribution
Definition devicescene.h:66
device_vector< uint > triangle_to_tree
Definition devicescene.h:77
KernelData data
Definition devicescene.h:95
device_vector< uint > light_to_tree
Definition devicescene.h:74
device_vector< KernelLight > lights
Definition devicescene.h:67
virtual void const_copy_to(const char *name, void *host, size_t size)=0
bool transform_applied
int packed_size()
Definition ies.cpp:38
void clear()
Definition ies.cpp:31
bool empty() const
ImageMetaData metadata()
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
void device_update_tree(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
int add_ies_from_file(const string &filename)
void device_update_lights(DeviceScene *dscene, Scene *scene)
void test_enabled_lights(Scene *scene)
uint32_t update_flags
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
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
thread_mutex ies_mutex
bool has_background_light(Scene *scene)
void tag_update(Scene *scene, uint32_t flag)
bool last_background_enabled
std::atomic< int > num_nodes
Definition light_tree.h:394
const LightTreeEmitter * get_emitters() const
Definition light_tree.h:424
uint64_t light_link_receiver_used
Definition light_tree.h:398
size_t num_triangles
Definition light_tree.h:395
LightTreeNode * build(Scene *scene, DeviceScene *dscene)
size_t num_emitters()
Definition light_tree.h:419
bool get_cancel() const
Definition progress.h:93
void set_status(const string &status_, const string &substatus_="")
Definition progress.h:263
void set_error(const string &error_message_)
Definition progress.h:113
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)
ShaderOutput * link
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
ShaderNode * parent
float3 emission_estimate
float get_sun_size()
float get_sun_average_radiance()
Transform compute_transform()
TextureMapping tex_mapping
T * alloc(size_t width, size_t height=0, size_t depth=0)
#define sinf(x)
#define cosf(x)
#define tanf(x)
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
#define fmaxf(x, y)
#define fminf(x, y)
#define __int_as_float(x)
ccl_device_forceinline int2 make_int2(const int x, const int y)
#define sqrtf(x)
int users
draw_view in_light_buf[] float
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:532
@ NODE_SKY_NISHITA
#define LIGHT_LINK_SET_MAX
LightTreeNodeType
#define PRIM_NONE
@ PATH_RAY_TRANSMIT
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_GLOSSY
@ PATH_RAY_DIFFUSE
@ PATH_RAY_CAMERA
#define OBJECT_NONE
@ EMISSION_SAMPLING_NONE
@ SHADER_EXCLUDE_SHADOW_CATCHER
@ SHADER_EXCLUDE_CAMERA
@ SHADER_EXCLUDE_DIFFUSE
@ SHADER_USE_MIS
@ SHADER_EXCLUDE_SCATTER
@ SHADER_EXCLUDE_GLOSSY
@ SHADER_EXCLUDE_TRANSMIT
#define LIGHTGROUP_NONE
#define LIGHT_LINK_MASK_ALL
@ LIGHT_AREA
@ LIGHT_DISTANT
@ LIGHT_SPOT
@ LIGHT_BACKGROUND
@ LIGHT_POINT
#define VLOG_INFO
Definition log.h:72
#define VLOG_WORK
Definition log.h:75
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float average(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float2 normalize_len(const float2 a, ccl_private float *t)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
#define M_PI_F
Definition mikk_util.hh:15
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:200
#define SOCKET_INT(name, ui_name, default_value,...)
Definition node_type.h:194
#define SOCKET_NODE(name, ui_name, node_type,...)
Definition node_type.h:229
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition node_type.h:214
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition node_type.h:196
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define SOCKET_COLOR(name, ui_name, default_value,...)
Definition node_type.h:202
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:192
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition node_type.h:212
#define SOCKET_UINT64(name, ui_name, default_value,...)
Definition node_type.h:198
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:216
#define hash
Definition noise.c:154
bool path_read_text(const string &path, string &text)
Definition path.cpp:739
static void light_tree_emitters_copy_and_flatten(LightTreeFlatten &flatten, const LightTreeNode *node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static int light_tree_flatten(LightTreeFlatten &flatten, const LightTreeNode *node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static void light_tree_leaf_emitters_copy_and_flatten(LightTreeFlatten &flatten, const LightTreeNode &node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static void background_cdf(int start, int end, int res_x, int res_y, const vector< float3 > *pixels, float2 *cond_cdf)
static void light_tree_node_copy_to_device(KernelLightTreeNode &knode, const LightTreeNode &node, const int left_child, const int right_child)
static CCL_NAMESPACE_BEGIN void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector< float3 > &pixels, Progress &progress)
static std::pair< int, LightTreeMeasure > light_tree_specialize_nodes_flatten(const LightTreeFlatten &flatten, LightTreeNode *node, const uint64_t light_link_mask, const int depth, vector< KernelLightTreeNode > &knodes, int &next_node_index)
@ SHADER_EVAL_BACKGROUND
Definition shader_eval.h:20
#define M_PI_2_F
Definition sky_float3.h:20
#define FLT_MAX
Definition stdcycles.h:14
unsigned int uint32_t
Definition stdint.h:80
unsigned __int64 uint64_t
Definition stdint.h:90
packed_float3 axis_u
packed_float3 axis_v
packed_float3 dir
struct KernelLightTreeEmitter::@1445::@1448 light
struct KernelLightTreeEmitter::@1445::@1447 triangle
EmissionSampling emission_sampling
struct KernelLightTreeEmitter::@1445::@1449 mesh
struct KernelLightTreeNode::@1440::@1444 instance
struct KernelLightTreeNode::@1440::@1442 leaf
LightTreeNodeType type
struct KernelLightTreeNode::@1440::@1443 inner
uint64_t light_set_membership
Transform itfm
uint64_t shadow_set_membership
float strength[3]
KernelSpotLight spot
Transform tfm
packed_float3 co
KernelDistantLight distant
KernelAreaLight area
float half_cot_half_spot_angle
packed_float3 dir
float cos_half_larger_spread
__forceinline bool is_mesh() const
Definition light_tree.h:197
__forceinline bool is_triangle() const
Definition light_tree.h:202
unique_ptr< LightTreeNode > root
Definition light_tree.h:181
uint64_t light_set_membership
Definition light_tree.h:190
LightTreeMeasure measure
Definition light_tree.h:192
__forceinline bool is_light() const
Definition light_tree.h:207
const uint * object_lookup_offset
const LightTreeEmitter * emitters
std::unordered_map< LightTreeNode *, int > instances
const Scene * scene
OrientationBounds bcone
Definition light_tree.h:66
__forceinline void add(const LightTreeMeasure &measure)
Definition light_tree.h:92
unique_ptr< LightTreeNode > children[2]
Definition light_tree.h:260
__forceinline Inner & get_inner()
Definition light_tree.h:293
void make_leaf(const int first_emitter_index, const int num_emitters)
Definition light_tree.h:313
LightTreeNode * get_reference()
Definition light_tree.h:343
LightTreeMeasure measure
Definition light_tree.h:242
std::variant< Leaf, Inner, Instance > variant_type
Definition light_tree.h:267
void make_distant(const int first_emitter_index, const int num_emitters)
Definition light_tree.h:323
__forceinline bool is_inner() const
Definition light_tree.h:362
LightTreeLightLink light_link
Definition light_tree.h:243
float3 get_axisv() const
float3 get_axisu() const
bool has_shadow_linking() const
void tag_update(Scene *scene)
float3 get_dir() const
float3 get_co() const
bool has_light_linking() const
bool has_contribution(Scene *scene)
bool valid(const float3 *verts) const
void insert(const char *x, int y)
Definition node_enum.h:21
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition graph/node.h:178
void dereference_all_used_nodes()
bool is_modified() const
vector< Object * > objects
Definition scene.h:131
float x
float y
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
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:30
CCL_NAMESPACE_BEGIN double time_dt()
Definition time.cpp:36
ccl_device_inline Transform transform_identity()
Definition transform.h:296
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
Definition transform.h:326
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:423
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
Definition transform.h:94
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63
float max
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN 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:584
ccl_device_inline float sqr(float a)
Definition util/math.h:782
ccl_device_inline float inversesqrtf(float f)
Definition util/math.h:711
ccl_device_inline size_t divide_up(size_t x, size_t y)
Definition util/types.h:53
wmTimer * timer
uint8_t flag
Definition wm_window.cc:138