Blender V4.5
tree.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* This code implements a modified version of the paper [Importance Sampling of Many Lights with
6 * Adaptive Tree Splitting](https://fpsunflower.github.io/ckulla/data/many-lights-hpg2018.pdf)
7 * by Alejandro Conty Estevez and Christopher Kulla.
8 * The original paper traverses both children when the variance of a node is too high (called
9 * splitting). However, Cycles does not support multiple lights per shading point. Therefore, we
10 * adjust the importance computation: instead of using a conservative measure (i.e., the maximal
11 * possible contribution a node could make to a shading point) as in the paper, we additionally
12 * compute the minimal possible contribution and choose uniformly between these two measures. Also,
13 * support for distant lights is added, which is not included in the paper.
14 */
15
16#pragma once
17
18#include "kernel/light/area.h"
20#include "kernel/light/common.h"
22#include "kernel/light/point.h"
23#include "kernel/light/spot.h"
25
26#include "util/math_fast.h"
27
29
30/* Consine of the angle subtended by the smallest enclosing sphere of the node bounding box. */
32 const float3 centroid,
33 const float3 P)
34{
35 const float distance_to_center_sq = len_squared(P - centroid);
36 const float radius_sq = len_squared(bbox.max - centroid);
37
38 /* If P is inside the bounding sphere, `theta_u` covers the whole sphere and return -1.0
39 * Otherwise compute cos(theta_u) by substituting our values into the cos_from_sin() formula on
40 * the basis that `sin(theta_u) = radius / distance_to_center`. */
41 return (distance_to_center_sq <= radius_sq) ?
42 -1.0f :
43 safe_sqrtf(1.0f - (radius_sq / distance_to_center_sq));
44}
45
46/* Compute vector v as in Fig .8. P_v is the corresponding point along the ray. */
48 const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t)
49{
50 const float3 unnormalized_v0 = P - centroid;
51 const float3 unnormalized_v1 = unnormalized_v0 + D * fminf(t, 1e12f);
52 const float3 v0 = normalize(unnormalized_v0);
53 const float3 v1 = normalize(unnormalized_v1);
54
55 const float3 o0 = v0;
56 float3 o1;
57 float3 o2;
58 make_orthonormals_tangent(o0, v1, &o1, &o2);
59
60 const float dot_o0_a = dot(o0, bcone_axis);
61 const float dot_o1_a = dot(o1, bcone_axis);
62 const float inv_len = inversesqrtf(sqr(dot_o0_a) + sqr(dot_o1_a));
63 const float cos_phi0 = dot_o0_a * inv_len;
64
65 return (dot_o1_a < 0 || dot(v0, v1) > cos_phi0) ? (dot_o0_a > dot(v1, bcone_axis) ? v0 : v1) :
66 cos_phi0 * o0 + dot_o1_a * inv_len * o1;
67}
68
70{
71 return kemitter->light.id < 0;
72}
73
75{
76 return !is_light(kemitter) && kemitter->object_id == OBJECT_NONE;
77}
78
80{
81 return !is_light(kemitter) && kemitter->object_id != OBJECT_NONE;
82}
83
85{
86 /* The distant node is also considered o leaf node. */
87 return knode->type >= LIGHT_TREE_LEAF;
88}
89
90template<bool in_volume_segment>
92 const int object_id,
94 ccl_private float3 &N_or_D,
95 ccl_private float &t)
96{
97 const int object_flag = kernel_data_fetch(object_flag, object_id);
98 if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
99#ifdef __OBJECT_MOTION__
100 Transform itfm;
101 object_fetch_transform_motion_test(kg, object_id, 0.5f, &itfm);
102#else
103 const Transform itfm = object_fetch_transform(kg, object_id, OBJECT_INVERSE_TRANSFORM);
104#endif
105 P = transform_point(&itfm, P);
106 if (in_volume_segment) {
107 /* Transform direction. */
108 const float3 D_local = transform_direction(&itfm, N_or_D);
109 float scale;
110 N_or_D = normalize_len(D_local, &scale);
111
112 t *= scale;
113 }
114 else if (!is_zero(N_or_D)) {
115 /* Transform normal. */
116 const Transform tfm = object_fetch_transform(kg, object_id, OBJECT_TRANSFORM);
117 N_or_D = normalize(transform_direction_transposed(&tfm, N_or_D));
118 }
119 }
120}
121
122/* This is the general function for calculating the importance of either a cluster or an emitter.
123 * Both of the specialized functions obtain the necessary data before calling this function. */
124template<bool in_volume_segment>
126 const bool has_transmission,
127 const float3 point_to_centroid,
128 const float cos_theta_u,
129 const KernelBoundingCone bcone,
130 const float max_distance,
131 const float min_distance,
132 const float energy,
133 const float theta_d,
134 ccl_private float &max_importance,
135 ccl_private float &min_importance)
136{
137 max_importance = 0.0f;
138 min_importance = 0.0f;
139
140 const float sin_theta_u = sin_from_cos(cos_theta_u);
141
142 /* cos(theta_i') in the paper, omitted for volume. */
143 float cos_min_incidence_angle = 1.0f;
144 float cos_max_incidence_angle = 1.0f;
145
146 if (!in_volume_segment) {
147 const float3 N = N_or_D;
148 const float cos_theta_i = has_transmission ? fabsf(dot(point_to_centroid, N)) :
149 dot(point_to_centroid, N);
150 const float sin_theta_i = sin_from_cos(cos_theta_i);
151
152 /* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */
153 cos_min_incidence_angle = cos_theta_i >= cos_theta_u ?
154 1.0f :
155 cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u;
156
157 /* If the node is guaranteed to be behind the surface we're sampling, and the surface is
158 * opaque, then we can give the node an importance of 0 as it contributes nothing to the
159 * surface. This is more accurate than the bbox test if we are calculating the importance of
160 * an emitter with radius. */
161 if (!has_transmission && cos_min_incidence_angle < 0) {
162 return;
163 }
164
165 /* cos_max_incidence_angle = cos(min{theta_i + theta_u, pi}) */
166 cos_max_incidence_angle = fmaxf(cos_theta_i * cos_theta_u - sin_theta_i * sin_theta_u, 0.0f);
167 }
168
169 float cos_theta;
170 float sin_theta;
171 if (isequal(bcone.axis, -point_to_centroid)) {
172 /* When `bcone.axis == -point_to_centroid`, dot(bcone.axis, -point_to_centroid) doesn't always
173 * return 1 due to floating point precision issues. We account for that case here. */
174 cos_theta = 1.0f;
175 sin_theta = 0.0f;
176 }
177 else {
178 cos_theta = dot(bcone.axis, -point_to_centroid);
180 }
181
182 /* cos(theta - theta_u) */
183 const float cos_theta_minus_theta_u = cos_theta * cos_theta_u + sin_theta * sin_theta_u;
184
185 float cos_theta_o;
186 float sin_theta_o;
187 fast_sincosf(bcone.theta_o, &sin_theta_o, &cos_theta_o);
188
189 /* Minimum angle an emitter's axis would form with the direction to the shading point,
190 * cos(theta') in the paper. */
191 float cos_min_outgoing_angle;
192 if ((cos_theta >= cos_theta_u) || (cos_theta_minus_theta_u >= cos_theta_o)) {
193 /* theta - theta_o - theta_u <= 0 */
194 kernel_assert((fast_acosf(cos_theta) - bcone.theta_o - fast_acosf(cos_theta_u)) < 1e-3f);
195 cos_min_outgoing_angle = 1.0f;
196 }
197 else if ((bcone.theta_o + bcone.theta_e > M_PI_F) ||
198 (cos_theta_minus_theta_u > cosf(bcone.theta_o + bcone.theta_e)))
199 {
200 /* theta' = theta - theta_o - theta_u < theta_e */
202 (fast_acosf(cos_theta) - bcone.theta_o - fast_acosf(cos_theta_u) - bcone.theta_e) < 5e-4f);
203 const float sin_theta_minus_theta_u = sin_from_cos(cos_theta_minus_theta_u);
204 cos_min_outgoing_angle = cos_theta_minus_theta_u * cos_theta_o +
205 sin_theta_minus_theta_u * sin_theta_o;
206 }
207 else {
208 /* Cluster is invisible. */
209 return;
210 }
211
212 /* TODO: find a good approximation for f_a. */
213 const float f_a = 1.0f;
214 /* Use `(theta_b - theta_a) / d` for volume, see Eq. (4) in the paper. */
215 max_importance = fabsf(f_a * cos_min_incidence_angle * energy * cos_min_outgoing_angle *
216 (in_volume_segment ? theta_d / min_distance : 1.0f / sqr(min_distance)));
217
218 /* TODO: compute proper min importance for volume. */
219 if (in_volume_segment) {
220 min_importance = 0.0f;
221 return;
222 }
223
224 /* cos(theta + theta_o + theta_u) if theta + theta_o + theta_u < theta_e, 0 otherwise */
225 float cos_max_outgoing_angle;
226 const float cos_theta_plus_theta_u = cos_theta * cos_theta_u - sin_theta * sin_theta_u;
227 if (bcone.theta_e - bcone.theta_o < 0 || cos_theta < 0 || cos_theta_u < 0 ||
228 cos_theta_plus_theta_u < fast_cosf(bcone.theta_e - bcone.theta_o))
229 {
230 min_importance = 0.0f;
231 }
232 else {
233 const float sin_theta_plus_theta_u = sin_from_cos(cos_theta_plus_theta_u);
234 cos_max_outgoing_angle = cos_theta_plus_theta_u * cos_theta_o -
235 sin_theta_plus_theta_u * sin_theta_o;
236 min_importance = fabsf(f_a * cos_max_incidence_angle * energy * cos_max_outgoing_angle /
237 sqr(max_distance));
238 }
239}
240
241template<bool in_volume_segment>
243 const ccl_global KernelLightTreeEmitter *kemitter,
244 const float3 P,
245 ccl_private float3 &centroid,
247{
248 if (is_light(kemitter)) {
249 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~(kemitter->light.id));
250 centroid = klight->co;
251
252 switch (klight->type) {
253 case LIGHT_SPOT:
254 dir = klight->spot.dir;
255 break;
256 case LIGHT_POINT:
257 /* Disk-oriented normal. */
258 dir = safe_normalize(P - centroid);
259 break;
260 case LIGHT_AREA:
261 dir = klight->area.dir;
262 break;
263 case LIGHT_BACKGROUND:
264 /* Arbitrary centroid and direction. */
265 centroid = make_float3(0.0f, 0.0f, 1.0f);
266 dir = make_float3(0.0f, 0.0f, -1.0f);
267 break;
268 case LIGHT_DISTANT:
269 dir = centroid;
270 break;
271 default:
272 return false;
273 }
274 }
275 else {
276 kernel_assert(is_triangle(kemitter));
277 const int object = kemitter->object_id;
278 float3 vertices[3];
279 triangle_vertices(kg, kemitter->triangle.id, vertices);
280 centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
281
282 const bool is_front_only = (kemitter->triangle.emission_sampling == EMISSION_SAMPLING_FRONT);
283 const bool is_back_only = (kemitter->triangle.emission_sampling == EMISSION_SAMPLING_BACK);
284 if (is_front_only || is_back_only) {
285 dir = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
286 if (is_back_only) {
287 dir = -dir;
288 }
289 const int object_flag = kernel_data_fetch(object_flag, object);
290 if ((object_flag & SD_OBJECT_TRANSFORM_APPLIED) && (object_flag & SD_OBJECT_NEGATIVE_SCALE))
291 {
292 dir = -dir;
293 }
294 }
295 else {
296 /* Double-sided: any vector in the plane. */
297 dir = safe_normalize(vertices[0] - vertices[1]);
298 }
299 }
300 return true;
301}
302
303template<bool in_volume_segment>
305 const float3 P,
306 const float3 N_or_D,
307 const float t,
308 const bool has_transmission,
309 const ccl_global KernelLightTreeNode *knode,
310 ccl_private float &max_importance,
311 ccl_private float &min_importance)
312{
313 const KernelBoundingCone bcone = knode->bcone;
314 const KernelBoundingBox bbox = knode->bbox;
315
316 float3 point_to_centroid;
317 float cos_theta_u;
318 float distance;
319 float theta_d;
320 if (knode->type == LIGHT_TREE_DISTANT) {
321 point_to_centroid = -bcone.axis;
322 cos_theta_u = fast_cosf(bcone.theta_o + bcone.theta_e);
323 distance = 1.0f;
324 /* For distant lights, the integral in Eq. (4) gives the ray length. */
325 if (t == FLT_MAX) {
326 /* In world volumes, distant lights can contribute to the lighting of the volume with
327 * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this
328 * case to give the distant light some weight, but one that isn't too high for a typical
329 * world volume use case. */
330 theta_d = 1.0f;
331 }
332 else {
333 theta_d = t;
334 }
335 }
336 else {
337 const float3 centroid = 0.5f * (bbox.min + bbox.max);
338
339 if (in_volume_segment) {
340 const float3 D = N_or_D;
341 const float closest_t = dot(centroid - P, D);
342 const float3 closest_point = P + D * clamp(closest_t, 0.0f, t);
343 /* Minimal distance of the ray to the cluster. */
344 distance = len(centroid - P - D * closest_t);
345 /* Estimate `theta_b - theta_a` using the centroid of the cluster and the complete ray
346 * segment in volume. */
347 theta_d = fast_atan2f(t - closest_t, distance) + fast_atan2f(closest_t, distance);
348 /* Vector that forms a minimal angle with the emitter centroid. */
349 point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
350 cos_theta_u = light_tree_cos_bound_subtended_angle(bbox, centroid, closest_point);
351 }
352 else {
353 const float3 N = N_or_D;
354 const float3 bbox_extent = bbox.max - centroid;
355 const bool bbox_is_visible = has_transmission |
356 (dot(N, centroid - P) + dot(fabs(N), fabs(bbox_extent)) > 0);
357
358 /* If the node is guaranteed to be behind the surface we're sampling, and the surface is
359 * opaque, then we can give the node an importance of 0 as it contributes nothing to the
360 * surface. */
361 if (!bbox_is_visible) {
362 return;
363 }
364
365 point_to_centroid = normalize_len(centroid - P, &distance);
366 cos_theta_u = light_tree_cos_bound_subtended_angle(bbox, centroid, P);
367 theta_d = 1.0f;
368 }
369 /* Clamp distance to half the radius of the cluster when splitting is disabled. */
370 distance = fmaxf(0.5f * len(centroid - bbox.max), distance);
371 }
372 /* TODO: currently max_distance = min_distance, max_importance = min_importance for the
373 * nodes. Do we need better weights for complex scenes? */
375 has_transmission,
376 point_to_centroid,
377 cos_theta_u,
378 bcone,
379 distance,
380 distance,
381 knode->energy,
382 theta_d,
383 max_importance,
384 min_importance);
385}
386
387template<bool in_volume_segment>
389 const float3 P,
390 const float3 N_or_D,
391 const float t,
392 const bool has_transmission,
393 const int emitter_index,
394 ccl_private float &max_importance,
395 ccl_private float &min_importance)
396{
397 max_importance = 0.0f;
398 min_importance = 0.0f;
399
400 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
401 emitter_index);
402
403 if (is_mesh(kemitter)) {
404 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes,
405 kemitter->mesh.node_id);
406
408 kg, P, N_or_D, t, has_transmission, knode, max_importance, min_importance);
409 return;
410 }
411
412 KernelBoundingCone bcone;
413 bcone.theta_o = kemitter->theta_o;
414 bcone.theta_e = kemitter->theta_e;
415 float cos_theta_u;
416 float theta_d = 1.0f;
417 float2 distance; /* distance.x = max_distance, distance.y = min_distance */
418 float3 centroid;
419 float3 point_to_centroid;
420 float3 P_c = P;
421
422 if (!compute_emitter_centroid_and_dir<in_volume_segment>(kg, kemitter, P, centroid, bcone.axis))
423 {
424 return;
425 }
426
427 if (in_volume_segment) {
428 const float3 D = N_or_D;
429 /* Closest point from ray to the emitter centroid. */
430 const float closest_t = dot(centroid - P, D);
431 P_c += D * clamp(closest_t, 0.0f, t);
432 const float d = len(centroid - P - D * closest_t);
433 theta_d = fast_atan2f(t - closest_t, d) + fast_atan2f(closest_t, d);
434 }
435
436 /* Early out if the emitter is guaranteed to be invisible. */
437 bool is_visible;
438 float energy = kemitter->energy;
439 if (is_triangle(kemitter)) {
441 kg, kemitter, centroid, P_c, N_or_D, bcone, cos_theta_u, distance, point_to_centroid);
442 }
443 else {
444 kernel_assert(is_light(kemitter));
445 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~(kemitter->light.id));
446 switch (klight->type) {
447 /* Function templates only modifies cos_theta_u when in_volume_segment = true. */
448 case LIGHT_SPOT:
450 klight, centroid, P_c, bcone, cos_theta_u, distance, point_to_centroid, energy);
451 break;
452 case LIGHT_POINT:
454 klight, centroid, P_c, cos_theta_u, distance, point_to_centroid);
455 bcone.theta_o = 0.0f;
456 break;
457 case LIGHT_AREA:
459 klight, centroid, P_c, N_or_D, bcone.axis, cos_theta_u, distance, point_to_centroid);
460 break;
461 case LIGHT_BACKGROUND:
463 centroid, t, cos_theta_u, distance, point_to_centroid, theta_d);
464 break;
465 case LIGHT_DISTANT:
467 centroid, bcone.theta_e, t, cos_theta_u, distance, point_to_centroid, theta_d);
468 break;
469 default:
470 return;
471 }
472 }
473
474 is_visible |= has_transmission;
475 if (!is_visible) {
476 return;
477 }
478
479 if (in_volume_segment) {
480 /* Vector that forms a minimal angle with the emitter centroid. */
481 point_to_centroid = -compute_v(centroid, P, N_or_D, bcone.axis, t);
482
483 if (is_light(kemitter)) {
484 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~(kemitter->light.id));
485 if (klight->type == LIGHT_DISTANT) {
486 /* For distant light `theta_min` is 0, but due to numerical issues this is not always true.
487 * Therefore explicitly assign `-bcone.axis` to `point_to_centroid` in this case. */
488 point_to_centroid = -bcone.axis;
489 }
490 }
491 }
492
494 has_transmission,
495 point_to_centroid,
496 cos_theta_u,
497 bcone,
498 distance.x,
499 distance.y,
500 energy,
501 theta_d,
502 max_importance,
503 min_importance);
504}
505
506template<bool in_volume_segment>
508 const float3 P,
509 const float3 N_or_D,
510 const float t,
511 const bool has_transmission,
512 const ccl_global KernelLightTreeNode *knode,
513 ccl_private float &max_importance,
514 ccl_private float &min_importance)
515{
516 max_importance = 0.0f;
517 min_importance = 0.0f;
518
519 if (knode->num_emitters == 1) {
521 P,
522 N_or_D,
523 t,
524 has_transmission,
525 knode->leaf.first_emitter,
526 max_importance,
527 min_importance);
528 }
529 else if (knode->num_emitters != 0) {
531 kg, P, N_or_D, t, has_transmission, knode, max_importance, min_importance);
532 }
533}
534
535/* Select an element from the reservoir with probability proportional to its weight.
536 * Expect `selected_index` to be initialized to -1, and stays -1 if all the weights are invalid. */
537ccl_device void sample_reservoir(const int current_index,
538 const float current_weight,
539 ccl_private int &selected_index,
540 ccl_private float &selected_weight,
541 ccl_private float &total_weight,
542 ccl_private float &rand)
543{
544 if (!(current_weight > 0.0f)) {
545 return;
546 }
547 total_weight += current_weight;
548
549 /* When `-ffast-math` is used it is possible that the threshold is almost 1 but not quite.
550 * For this case we check the first valid element explicitly (instead of relying on the threshold
551 * to be 1, giving it certain probability). */
552 if (selected_index == -1) {
553 selected_index = current_index;
554 selected_weight = current_weight;
555 /* The threshold is expected to be 1 in this case with strict mathematics, so no need to divide
556 * the rand. In fact, division in such case could lead the rand to exceed 1 because of division
557 * by something smaller than 1. */
558 return;
559 }
560
561 const float thresh = current_weight / total_weight;
562 if (rand <= thresh) {
563 selected_index = current_index;
564 selected_weight = current_weight;
565 rand = rand / thresh;
566 }
567 else {
568 rand = (rand - thresh) / (1.0f - thresh);
569 }
570
571 /* Ensure the `rand` is always within 0..1 range, which could be violated above when
572 * `-ffast-math` is used. */
573 rand = saturatef(rand);
574}
575
576/* Pick an emitter from a leaf node using reservoir sampling, keep two reservoirs for upper and
577 * lower bounds. */
578template<bool in_volume_segment>
580 ccl_private float &rand,
582 ccl_private float3 &N_or_D,
583 ccl_private float &t,
584 const bool has_transmission,
585 ccl_private int *node_index,
586 ccl_private float *pdf_factor)
587{
588 float selected_importance[2] = {0.0f, 0.0f};
589 float total_importance[2] = {0.0f, 0.0f};
590 int selected_index = -1;
591 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, *node_index);
592 *node_index = -1;
593
594 kernel_assert(knode->num_emitters <= sizeof(uint) * 8);
595 /* Mark emitters with valid importance. Used for reservoir when total minimum importance = 0. */
596 uint has_importance = 0;
597
598 const bool sample_max = (rand > 0.5f); /* Sampling using the maximum importance. */
599 if (knode->num_emitters > 1) {
600 rand = rand * 2.0f - float(sample_max);
601 }
602
603 for (int i = 0; i < knode->num_emitters; i++) {
604 int current_index = knode->leaf.first_emitter + i;
605 /* maximum importance = importance[0], minimum importance = importance[1] */
606 float importance[2];
608 kg, P, N_or_D, t, has_transmission, current_index, importance[0], importance[1]);
609
610 sample_reservoir(current_index,
611 importance[!sample_max],
612 selected_index,
613 selected_importance[!sample_max],
614 total_importance[!sample_max],
615 rand);
616 if (selected_index == current_index) {
617 selected_importance[sample_max] = importance[sample_max];
618 }
619 total_importance[sample_max] += importance[sample_max];
620
621 has_importance |= ((importance[0] > 0) << i);
622 }
623
624 if (!has_importance) {
625 return -1;
626 }
627
628 if (total_importance[1] == 0.0f) {
629 /* Uniformly sample emitters with positive maximum importance. */
630 if (sample_max) {
631 selected_importance[1] = 1.0f;
632 total_importance[1] = float(popcount(has_importance));
633 }
634 else {
635 selected_index = -1;
636 for (int i = 0; i < knode->num_emitters; i++) {
637 const int current_index = knode->leaf.first_emitter + i;
638 sample_reservoir(current_index,
639 float(has_importance & 1),
640 selected_index,
641 selected_importance[1],
642 total_importance[1],
643 rand);
644 has_importance >>= 1;
645 }
646
647 float discard;
649 kg, P, N_or_D, t, has_transmission, selected_index, selected_importance[0], discard);
650 }
651 }
652
653 *pdf_factor *= 0.5f * (selected_importance[0] / total_importance[0] +
654 selected_importance[1] / total_importance[1]);
655
656 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
657 selected_index);
658
659 if (is_mesh(kemitter)) {
660 /* Transform ray from world to local space. */
661 light_tree_to_local_space<in_volume_segment>(kg, kemitter->mesh.object_id, P, N_or_D, t);
662
663 *node_index = kemitter->mesh.node_id;
664 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes,
665 *node_index);
666 if (knode->type == LIGHT_TREE_INSTANCE) {
667 /* Switch to the node with the subtree. */
668 *node_index = knode->instance.reference;
669 }
670 }
671
672 return selected_index;
673}
674
675template<bool in_volume_segment>
677 const float3 P,
678 const float3 N_or_D,
679 const float t,
680 const bool has_transmission,
681 const int left_index,
682 const int right_index,
683 ccl_private float &left_probability)
684{
685 const ccl_global KernelLightTreeNode *left = &kernel_data_fetch(light_tree_nodes, left_index);
686 const ccl_global KernelLightTreeNode *right = &kernel_data_fetch(light_tree_nodes, right_index);
687
688 float min_left_importance;
689 float max_left_importance;
690 float min_right_importance;
691 float max_right_importance;
693 kg, P, N_or_D, t, has_transmission, left, max_left_importance, min_left_importance);
695 kg, P, N_or_D, t, has_transmission, right, max_right_importance, min_right_importance);
696
697 const float total_max_importance = max_left_importance + max_right_importance;
698 if (total_max_importance == 0.0f) {
699 return false;
700 }
701 const float total_min_importance = min_left_importance + min_right_importance;
702
703 /* Average two probabilities of picking the left child node using lower and upper bounds. */
704 const float probability_max = max_left_importance / total_max_importance;
705 const float probability_min = total_min_importance > 0 ?
706 min_left_importance / total_min_importance :
707 0.5f * (float(max_left_importance > 0) +
708 float(max_right_importance == 0.0f));
709 left_probability = 0.5f * (probability_max + probability_min);
710 return true;
711}
712
713ccl_device int light_tree_root_node_index(KernelGlobals kg, const int object_receiver)
714{
715 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_LINKING) {
716 const uint receiver_light_set =
717 (object_receiver != OBJECT_NONE) ?
718 kernel_data_fetch(objects, object_receiver).receiver_light_set :
719 0;
720 return kernel_data.light_link_sets[receiver_light_set].light_tree_root;
721 }
722
723 return 0;
724}
725
726/* Pick a random light from the light tree from a given shading point P, write to the picked light
727 * index and the probability of picking the light. */
728template<bool in_volume_segment>
730 const float rand,
731 const float3 P,
732 float3 N_or_D,
733 float t,
734 const int object_receiver,
735 const int shader_flags,
737{
738 if (!kernel_data.integrator.use_direct_light) {
739 return false;
740 }
741
742 const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
743 float pdf_leaf = 1.0f;
744 float pdf_selection = 1.0f;
745 int selected_emitter = -1;
746 int node_index = light_tree_root_node_index(kg, object_receiver);
747 float rand_selection = rand;
748
749 float3 local_P = P;
750
751 /* Traverse the light tree until a leaf node is reached. */
752 while (true) {
753 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index);
754
755 if (is_leaf(knode)) {
756 /* At a leaf node, we pick an emitter. */
758 kg, rand_selection, local_P, N_or_D, t, has_transmission, &node_index, &pdf_selection);
759
760 if (selected_emitter < 0) {
761 return false;
762 }
763
764 if (node_index < 0) {
765 break;
766 }
767
768 /* Continue with the picked mesh light. */
769 ls->object = kernel_data_fetch(light_tree_emitters, selected_emitter).mesh.object_id;
770 continue;
771 }
772
773 /* Inner node. */
774 const int left_index = knode->inner.left_child;
775 const int right_index = knode->inner.right_child;
776
777 float left_prob;
779 kg, local_P, N_or_D, t, has_transmission, left_index, right_index, left_prob))
780 {
781 return false; /* Both child nodes have zero importance. */
782 }
783
784 float discard;
785 float total_prob = left_prob;
786 node_index = left_index;
788 right_index, 1.0f - left_prob, node_index, discard, total_prob, rand_selection);
789 pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob);
790 }
791
792 ls->emitter_id = selected_emitter;
793 ls->pdf_selection = pdf_selection * pdf_leaf;
794
795 return true;
796}
797
798/* We need to be able to find the probability of selecting a given light for MIS. */
799template<bool in_volume_segment>
801 float3 P,
802 float3 N,
803 const float dt,
804 const int path_flag,
805 const int object_emitter,
806 const uint index_emitter,
807 const int object_receiver)
808{
809 const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
810
811 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
812 index_emitter);
813 int subtree_root_index;
814 uint bit_trail;
815 uint target_emitter;
816
817 if (is_triangle(kemitter)) {
818 /* If the target is an emissive triangle, first traverse the top level tree to find the mesh
819 * light emitter, then traverse the subtree. */
820 target_emitter = kernel_data_fetch(object_to_tree, object_emitter);
821 const ccl_global KernelLightTreeEmitter *kmesh = &kernel_data_fetch(light_tree_emitters,
822 target_emitter);
823 subtree_root_index = kmesh->mesh.node_id;
824 const ccl_global KernelLightTreeNode *kroot = &kernel_data_fetch(light_tree_nodes,
825 subtree_root_index);
826 bit_trail = kroot->bit_trail;
827
828 if (kroot->type == LIGHT_TREE_INSTANCE) {
829 subtree_root_index = kroot->instance.reference;
830 }
831 }
832 else {
833 subtree_root_index = -1;
834 bit_trail = kemitter->bit_trail;
835 target_emitter = index_emitter;
836 }
837
838 float pdf = 1.0f;
839 int node_index = light_tree_root_node_index(kg, object_receiver);
840
841 /* Traverse the light tree until we reach the target leaf node. */
842 while (true) {
843 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index);
844
845 if (is_leaf(knode)) {
846 /* Iterate through leaf node to find the probability of sampling the target emitter. */
847 float target_max_importance = 0.0f;
848 float target_min_importance = 0.0f;
849 float total_max_importance = 0.0f;
850 float total_min_importance = 0.0f;
851 int num_has_importance = 0;
852 for (int i = 0; i < knode->num_emitters; i++) {
853 const int emitter = knode->leaf.first_emitter + i;
854 float max_importance;
855 float min_importance;
857 kg, P, N, dt, has_transmission, emitter, max_importance, min_importance);
858 num_has_importance += (max_importance > 0);
859 if (emitter == target_emitter) {
860 target_max_importance = max_importance;
861 target_min_importance = min_importance;
862 }
863 total_max_importance += max_importance;
864 total_min_importance += min_importance;
865 }
866
867 if (target_max_importance > 0.0f) {
868 pdf *= 0.5f * (target_max_importance / total_max_importance +
869 (total_min_importance > 0 ? target_min_importance / total_min_importance :
870 1.0f / num_has_importance));
871 }
872 else {
873 return 0.0f;
874 }
875
876 if (subtree_root_index != -1) {
877 /* Arrived at the mesh light. Continue with the subtree. */
878 float unused;
879 light_tree_to_local_space<in_volume_segment>(kg, object_emitter, P, N, unused);
880
881 node_index = subtree_root_index;
882 subtree_root_index = -1;
883 target_emitter = index_emitter;
884 bit_trail = kemitter->bit_trail;
885 continue;
886 }
887 return pdf;
888 }
889
890 /* Inner node. */
891 const int left_index = knode->inner.left_child;
892 const int right_index = knode->inner.right_child;
893
894 float left_prob;
896 kg, P, N, dt, has_transmission, left_index, right_index, left_prob))
897 {
898 return 0.0f;
899 }
900
901 bit_trail >>= kernel_data_fetch(light_tree_nodes, node_index).bit_skip;
902 const bool go_left = (bit_trail & 1) == 0;
903 bit_trail >>= 1;
904
905 node_index = go_left ? left_index : right_index;
906 pdf *= go_left ? left_prob : (1.0f - left_prob);
907
908 if (pdf == 0) {
909 return 0.0f;
910 }
911 }
912}
913
914/* If the function is called in volume, retrieve the previous point in volume segment, and compute
915 * pdf from there. Otherwise compute from the current shading point. */
917 float3 P,
918 const float3 N,
919 const float dt,
920 const int path_flag,
921 const int emitter_object,
922 const uint emitter_id,
923 const int object_receiver)
924{
925 if (path_flag & PATH_RAY_VOLUME_SCATTER) {
926 const float3 D_times_t = N;
927 const float3 D = normalize(D_times_t);
928 P = P - D_times_t;
930 kg, P, D, dt, path_flag, emitter_object, emitter_id, object_receiver);
931 }
932
934 kg, P, N, 0.0f, path_flag, emitter_object, emitter_id, object_receiver);
935}
936
#define D
MINLINE float safe_sqrtf(float a)
unsigned int uint
ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLight *klight, const float3 centroid, const float3 P, const float3 N, const float3 bcone_axis, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid)
Definition area.h:500
ccl_device_inline float cos_theta(const float3 w)
ccl_device_inline float sin_theta(const float3 w)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define kernel_data
#define kernel_data_fetch(name, index)
#define ccl_device
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define M_PI_F
#define KERNEL_FEATURE_LIGHT_LINKING
#define ccl_global
#define ccl_device_noinline
#define cosf(x)
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define fmaxf(x, y)
#define fminf(x, y)
#define fabsf(x)
ccl_device_forceinline bool distant_light_tree_parameters(const float3 centroid, const float theta_e, const float t, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid, ccl_private float &theta_d)
Definition distant.h:136
ccl_device_inline void triangle_vertices(KernelGlobals kg, const int prim, float3 P[3])
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
constexpr T clamp(T, U, U) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
@ OBJECT_INVERSE_TRANSFORM
@ OBJECT_TRANSFORM
ccl_device_inline Transform object_fetch_transform(KernelGlobals kg, const int object, enum ObjectTransform type)
ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg, const int object, const float time, ccl_private Transform *itfm)
ccl_device_forceinline bool background_light_tree_parameters(const float3 centroid, const float t, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid, ccl_private float &theta_d)
@ SD_BSDF_HAS_TRANSMISSION
@ LIGHT_TREE_INSTANCE
@ LIGHT_TREE_DISTANT
@ LIGHT_TREE_LEAF
@ PATH_RAY_MIS_HAD_TRANSMISSION
@ PATH_RAY_VOLUME_SCATTER
@ EMISSION_SAMPLING_BACK
@ EMISSION_SAMPLING_FRONT
@ SD_OBJECT_NEGATIVE_SCALE
@ SD_OBJECT_TRANSFORM_APPLIED
@ LIGHT_AREA
@ LIGHT_DISTANT
@ LIGHT_SPOT
@ LIGHT_BACKGROUND
@ LIGHT_POINT
ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelLight *klight, const float3 centroid, const float3 P, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid)
ccl_device_forceinline bool triangle_light_tree_parameters(KernelGlobals kg, const ccl_global KernelLightTreeEmitter *kemitter, const float3 centroid, const float3 P, const float3 N, const KernelBoundingCone bcone, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid)
ccl_device_inline float sqr(const float a)
Definition math_base.h:600
ccl_device_inline float inversesqrtf(const float f)
Definition math_base.h:529
ccl_device_inline float sin_from_cos(const float c)
Definition math_base.h:605
ccl_device_inline uint popcount(const uint x)
Definition math_base.h:673
ccl_device float fast_atan2f(const float y, const float x)
Definition math_fast.h:309
ccl_device float fast_acosf(const float x)
Definition math_fast.h:259
ccl_device void fast_sincosf(float x, ccl_private float *sine, ccl_private float *cosine)
Definition math_fast.h:144
ccl_device float fast_cosf(float x)
Definition math_fast.h:118
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline bool is_zero(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 bool isequal(const float2 a, const float2 b)
static int left
#define N
ccl_device void make_orthonormals_tangent(const float3 N, const float3 T, ccl_private float3 *a, ccl_private float3 *b)
ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLight *klight, const float3 centroid, const float3 P, const ccl_private KernelBoundingCone &bcone, ccl_private float &cos_theta_u, ccl_private float2 &distance, ccl_private float3 &point_to_centroid, ccl_private float &energy)
Definition spot.h:296
#define FLT_MAX
Definition stdcycles.h:14
packed_float3 min
packed_float3 max
packed_float3 axis
i
Definition text_draw.cc:230
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:87
ccl_device_inline float3 transform_direction_transposed(const ccl_private Transform *t, const float3 a)
Definition transform.h:116
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56
ccl_device_inline bool is_triangle(const ccl_global KernelLightTreeEmitter *kemitter)
Definition tree.h:79
ccl_device void light_tree_emitter_importance(KernelGlobals kg, const float3 P, const float3 N_or_D, const float t, const bool has_transmission, const int emitter_index, ccl_private float &max_importance, ccl_private float &min_importance)
Definition tree.h:388
ccl_device float3 compute_v(const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t)
Definition tree.h:47
ccl_device_inline bool is_light(const ccl_global KernelLightTreeEmitter *kemitter)
Definition tree.h:69
ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, ccl_private float &rand, ccl_private float3 &P, ccl_private float3 &N_or_D, ccl_private float &t, const bool has_transmission, ccl_private int *node_index, ccl_private float *pdf_factor)
Definition tree.h:579
ccl_device_noinline bool light_tree_sample(KernelGlobals kg, const float rand, const float3 P, float3 N_or_D, float t, const int object_receiver, const int shader_flags, ccl_private LightSample *ls)
Definition tree.h:729
ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, const ccl_global KernelLightTreeEmitter *kemitter, const float3 P, ccl_private float3 &centroid, ccl_private packed_float3 &dir)
Definition tree.h:242
ccl_device_inline bool is_mesh(const ccl_global KernelLightTreeEmitter *kemitter)
Definition tree.h:74
ccl_device void sample_reservoir(const int current_index, const float current_weight, ccl_private int &selected_index, ccl_private float &selected_weight, ccl_private float &total_weight, ccl_private float &rand)
Definition tree.h:537
ccl_device void light_tree_to_local_space(KernelGlobals kg, const int object_id, ccl_private float3 &P, ccl_private float3 &N_or_D, ccl_private float &t)
Definition tree.h:91
ccl_device bool get_left_probability(KernelGlobals kg, const float3 P, const float3 N_or_D, const float t, const bool has_transmission, const int left_index, const int right_index, ccl_private float &left_probability)
Definition tree.h:676
ccl_device void light_tree_importance(const float3 N_or_D, const bool has_transmission, const float3 point_to_centroid, const float cos_theta_u, const KernelBoundingCone bcone, const float max_distance, const float min_distance, const float energy, const float theta_d, ccl_private float &max_importance, ccl_private float &min_importance)
Definition tree.h:125
CCL_NAMESPACE_BEGIN ccl_device float light_tree_cos_bound_subtended_angle(const KernelBoundingBox bbox, const float3 centroid, const float3 P)
Definition tree.h:31
ccl_device void light_tree_child_importance(KernelGlobals kg, const float3 P, const float3 N_or_D, const float t, const bool has_transmission, const ccl_global KernelLightTreeNode *knode, ccl_private float &max_importance, ccl_private float &min_importance)
Definition tree.h:507
ccl_device void light_tree_node_importance(KernelGlobals kg, const float3 P, const float3 N_or_D, const float t, const bool has_transmission, const ccl_global KernelLightTreeNode *knode, ccl_private float &max_importance, ccl_private float &min_importance)
Definition tree.h:304
ccl_device_inline bool is_leaf(const ccl_global KernelLightTreeNode *knode)
Definition tree.h:84
ccl_device float light_tree_pdf(KernelGlobals kg, float3 P, float3 N, const float dt, const int path_flag, const int object_emitter, const uint index_emitter, const int object_receiver)
Definition tree.h:800
ccl_device int light_tree_root_node_index(KernelGlobals kg, const int object_receiver)
Definition tree.h:713
uint len