Blender V5.0
distribution.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#pragma once
6
7#include "kernel/globals.h"
8
10
12
13/* Simple CDF based sampling over all lights in the scene, without taking into
14 * account shading position or normal. */
15
17{
18 /* This is basically std::upper_bound as used by PBRT, to find a point light or
19 * triangle to emit from, proportional to area. a good improvement would be to
20 * also sample proportional to power, though it's not so well defined with
21 * arbitrary shaders. */
22 int first = 0;
23 int len = kernel_data.integrator.num_distribution + 1;
24
25 do {
26 const int half_len = len >> 1;
27 const int middle = first + half_len;
28
29 if (rand < kernel_data_fetch(light_distribution, middle).totarea) {
30 len = half_len;
31 }
32 else {
33 first = middle + 1;
34 len = len - half_len - 1;
35 }
36 } while (len > 0);
37
38 /* Clamping should not be needed but float rounding errors seem to
39 * make this fail on rare occasions. */
40 const int index = clamp(first - 1, 0, kernel_data.integrator.num_distribution - 1);
41
42 return index;
43}
44
46 const float rand,
48{
49 /* Sample light index from distribution. */
50 ls->emitter_id = light_distribution_sample(kg, rand);
51 ls->pdf_selection = kernel_data.integrator.distribution_pdf_lights;
52 return true;
53}
54
56{
57 return kernel_data.integrator.distribution_pdf_lights;
58}
59
#define kernel_data
#define kernel_data_fetch(name, index)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_inline float light_distribution_pdf_lamp(KernelGlobals kg)
CCL_NAMESPACE_BEGIN ccl_device int light_distribution_sample(KernelGlobals kg, const float rand)
constexpr T clamp(T, U, U) RET
#define ccl_device
uint len