[Bf-blender-cvs] [2c101527c1b] soc-2022-many-lights-sampling: Cycles: support single point light rendering in light tree
Jeffrey Liu
noreply at git.blender.org
Wed Jun 15 09:34:43 CEST 2022
Commit: 2c101527c1bf5583dca0b2a3358a9010e7e259bb
Author: Jeffrey Liu
Date: Wed Jun 15 03:26:33 2022 -0400
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB2c101527c1bf5583dca0b2a3358a9010e7e259bb
Cycles: support single point light rendering in light tree
===================================================================
M intern/cycles/kernel/light/light_tree.h
M intern/cycles/scene/light_tree.cpp
===================================================================
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index 19e57c88152..c5f1f52f05e 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -37,7 +37,9 @@ ccl_device float light_tree_node_importance(const float3 P,
/* to-do: compare this with directly using fmaxf and cosf. */
/* Avoid using cosine until needed. */
const float theta_prime = fmaxf(theta_i - theta_u, 0);
- if (theta_prime >= theta_e) {
+ /* to-do: this is also a rough heuristic to see if any contribution is possible.
+ * In the paper, this is only theta_e, but this seems to be off for point lights. */
+ if (theta_prime >= theta_o + theta_e) {
return 0;
}
const float cos_theta_prime = cosf(theta_prime);
@@ -127,6 +129,7 @@ ccl_device bool light_tree_sample(KernelGlobals kg,
/* Also keep track of the probability of traversing to a given node, */
/* so that we can scale our PDF accordingly later. */
int index = 0;
+ *pdf_factor = 1.0f;
/* to-do: is it better to generate a new random sample for each step of the traversal? */
float tree_u = path_state_rng_1D(kg, rng_state, 1);
@@ -137,8 +140,8 @@ ccl_device bool light_tree_sample(KernelGlobals kg,
const ccl_global KernelLightTreeNode *left = &kernel_tex_fetch(__light_tree_nodes, index + 1);
const ccl_global KernelLightTreeNode *right = &kernel_tex_fetch(__light_tree_nodes, knode->child_index);
- const float left_importance{light_tree_cluster_importance(kg, P, N, left)};
- const float right_importance{light_tree_cluster_importance(kg, P, N, right)};
+ const float left_importance = light_tree_cluster_importance(kg, P, N, left);
+ const float right_importance = light_tree_cluster_importance(kg, P, N, right);
const float left_probability = left_importance / (left_importance + right_importance);
if (tree_u < left_probability) {
@@ -159,20 +162,27 @@ ccl_device bool light_tree_sample(KernelGlobals kg,
const int prim_index = -knode->child_index + i;
total_emitter_importance += light_tree_emitter_importance(kg, P, N, prim_index);
}
- const float inv_total_importance = 1 / total_emitter_importance;
+
+ /* to-do: need to handle a case when total importance is 0.*/
+ if (total_emitter_importance == 0.0f) {
+
+ }
/* Once we have the total importance, we can normalize the CDF and sample it. */
+ const float inv_total_importance = 1 / 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?
* At the very least, we can maybe store the total importance during light tree construction
* so that the first for loop isn't necessary. */
- const float emitter_pdf{light_tree_emitter_importance(kg, P, N, prim_index)};
- emitter_cdf += emitter_pdf * inv_total_importance;
+ const float emitter_pdf = light_tree_emitter_importance(kg, P, N, prim_index) *
+ inv_total_importance;
+ emitter_cdf += emitter_pdf;
if (tree_u < emitter_cdf) {
*pdf_factor *= emitter_pdf;
+ assert(*pdf_factor != 0.0f);
return light_sample<in_volume_segment>(kg, prim_index, randu, randv, P, path_flag, ls);
}
}
@@ -195,6 +205,7 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg,
float pdf_factor;
bool ret = light_tree_sample<false>(
kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
+ assert(pdf_factor != 0.0f);
ls->pdf *= pdf_factor;
return ret;
}
diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp
index 8ae86443150..ef5317f2bd1 100644
--- a/intern/cycles/scene/light_tree.cpp
+++ b/intern/cycles/scene/light_tree.cpp
@@ -118,7 +118,7 @@ LightTree::LightTree(const vector<LightTreePrimitive> &prims, Scene *scene, uint
scene_ = scene;
max_lights_in_leaf_ = max_lights_in_leaf;
- vector<LightTreePrimitiveInfo> build_data(prims.size());
+ vector<LightTreePrimitiveInfo> build_data;
for (int i = 0; i < prims.size(); i++) {
LightTreePrimitiveInfo prim_info;
prim_info.bbox = prims[i].calculate_bbox(scene);
@@ -235,7 +235,6 @@ LightTreeBuildNode *LightTree::recursive_build(vector<LightTreePrimitiveInfo> &p
}
else {
int first_prim_offset = ordered_prims.size();
- /* to-do: reduce this? */
for (int i = start; i < end; i++) {
int prim_num = primitive_info[i].prim_num;
ordered_prims.push_back(prims_[prim_num]);
More information about the Bf-blender-cvs
mailing list