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 _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
