Blender V5.0
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 N_or_D,
306 const float t,
307 const bool has_transmission,
308 const ccl_global KernelLightTreeNode *knode,
309 ccl_private float &max_importance,
310 ccl_private float &min_importance)
311{
312 const KernelBoundingCone bcone = knode->bcone;
313 const KernelBoundingBox bbox = knode->bbox;
314
315 float3 point_to_centroid;
316 float cos_theta_u;
317 float distance;
318 float theta_d;
319 if (knode->type == LIGHT_TREE_DISTANT) {
320 point_to_centroid = -bcone.axis;
321 cos_theta_u = fast_cosf(bcone.theta_o + bcone.theta_e);
322 distance = 1.0f;
323 /* For distant lights, the integral in Eq. (4) gives the ray length. */
324 if (t == FLT_MAX) {
325 /* In world volumes, distant lights can contribute to the lighting of the volume with
326 * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this
327 * case to give the distant light some weight, but one that isn't too high for a typical
328 * world volume use case. */
329 theta_d = 1.0f;
330 }
331 else {
332 theta_d = t;
333 }
334 }
335 else {
336 const float3 centroid = 0.5f * (bbox.min + bbox.max);
337
338 if (in_volume_segment) {
339 const float3 D = N_or_D;
340 const float closest_t = dot(centroid - P, D);
341 const float3 closest_point = P + D * clamp(closest_t, 0.0f, t);
342 /* Minimal distance of the ray to the cluster. */
343 distance = len(centroid - P - D * closest_t);
344
345 /* Estimate `theta_b - theta_a` using the centroid of the cluster and the complete ray
346 * segment in volume. */
347 if (t == FLT_MAX) {
348 theta_d = fast_atan2f(closest_t, distance) + M_PI_2_F;
349 }
350 else {
351 /* Original equation is `theta_d = atan((t - closest) /d) + atan(closest / d)`, convert to
352 * the below equation using the equality `atan(a) + atan(b) = atan2(a + b, 1 - a*b)` for
353 * better precision at small angles. */
354 theta_d = atan2f(t, distance - closest_t * safe_divide(t - closest_t, distance));
355 }
356
357 /* Vector that forms a minimal angle with the emitter centroid. */
358 point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
359 cos_theta_u = light_tree_cos_bound_subtended_angle(bbox, centroid, closest_point);
360 }
361 else {
362 const float3 N = N_or_D;
363 const float3 bbox_extent = bbox.max - centroid;
364 const bool bbox_is_visible = has_transmission |
365 (dot(N, centroid - P) + dot(fabs(N), fabs(bbox_extent)) > 0);
366
367 /* If the node is guaranteed to be behind the surface we're sampling, and the surface is
368 * opaque, then we can give the node an importance of 0 as it contributes nothing to the
369 * surface. */
370 if (!bbox_is_visible) {
371 return;
372 }
373
374 point_to_centroid = normalize_len(centroid - P, &distance);
375 cos_theta_u = light_tree_cos_bound_subtended_angle(bbox, centroid, P);
376 theta_d = 1.0f;
377 }
378 /* Clamp distance to half the radius of the cluster when splitting is disabled. */
379 distance = fmaxf(0.5f * len(centroid - bbox.max), distance);
380 }
381 /* TODO: currently max_distance = min_distance, max_importance = min_importance for the
382 * nodes. Do we need better weights for complex scenes? */
384 has_transmission,
385 point_to_centroid,
386 cos_theta_u,
387 bcone,
388 distance,
389 distance,
390 knode->energy,
391 theta_d,
392 max_importance,
393 min_importance);
394}
395
396template<bool in_volume_segment>
398 const float3 P,
399 const float3 N_or_D,
400 const float t,
401 const bool has_transmission,
402 const int emitter_index,
403 ccl_private float &max_importance,
404 ccl_private float &min_importance)
405{
406 max_importance = 0.0f;
407 min_importance = 0.0f;
408
409 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
410 emitter_index);
411
412 if (is_mesh(kemitter)) {
413 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes,
414 kemitter->mesh.node_id);
415
417 P, N_or_D, t, has_transmission, knode, max_importance, min_importance);
418 return;
419 }
420
421 KernelBoundingCone bcone;
422 bcone.theta_o = kemitter->theta_o;
423 bcone.theta_e = kemitter->theta_e;
424 float cos_theta_u;
425 float theta_d = 1.0f;
426 float2 distance; /* distance.x = max_distance, distance.y = min_distance */
427 float3 centroid;
428 float3 point_to_centroid;
429 float3 P_c = P;
430
431 if (!compute_emitter_centroid_and_dir<in_volume_segment>(kg, kemitter, P, centroid, bcone.axis))
432 {
433 return;
434 }
435
436 if (in_volume_segment) {
437 const float3 D = N_or_D;
438 /* Closest point from ray to the emitter centroid. */
439 const float closest_t = dot(centroid - P, D);
440 P_c += D * clamp(closest_t, 0.0f, t);
441 const float d = len(centroid - P - D * closest_t);
442 if (t == FLT_MAX) {
443 theta_d = fast_atan2f(closest_t, d) + M_PI_2_F;
444 }
445 else {
446 theta_d = atan2f(t, d - closest_t * safe_divide(t - closest_t, d));
447 }
448 }
449
450 /* Early out if the emitter is guaranteed to be invisible. */
451 bool is_visible;
452 float energy = kemitter->energy;
453 if (is_triangle(kemitter)) {
455 kg, kemitter, centroid, P_c, N_or_D, bcone, cos_theta_u, distance, point_to_centroid);
456 }
457 else {
458 kernel_assert(is_light(kemitter));
459 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~(kemitter->light.id));
460 switch (klight->type) {
461 /* Function templates only modifies cos_theta_u when in_volume_segment = true. */
462 case LIGHT_SPOT:
464 klight, centroid, P_c, bcone, cos_theta_u, distance, point_to_centroid, energy);
465 break;
466 case LIGHT_POINT:
468 klight, centroid, P_c, cos_theta_u, distance, point_to_centroid);
469 bcone.theta_o = 0.0f;
470 break;
471 case LIGHT_AREA:
473 klight, centroid, P_c, N_or_D, bcone.axis, cos_theta_u, distance, point_to_centroid);
474 break;
475 case LIGHT_BACKGROUND:
477 centroid, t, cos_theta_u, distance, point_to_centroid, theta_d);
478 break;
479 case LIGHT_DISTANT:
481 centroid, bcone.theta_e, t, cos_theta_u, distance, point_to_centroid, theta_d);
482 break;
483 default:
484 return;
485 }
486 }
487
488 is_visible |= has_transmission;
489 if (!is_visible) {
490 return;
491 }
492
493 if (in_volume_segment) {
494 /* Vector that forms a minimal angle with the emitter centroid. */
495 point_to_centroid = -compute_v(centroid, P, N_or_D, bcone.axis, t);
496
497 if (is_light(kemitter)) {
498 const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~(kemitter->light.id));
499 if (klight->type == LIGHT_DISTANT) {
500 /* For distant light `theta_min` is 0, but due to numerical issues this is not always true.
501 * Therefore explicitly assign `-bcone.axis` to `point_to_centroid` in this case. */
502 point_to_centroid = -bcone.axis;
503 }
504 }
505 }
506
508 has_transmission,
509 point_to_centroid,
510 cos_theta_u,
511 bcone,
512 distance.x,
513 distance.y,
514 energy,
515 theta_d,
516 max_importance,
517 min_importance);
518}
519
520template<bool in_volume_segment>
522 const float3 P,
523 const float3 N_or_D,
524 const float t,
525 const bool has_transmission,
526 const ccl_global KernelLightTreeNode *knode,
527 ccl_private float &max_importance,
528 ccl_private float &min_importance)
529{
530 max_importance = 0.0f;
531 min_importance = 0.0f;
532
533 if (knode->num_emitters == 1) {
535 P,
536 N_or_D,
537 t,
538 has_transmission,
539 knode->leaf.first_emitter,
540 max_importance,
541 min_importance);
542 }
543 else if (knode->num_emitters != 0) {
545 P, N_or_D, t, has_transmission, knode, max_importance, min_importance);
546 }
547}
548
549/* Select an element from the reservoir with probability proportional to its weight.
550 * Expect `selected_index` to be initialized to -1, and stays -1 if all the weights are invalid. */
551ccl_device void sample_reservoir(const int current_index,
552 const float current_weight,
553 ccl_private int &selected_index,
554 ccl_private float &selected_weight,
555 ccl_private float &total_weight,
556 ccl_private float &rand)
557{
558 if (!(current_weight > 0.0f)) {
559 return;
560 }
561 total_weight += current_weight;
562
563 /* When `-ffast-math` is used it is possible that the threshold is almost 1 but not quite.
564 * For this case we check the first valid element explicitly (instead of relying on the threshold
565 * to be 1, giving it certain probability). */
566 if (selected_index == -1) {
567 selected_index = current_index;
568 selected_weight = current_weight;
569 /* The threshold is expected to be 1 in this case with strict mathematics, so no need to divide
570 * the rand. In fact, division in such case could lead the rand to exceed 1 because of division
571 * by something smaller than 1. */
572 return;
573 }
574
575 const float thresh = current_weight / total_weight;
576 if (rand <= thresh) {
577 selected_index = current_index;
578 selected_weight = current_weight;
579 rand = rand / thresh;
580 }
581 else {
582 rand = (rand - thresh) / (1.0f - thresh);
583 }
584
585 /* Ensure the `rand` is always within 0..1 range, which could be violated above when
586 * `-ffast-math` is used. */
587 rand = saturatef(rand);
588}
589
590/* Pick an emitter from a leaf node using reservoir sampling, keep two reservoirs for upper and
591 * lower bounds. */
592template<bool in_volume_segment>
594 ccl_private float &rand,
596 ccl_private float3 &N_or_D,
597 ccl_private float &t,
598 const bool has_transmission,
599 ccl_private int *node_index,
600 ccl_private float *pdf_factor)
601{
602 float selected_importance[2] = {0.0f, 0.0f};
603 float total_importance[2] = {0.0f, 0.0f};
604 int selected_index = -1;
605 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, *node_index);
606 *node_index = -1;
607
608 kernel_assert(knode->num_emitters <= sizeof(uint) * 8);
609 /* Mark emitters with valid importance. Used for reservoir when total minimum importance = 0. */
610 uint has_importance = 0;
611
612 const bool sample_max = (rand > 0.5f); /* Sampling using the maximum importance. */
613 if (knode->num_emitters > 1) {
614 rand = rand * 2.0f - float(sample_max);
615 }
616
617 for (int i = 0; i < knode->num_emitters; i++) {
618 int current_index = knode->leaf.first_emitter + i;
619 /* maximum importance = importance[0], minimum importance = importance[1] */
620 float importance[2];
622 kg, P, N_or_D, t, has_transmission, current_index, importance[0], importance[1]);
623
624 sample_reservoir(current_index,
625 importance[!sample_max],
626 selected_index,
627 selected_importance[!sample_max],
628 total_importance[!sample_max],
629 rand);
630 if (selected_index == current_index) {
631 selected_importance[sample_max] = importance[sample_max];
632 }
633 total_importance[sample_max] += importance[sample_max];
634
635 has_importance |= ((importance[0] > 0) << i);
636 }
637
638 if (!has_importance) {
639 return -1;
640 }
641
642 if (total_importance[1] == 0.0f) {
643 /* Uniformly sample emitters with positive maximum importance. */
644 if (sample_max) {
645 selected_importance[1] = 1.0f;
646 total_importance[1] = float(popcount(has_importance));
647 }
648 else {
649 selected_index = -1;
650 for (int i = 0; i < knode->num_emitters; i++) {
651 const int current_index = knode->leaf.first_emitter + i;
652 sample_reservoir(current_index,
653 float(has_importance & 1),
654 selected_index,
655 selected_importance[1],
656 total_importance[1],
657 rand);
658 has_importance >>= 1;
659 }
660
661 float discard;
663 kg, P, N_or_D, t, has_transmission, selected_index, selected_importance[0], discard);
664 }
665 }
666
667 *pdf_factor *= 0.5f * (selected_importance[0] / total_importance[0] +
668 selected_importance[1] / total_importance[1]);
669
670 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
671 selected_index);
672
673 if (is_mesh(kemitter)) {
674 /* Transform ray from world to local space. */
675 light_tree_to_local_space<in_volume_segment>(kg, kemitter->mesh.object_id, P, N_or_D, t);
676
677 *node_index = kemitter->mesh.node_id;
678 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes,
679 *node_index);
680 if (knode->type == LIGHT_TREE_INSTANCE) {
681 /* Switch to the node with the subtree. */
682 *node_index = knode->instance.reference;
683 }
684 }
685
686 return selected_index;
687}
688
689template<bool in_volume_segment>
691 const float3 P,
692 const float3 N_or_D,
693 const float t,
694 const bool has_transmission,
695 const int left_index,
696 const int right_index,
697 ccl_private float &left_probability)
698{
699 const ccl_global KernelLightTreeNode *left = &kernel_data_fetch(light_tree_nodes, left_index);
700 const ccl_global KernelLightTreeNode *right = &kernel_data_fetch(light_tree_nodes, right_index);
701
702 float min_left_importance;
703 float max_left_importance;
704 float min_right_importance;
705 float max_right_importance;
707 kg, P, N_or_D, t, has_transmission, left, max_left_importance, min_left_importance);
709 kg, P, N_or_D, t, has_transmission, right, max_right_importance, min_right_importance);
710
711 const float total_max_importance = max_left_importance + max_right_importance;
712 if (total_max_importance == 0.0f) {
713 return false;
714 }
715 const float total_min_importance = min_left_importance + min_right_importance;
716
717 /* Average two probabilities of picking the left child node using lower and upper bounds. */
718 const float probability_max = max_left_importance / total_max_importance;
719 const float probability_min = total_min_importance > 0 ?
720 min_left_importance / total_min_importance :
721 0.5f * (float(max_left_importance > 0) +
722 float(max_right_importance == 0.0f));
723 left_probability = 0.5f * (probability_max + probability_min);
724 return true;
725}
726
727ccl_device int light_tree_root_node_index(KernelGlobals kg, const int object_receiver)
728{
729 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_LINKING) {
730 const uint receiver_light_set =
731 (object_receiver != OBJECT_NONE) ?
732 kernel_data_fetch(objects, object_receiver).receiver_light_set :
733 0;
734 return kernel_data.light_link_sets[receiver_light_set].light_tree_root;
735 }
736
737 return 0;
738}
739
740/* Pick a random light from the light tree from a given shading point P, write to the picked light
741 * index and the probability of picking the light. */
742template<bool in_volume_segment>
744 const float rand,
745 const float3 P,
746 float3 N_or_D,
747 float t,
748 const int object_receiver,
749 const int shader_flags,
751{
752 if (!kernel_data.integrator.use_direct_light) {
753 return false;
754 }
755
756 const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION);
757 float pdf_leaf = 1.0f;
758 float pdf_selection = 1.0f;
759 int selected_emitter = -1;
760 int node_index = light_tree_root_node_index(kg, object_receiver);
761 float rand_selection = rand;
762
763 float3 local_P = P;
764
765 /* Traverse the light tree until a leaf node is reached. */
766 while (true) {
767 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index);
768
769 if (is_leaf(knode)) {
770 /* At a leaf node, we pick an emitter. */
772 kg, rand_selection, local_P, N_or_D, t, has_transmission, &node_index, &pdf_selection);
773
774 if (selected_emitter < 0) {
775 return false;
776 }
777
778 if (node_index < 0) {
779 break;
780 }
781
782 /* Continue with the picked mesh light. */
783 ls->object = kernel_data_fetch(light_tree_emitters, selected_emitter).mesh.object_id;
784 continue;
785 }
786
787 /* Inner node. */
788 const int left_index = knode->inner.left_child;
789 const int right_index = knode->inner.right_child;
790
791 float left_prob;
793 kg, local_P, N_or_D, t, has_transmission, left_index, right_index, left_prob))
794 {
795 return false; /* Both child nodes have zero importance. */
796 }
797
798 float discard;
799 float total_prob = left_prob;
800 node_index = left_index;
802 right_index, 1.0f - left_prob, node_index, discard, total_prob, rand_selection);
803 pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob);
804 }
805
806 ls->emitter_id = selected_emitter;
807 ls->pdf_selection = pdf_selection * pdf_leaf;
808
809 return true;
810}
811
812/* We need to be able to find the probability of selecting a given light for MIS. */
813template<bool in_volume_segment>
815 float3 P,
816 float3 N,
817 const float dt,
818 const int path_flag,
819 const int object_emitter,
820 const uint index_emitter,
821 const int object_receiver)
822{
823 const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
824
825 const ccl_global KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
826 index_emitter);
827 int subtree_root_index;
828 uint bit_trail;
829 uint target_emitter;
830
831 if (is_triangle(kemitter)) {
832 /* If the target is an emissive triangle, first traverse the top level tree to find the mesh
833 * light emitter, then traverse the subtree. */
834 target_emitter = kernel_data_fetch(object_to_tree, object_emitter);
835 const ccl_global KernelLightTreeEmitter *kmesh = &kernel_data_fetch(light_tree_emitters,
836 target_emitter);
837 subtree_root_index = kmesh->mesh.node_id;
838 const ccl_global KernelLightTreeNode *kroot = &kernel_data_fetch(light_tree_nodes,
839 subtree_root_index);
840 bit_trail = kroot->bit_trail;
841
842 if (kroot->type == LIGHT_TREE_INSTANCE) {
843 subtree_root_index = kroot->instance.reference;
844 }
845 }
846 else {
847 subtree_root_index = -1;
848 bit_trail = kemitter->bit_trail;
849 target_emitter = index_emitter;
850 }
851
852 float pdf = 1.0f;
853 int node_index = light_tree_root_node_index(kg, object_receiver);
854
855 /* Traverse the light tree until we reach the target leaf node. */
856 while (true) {
857 const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index);
858
859 if (is_leaf(knode)) {
860 /* Iterate through leaf node to find the probability of sampling the target emitter. */
861 float target_max_importance = 0.0f;
862 float target_min_importance = 0.0f;
863 float total_max_importance = 0.0f;
864 float total_min_importance = 0.0f;
865 int num_has_importance = 0;
866 for (int i = 0; i < knode->num_emitters; i++) {
867 const int emitter = knode->leaf.first_emitter + i;
868 float max_importance;
869 float min_importance;
871 kg, P, N, dt, has_transmission, emitter, max_importance, min_importance);
872 num_has_importance += (max_importance > 0);
873 if (emitter == target_emitter) {
874 target_max_importance = max_importance;
875 target_min_importance = min_importance;
876 }
877 total_max_importance += max_importance;
878 total_min_importance += min_importance;
879 }
880
881 if (target_max_importance > 0.0f) {
882 pdf *= 0.5f * (target_max_importance / total_max_importance +
883 (total_min_importance > 0 ? target_min_importance / total_min_importance :
884 1.0f / num_has_importance));
885 }
886 else {
887 return 0.0f;
888 }
889
890 if (subtree_root_index != -1) {
891 /* Arrived at the mesh light. Continue with the subtree. */
892 float unused;
893 light_tree_to_local_space<in_volume_segment>(kg, object_emitter, P, N, unused);
894
895 node_index = subtree_root_index;
896 subtree_root_index = -1;
897 target_emitter = index_emitter;
898 bit_trail = kemitter->bit_trail;
899 continue;
900 }
901 return pdf;
902 }
903
904 /* Inner node. */
905 const int left_index = knode->inner.left_child;
906 const int right_index = knode->inner.right_child;
907
908 float left_prob;
910 kg, P, N, dt, has_transmission, left_index, right_index, left_prob))
911 {
912 return 0.0f;
913 }
914
915 bit_trail >>= kernel_data_fetch(light_tree_nodes, node_index).bit_skip;
916 const bool go_left = (bit_trail & 1) == 0;
917 bit_trail >>= 1;
918
919 node_index = go_left ? left_index : right_index;
920 pdf *= go_left ? left_prob : (1.0f - left_prob);
921
922 if (pdf == 0) {
923 return 0.0f;
924 }
925 }
926}
927
928/* If the function is called in volume, retrieve the previous point in volume segment, and compute
929 * pdf from there. Otherwise compute from the current shading point. */
931 float3 P,
932 const float3 N,
933 const float dt,
934 const int path_flag,
935 const int emitter_object,
936 const uint emitter_id,
937 const int object_receiver)
938{
939 if (path_flag & PATH_RAY_VOLUME_SCATTER) {
940 const float3 D_times_t = N;
941 const float3 D = normalize(D_times_t);
942 P = P - D_times_t;
944 kg, P, D, dt, path_flag, emitter_object, emitter_id, object_receiver);
945 }
946
948 kg, P, N, 0.0f, path_flag, emitter_object, emitter_id, object_receiver);
949}
950
#define D
MINLINE float safe_sqrtf(float a)
MINLINE float safe_divide(float a, float b)
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)
nullptr float
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define kernel_data
#define M_PI_2_F
#define kernel_data_fetch(name, index)
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define KERNEL_FEATURE_LIGHT_LINKING
#define ccl_global
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
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 inversesqrtf(const float f)
Definition math_base.h:529
ccl_device_inline float sin_from_cos(const float c)
Definition math_base.h:609
ccl_device_inline uint popcount(const uint x)
Definition math_base.h:688
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
#define sqr
#define fabsf
#define ccl_device
#define fmaxf
#define fminf
#define M_PI_F
#define cosf
#define atan2f
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:127
ccl_device_inline float3 transform_direction_transposed(const ccl_private Transform *t, const float3 a)
Definition transform.h:149
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:397
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:593
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:743
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:551
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:690
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:521
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:814
ccl_device void light_tree_node_importance(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 int light_tree_root_node_index(KernelGlobals kg, const int object_receiver)
Definition tree.h:727
uint len