[Bf-blender-cvs] [63bf31ce815] soc-2022-many-lights-sampling: Improve precision of selecting emitters based on importance
Brecht Van Lommel
noreply at git.blender.org
Fri Oct 7 14:11:44 CEST 2022
Commit: 63bf31ce81519a70693e8c331b92a770688b64e6
Author: Brecht Van Lommel
Date: Fri Oct 7 13:40:35 2022 +0200
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB63bf31ce81519a70693e8c331b92a770688b64e6
Improve precision of selecting emitters based on importance
And add some comments for future improvement.
DIfferential Revision: https://developer.blender.org/D16075
===================================================================
M intern/cycles/kernel/light/light_tree.h
===================================================================
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index e2318675d57..dfd552e95e9 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -233,6 +233,7 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
const ccl_global KernelLightTreeNode *knode,
ccl_private float *pdf_factor)
{
+ /* TODO: use single loop over prims to avoid computing light_tree_emitter_importance twice? */
float total_emitter_importance = 0.0f;
for (int i = 0; i < knode->num_prims; i++) {
const int prim_index = -knode->child_index + i;
@@ -244,13 +245,12 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
}
/* Once we have the total importance, we can normalize the CDF and sample it. */
- const float inv_total_importance = 1.0f / total_emitter_importance;
float emitter_cdf = 0.0f;
for (int i = 0; i < knode->num_prims; i++) {
const int prim_index = -knode->child_index + i;
/* to-do: is there any way to cache these values, so that recalculation isn't needed? */
- const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) *
- inv_total_importance;
+ const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) /
+ total_emitter_importance;
if (*randu <= emitter_cdf + emitter_pdf) {
*randu = (*randu - emitter_cdf) / emitter_pdf;
*pdf_factor *= emitter_pdf;
@@ -259,8 +259,9 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg,
emitter_cdf += emitter_pdf;
}
- /* This point should never be reached. */
- assert(false);
+ /* TODO: change implementation so that even under precision issues, we always end
+ * up selecting a light and this can't happen? */
+ kernel_assert(false);
return -1;
}
@@ -464,16 +465,21 @@ ccl_device bool light_tree_sample_distant_lights(KernelGlobals kg,
ccl_private LightSample *ls,
ccl_private float *pdf_factor)
{
+ /* TODO: do single loop over lights to avoid computing importance twice? */
+
const int num_distant_lights = kernel_data.integrator.num_distant_lights;
float total_importance = 0.0f;
for (int i = 0; i < num_distant_lights; i++) {
total_importance += light_tree_distant_light_importance(kg, N, i);
}
- const float inv_total_importance = 1.0f / total_importance;
+
+ if (total_importance == 0.0f) {
+ return -1;
+ }
float light_cdf = 0.0f;
for (int i = 0; i < num_distant_lights; i++) {
- const float light_pdf = light_tree_distant_light_importance(kg, N, i) * inv_total_importance;
+ const float light_pdf = light_tree_distant_light_importance(kg, N, i) / total_importance;
if (*randu <= light_cdf + light_pdf) {
*randu = (*randu - light_cdf) / light_pdf;
*pdf_factor *= light_pdf;
@@ -483,7 +489,7 @@ ccl_device bool light_tree_sample_distant_lights(KernelGlobals kg,
const int lamp = kdistant->prim_id;
if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
- return false;
+ return -1;
}
return light_sample<in_volume_segment>(kg, lamp, *randu, randv, P, path_flag, ls);
@@ -491,8 +497,9 @@ ccl_device bool light_tree_sample_distant_lights(KernelGlobals kg,
light_cdf += light_pdf;
}
- /* We should never reach this point. */
- assert(false);
+ /* TODO: change implementation so that even under precision issues, we always end
+ * up selecting a light and this can't happen? */
+ kernel_assert(false);
return -1;
}
@@ -508,7 +515,7 @@ ccl_device float light_tree_pdf(
light_tree_importance = light_tree_cluster_importance(kg, P, N, kroot);
}
const float total_group_importance = light_tree_importance + distant_light_importance;
- assert(total_group_importance != 0.0f);
+ kernel_assert(total_group_importance != 0.0f);
float pdf = light_tree_importance / total_group_importance;
const int emitter = (prim >= 0) ? kernel_data_fetch(triangle_to_tree, prim) :
@@ -652,7 +659,7 @@ ccl_device float distant_lights_pdf(KernelGlobals kg,
light_tree_importance = light_tree_cluster_importance(kg, P, N, kroot);
}
const float total_group_importance = light_tree_importance + distant_light_importance;
- assert(total_group_importance != 0.0f);
+ kernel_assert(total_group_importance != 0.0f);
float pdf = distant_light_importance / total_group_importance;
/* The light_to_tree array doubles as a lookup table for
More information about the Bf-blender-cvs
mailing list