[Bf-blender-cvs] [2b8f717be6b] soc-2022-many-lights-sampling: Cleanup: make distant lights part of the light tree
Weizhen Huang
noreply at git.blender.org
Wed Nov 23 14:46:34 CET 2022
Commit: 2b8f717be6b5a0b28731a566ae0b3f0a7210bd55
Author: Weizhen Huang
Date: Wed Nov 23 14:45:23 2022 +0100
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB2b8f717be6b5a0b28731a566ae0b3f0a7210bd55
Cleanup: make distant lights part of the light tree
===================================================================
M intern/cycles/kernel/data_arrays.h
M intern/cycles/kernel/data_template.h
M intern/cycles/kernel/light/sample.h
M intern/cycles/kernel/light/tree.h
M intern/cycles/kernel/types.h
M intern/cycles/scene/light.cpp
M intern/cycles/scene/light_tree.cpp
M intern/cycles/scene/light_tree.h
M intern/cycles/scene/scene.cpp
M intern/cycles/scene/scene.h
===================================================================
diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h
index 9c57a0176b8..6914a4642e9 100644
--- a/intern/cycles/kernel/data_arrays.h
+++ b/intern/cycles/kernel/data_arrays.h
@@ -63,7 +63,6 @@ KERNEL_DATA_ARRAY(float2, light_background_conditional_cdf)
/* light tree */
KERNEL_DATA_ARRAY(KernelLightTreeNode, light_tree_nodes)
KERNEL_DATA_ARRAY(KernelLightTreeEmitter, light_tree_emitters)
-KERNEL_DATA_ARRAY(KernelLightTreeDistantEmitter, light_tree_distant_group)
KERNEL_DATA_ARRAY(uint, light_to_tree)
KERNEL_DATA_ARRAY(uint, object_lookup_offset)
KERNEL_DATA_ARRAY(uint, triangle_to_tree)
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index 7d6c1fd6804..994e7f7446c 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -155,8 +155,6 @@ KERNEL_STRUCT_MEMBER(integrator, int, num_distribution)
KERNEL_STRUCT_MEMBER(integrator, float, distribution_pdf_triangles)
KERNEL_STRUCT_MEMBER(integrator, float, distribution_pdf_lights)
KERNEL_STRUCT_MEMBER(integrator, float, light_inv_rr_threshold)
-/* Light tree. */
-KERNEL_STRUCT_MEMBER(integrator, int, num_tree_lights)
/* Bounces. */
KERNEL_STRUCT_MEMBER(integrator, int, min_bounce)
KERNEL_STRUCT_MEMBER(integrator, int, max_bounce)
@@ -210,6 +208,7 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights)
/* Padding */
KERNEL_STRUCT_MEMBER(integrator, int, pad1)
KERNEL_STRUCT_MEMBER(integrator, int, pad2)
+KERNEL_STRUCT_MEMBER(integrator, int, pad3)
KERNEL_STRUCT_END(KernelIntegrator)
/* SVM. For shader specialization. */
diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h
index 5f6b981a369..a462d0e01ac 100644
--- a/intern/cycles/kernel/light/sample.h
+++ b/intern/cycles/kernel/light/sample.h
@@ -463,20 +463,8 @@ ccl_device_inline float light_sample_mis_weight_forward_distant(KernelGlobals kg
const uint32_t path_flag,
const ccl_private LightSample *ls)
{
- const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
- float pdf = ls->pdf;
-
- /* Light selection pdf. */
- if (kernel_data.integrator.use_light_tree) {
- const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
- const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- pdf *= light_tree_pdf_distant(kg, ray_P, N, path_flag, ls->lamp);
- }
- else {
- pdf *= light_distribution_pdf_lamp(kg);
- }
-
- return light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
+ const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
+ return light_sample_mis_weight_forward_lamp(kg, state, path_flag, ls, ray_P);
}
ccl_device_inline float light_sample_mis_weight_forward_background(KernelGlobals kg,
@@ -492,7 +480,7 @@ ccl_device_inline float light_sample_mis_weight_forward_background(KernelGlobals
/* Light selection pdf. */
if (kernel_data.integrator.use_light_tree) {
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- pdf *= light_tree_pdf_distant(kg, ray_P, N, path_flag, kernel_data.background.light_index);
+ pdf *= light_tree_pdf(kg, ray_P, N, path_flag, ~kernel_data.background.light_index);
}
else {
pdf *= light_distribution_pdf_lamp(kg);
diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h
index c762f2b4cbf..e1498486f84 100644
--- a/intern/cycles/kernel/light/tree.h
+++ b/intern/cycles/kernel/light/tree.h
@@ -181,6 +181,8 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
emitter_index);
+ max_importance = 0.0f;
+ min_importance = 0.0f;
float theta_o = kemitter->theta_o;
float min_distance, distance;
float max_distance = 0.0f;
@@ -191,7 +193,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
const int prim = kemitter->prim_id;
/* TODO: pack in functions and move to header files for respective light types */
if (prim < 0) {
- const int lamp = -prim - 1;
+ const int lamp = ~prim;
const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
centroid = make_float3(klight->co[0], klight->co[1], klight->co[2]);
point_to_centroid = safe_normalize_len(centroid - P, &distance);
@@ -203,9 +205,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
max_distance = sqrtf(sqr(radius) + sqr(distance));
const float hypotenus = max_distance;
cos_theta_u = distance / hypotenus;
- bbox_is_visible = true; /* will be tested later */
+ bbox_is_visible = true; /* will be tested when computing the importance */
}
- else { /* area light */
+ else if (klight->type == LIGHT_AREA) {
bcone_axis = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
const float3 extentu = make_float3(
klight->area.extentu[0], klight->area.extentu[1], klight->area.extentu[2]);
@@ -224,6 +226,27 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
* the overhead to compute the accurate minimal distance? */
min_distance = distance;
}
+ else { /* distant light */
+ if (in_volume_segment) {
+ return;
+ }
+ if (klight->type == LIGHT_DISTANT) {
+ /* Treating it as a disk light 1 unit away */
+ cos_theta_u = fast_cosf(theta_o);
+ theta_o = 0.0f;
+ max_distance = 1.0f / cos_theta_u;
+ }
+ else {
+ /* Set an arbitrary direction for the background light. */
+ centroid = -N_or_D;
+ cos_theta_u = -1.0f;
+ max_distance = 1.0f;
+ }
+ bcone_axis = centroid;
+ point_to_centroid = -centroid;
+ min_distance = 1.0f;
+ bbox_is_visible = true; /* will be tested when computing the importance */
+ }
if (klight->type == LIGHT_POINT) {
bcone_axis = -point_to_centroid; /* disk oriented normal */
theta_o = 0.0f;
@@ -255,9 +278,8 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
min_distance = distance;
}
+ /* TODO: rename `bbox_is_visible` to `is_visible`? */
if (!bbox_is_visible) {
- max_importance = 0.0f;
- min_importance = 0.0f;
return;
}
@@ -296,45 +318,59 @@ ccl_device void light_tree_node_importance(KernelGlobals kg,
ccl_private float &max_importance,
ccl_private float &min_importance)
{
- if (knode->child_index <= 0 && knode->num_prims == 1) {
- /* at a leaf node and there is only one emitter */
+ max_importance = 0.0f;
+ min_importance = 0.0f;
+ if (knode->num_prims == 1) {
+ /* At a leaf node with only one emitter */
light_tree_emitter_importance<in_volume_segment>(
kg, P, N_or_D, t, has_transmission, -knode->child_index, max_importance, min_importance);
}
- else {
- const float3 bbox_min = make_float3(
- knode->bounding_box_min[0], knode->bounding_box_min[1], knode->bounding_box_min[2]);
- const float3 bbox_max = make_float3(
- knode->bounding_box_max[0], knode->bounding_box_max[1], knode->bounding_box_max[2]);
+ else if (knode->num_prims != 0) {
const float3 bcone_axis = make_float3(
knode->bounding_cone_axis[0], knode->bounding_cone_axis[1], knode->bounding_cone_axis[2]);
- const float3 centroid = 0.5f * (bbox_min + bbox_max);
+ float3 point_to_centroid;
+ float cos_theta_u;
float distance;
- float3 point_to_centroid = normalize_len(centroid - P, &distance);
- bool bbox_is_visible = has_transmission;
- float cos_theta_u = light_tree_cos_bounding_box_angle(
- bbox_min, bbox_max, P, N_or_D, point_to_centroid, bbox_is_visible);
-
- /* If the node is guaranteed to be behind the surface we're sampling, and the surface is
- * opaque, then we can give the node an importance of 0 as it contributes nothing to the
- * surface. */
- if (!bbox_is_visible) {
- max_importance = 0.0f;
- min_importance = 0.0f;
- return;
+ if (knode->bit_trail == 1) {
+ /* distant light node */
+ if (in_volume_segment) {
+ return;
+ }
+ point_to_centroid = -bcone_axis;
+ cos_theta_u = fmaxf(fast_cosf(knode->theta_o), 0.0f);
+ distance = 1.0f;
}
+ else {
+ const float3 bbox_min = make_float3(
+ knode->bounding_box_min[0], knode->bounding_box_min[1], knode->bounding_box_min[2]);
+ const float3 bbox_max = make_float3(
+ knode->bounding_box_max[0], knode->bounding_box_max[1], knode->bounding_box_max[2]);
- if (in_volume_segment) {
- const float3 D = N_or_D;
- const float3 closest_point = P + D * dot(point_to_centroid, D);
- /* minimal distance of the ray to the cluster */
- distance = len(centroid - closest_point);
- point_to_centroid = centroid - P;
- }
- /* clamp distance to half the radius of the cluster when splitting is disabled */
- distance = fmaxf(0.5f * len(centroid - bbox_max), distance);
+ const float3 centroid = 0.5f * (bbox_min + bbox_max);
+ point_to_centroid = normalize_len(centroid - P, &distance);
+ bool bbox_is_visible = has_transmission;
+ cos_theta_u = light_tree_cos_bounding_box_angle(
+ bbox_min, bbox_max, P, N_or_D, point_to_centroid, bbox_is_visible);
+
+ /* If the node is guaranteed to be behind the surface we're sampling, and the surface is
+ * opaque, then we can give the node an importance of 0 as it contributes nothing to the
+ * surface. */
+ if (!bbox_is_visible) {
+ return;
+ }
+
+ if (in_volume_segment) {
+ const float3 D = N_or_D;
+ const float3 closest_point = P + D * dot(point_to_centroid, D);
+ /* minimal distance of the ray to the cluster */
+ distance = len(centroid - closest_point);
+ point_to_centroid = centroid - P;
+ }
+ /* clamp distance to half the radius of the cluster when splitting is disabled */
+ dis
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list