29 const int cdf_width = res_x + 1;
37 const int middle = first +
step;
48 const int index_v =
max(0, first - 1);
57 const float v = (index_v + dv) / res_y;
64 const int middle = first +
step;
66 if (
kernel_data_fetch(light_background_conditional_cdf, index_v * cdf_width + middle).
y <
77 const int index_u =
max(0, first - 1);
81 index_v * cdf_width + index_u);
83 index_v * cdf_width + index_u + 1);
85 index_v * cdf_width + res_x);
89 const float u = (index_u + du) / res_x;
99 *pdf = (cdf_u.
x * cdf_v.
x) / denom;
112 const int res_x =
kernel_data.background.map_res_x;
113 const int res_y =
kernel_data.background.map_res_y;
114 const int cdf_width = res_x + 1;
127 index_v * cdf_width + res_x);
138 index_v * cdf_width + index_u);
141 return (cdf_u.
x * cdf_v.
x) / denom;
150 const int portal =
kernel_data.integrator.portal_offset + index;
153 *lightpos = klight->co;
154 *dir = klight->area.dir;
157 if (
dot(*dir,
P - *lightpos) > 1e-4f) {
167 const int ignore_portal,
170 float portal_pdf = 0.0f;
172 int num_possible = 0;
173 for (
int p = 0; p <
kernel_data.integrator.num_portals; p++) {
174 if (p == ignore_portal) {
190 const int portal =
kernel_data.integrator.portal_offset + p;
193 const float3 axis_u = klight->area.axis_u;
194 const float len_u = klight->area.len_u;
195 const float3 axis_v = klight->area.axis_v;
196 const float len_v = klight->area.len_v;
197 const float3 inv_extent_u = axis_u / len_u;
198 const float3 inv_extent_v = axis_v / len_v;
200 const bool is_round = (klight->area.invarea < 0.0f);
226 P, &lightpos, axis_u, len_u, axis_v, len_v,
zero_float2(),
false);
230 if (ignore_portal >= 0) {
235 return (num_possible > 0) ? portal_pdf / num_possible : 0.0f;
240 int num_possible_portals = 0;
241 for (
int p = 0; p <
kernel_data.integrator.num_portals; p++) {
245 num_possible_portals++;
248 return num_possible_portals;
254 const int num_possible,
259 rand.
y *= num_possible;
260 int portal = (int)rand.
y;
266 for (
int p = 0; p <
kernel_data.integrator.num_portals; p++) {
276 const int portal =
kernel_data.integrator.portal_offset + p;
278 const float3 axis_u = klight->area.axis_u;
279 const float3 axis_v = klight->area.axis_v;
280 const float len_u = klight->area.len_u;
281 const float len_v = klight->area.len_v;
282 const bool is_round = (klight->area.invarea < 0.0f);
286 lightpos +=
ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, rand);
296 *pdf /= num_possible;
329 float portal_method_pdf =
kernel_data.background.portal_weight;
330 float sun_method_pdf =
kernel_data.background.sun_weight;
331 float map_method_pdf =
kernel_data.background.map_weight;
334 if (portal_method_pdf > 0.0f) {
337 if (num_portals == 0) {
338 portal_method_pdf = 0.0f;
342 float pdf_fac = (portal_method_pdf + sun_method_pdf + map_method_pdf);
343 if (pdf_fac == 0.0f) {
349 pdf_fac = 1.0f / pdf_fac;
350 portal_method_pdf *= pdf_fac;
351 sun_method_pdf *= pdf_fac;
352 map_method_pdf *= pdf_fac;
358 const float sun_method_cdf = portal_method_pdf + sun_method_pdf;
362 if (rand.
x < portal_method_pdf) {
365 if (portal_method_pdf != 1.0f) {
366 rand.
x /= portal_method_pdf;
372 if (num_portals > 1) {
378 if (portal_method_pdf == 1.0f) {
381 *pdf *= portal_method_pdf;
383 else if (rand.
x < sun_method_cdf) {
386 if (sun_method_pdf != 1.0f) {
387 rand.
x = (rand.
x - portal_method_pdf) / sun_method_pdf;
393 if (sun_method_pdf == 1.0f) {
396 *pdf *= sun_method_pdf;
401 if (map_method_pdf != 1.0f) {
402 rand.
x = (rand.
x - sun_method_cdf) / map_method_pdf;
408 if (map_method_pdf == 1.0f) {
411 *pdf *= map_method_pdf;
415 if (method != 0 && portal_method_pdf != 0.0f) {
418 if (method != 1 && sun_method_pdf != 0.0f) {
421 if (method != 2 && map_method_pdf != 0.0f) {
429 float portal_method_pdf =
kernel_data.background.portal_weight;
430 float sun_method_pdf =
kernel_data.background.sun_weight;
431 float map_method_pdf =
kernel_data.background.map_weight;
433 float portal_pdf = 0.0f;
436 if (portal_method_pdf > 0.0f) {
438 bool is_possible =
false;
444 portal_method_pdf = 0.0f;
448 float pdf_fac = (portal_method_pdf + sun_method_pdf + map_method_pdf);
449 if (pdf_fac == 0.0f) {
454 pdf_fac = 1.0f / pdf_fac;
455 portal_method_pdf *= pdf_fac;
456 sun_method_pdf *= pdf_fac;
457 map_method_pdf *= pdf_fac;
459 float pdf = portal_pdf * portal_method_pdf;
460 if (sun_method_pdf != 0.0f) {
463 if (map_method_pdf != 0.0f) {
470template<
bool in_volume_segment>
478 if (in_volume_segment) {
495 point_to_centroid = -centroid;
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
CCL_NAMESPACE_BEGIN ccl_device_inline float area_light_rect_sample(const float3 P, ccl_private float3 *light_p, const float3 axis_u, const float len_u, const float3 axis_v, const float len_v, const float2 rand, bool sample_coord)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float sin_theta(const float3 w)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device float2 direction_to_equirectangular(const float3 dir)
ccl_device float3 equirectangular_to_direction(const float u, const float v)
#define kernel_assert(cond)
#define ccl_device_forceinline
#define kernel_data_fetch(name, index)
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
constexpr T clamp(T, U, U) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
CCL_NAMESPACE_BEGIN ccl_device float3 background_map_sample(KernelGlobals kg, const float2 rand, ccl_private float *pdf)
ccl_device_inline float3 background_sun_sample(KernelGlobals kg, const float2 rand, ccl_private float *pdf)
ccl_device_inline float background_sun_pdf(KernelGlobals kg, const float3 D)
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)
ccl_device int background_num_possible_portals(KernelGlobals kg, const float3 P)
ccl_device_inline float background_portal_pdf(KernelGlobals kg, const float3 P, float3 direction, const int ignore_portal, ccl_private bool *is_possible)
ccl_device float background_light_pdf(KernelGlobals kg, const float3 P, float3 direction)
ccl_device_inline bool background_portal_data_fetch_and_check_side(KernelGlobals kg, const float3 P, const int index, ccl_private float3 *lightpos, ccl_private float3 *dir)
ccl_device float background_map_pdf(KernelGlobals kg, const float3 direction)
ccl_device float3 background_portal_sample(KernelGlobals kg, const float3 P, float2 rand, const int num_possible, ccl_private int *sampled_portal, ccl_private float *pdf)
ccl_device_inline float3 background_light_sample(KernelGlobals kg, const float3 P, float2 rand, ccl_private float *pdf)
ccl_device_inline float3 ellipse_sample(const float3 ru, const float3 rv, const float2 rand)
ccl_device float light_pdf_area_to_solid_angle(const float3 Ng, const float3 I, const float t)
ccl_device_inline float inverse_lerp(const float a, const float b, const float x)
ccl_device_inline int float_to_int(const float f)
ccl_device_inline float one_minus_cos(const float angle)
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
ccl_device_inline float2 normalize_len(const float2 a, ccl_private float *t)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
ccl_device bool ray_quad_intersect(const float3 ray_P, const float3 ray_D, const float ray_tmin, const float ray_tmax, const float3 quad_P, const float3 inv_quad_u, const float3 inv_quad_v, const float3 quad_n, ccl_private float3 *isect_P, ccl_private float *isect_t, ccl_private float *isect_u, ccl_private float *isect_v, bool ellipse)
ccl_device_inline float pdf_uniform_cone(const float3 N, const float3 D, const float angle)
ccl_device float3 sample_uniform_sphere(const float2 rand)
ccl_device_inline float3 sample_uniform_cone(const float3 N, const float one_minus_cos_angle, const float2 rand, ccl_private float *cos_theta, ccl_private float *pdf)