[Bf-blender-cvs] [0f7bafed382] soc-2022-many-lights-sampling: Cycles: re-implement distant lights in many lights sampling
Jeffrey Liu
noreply at git.blender.org
Sat Jul 2 19:57:47 CEST 2022
Commit: 0f7bafed3826f09e2c96126bd401de5e0540e038
Author: Jeffrey Liu
Date: Sat Jul 2 13:55:19 2022 -0400
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB0f7bafed3826f09e2c96126bd401de5e0540e038
Cycles: re-implement distant lights in many lights sampling
This uses a basic heuristic to determine whether Cycles should sample
from the distant lights group or the light tree, using the total energy.
A better solution would be to compute some importance value.
===================================================================
M intern/cycles/kernel/light/light_tree.h
M intern/cycles/kernel/types.h
M intern/cycles/scene/light.cpp
===================================================================
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index 9cf601407b7..57f2792cc35 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -248,8 +248,6 @@ ccl_device int light_tree_sample(KernelGlobals kg,
/* to-do: assign relative importances for the background and distant lights.
* Can we somehow adjust the importance measure to account for these as well? */
-
-/*
ccl_device float light_tree_distant_light_importance(KernelGlobals kg,
const float3 P,
const float3 N,
@@ -301,7 +299,6 @@ ccl_device int light_tree_sample_distant_lights(KernelGlobals kg,
}
}
}
-*/
ccl_device bool light_tree_sample_from_position(KernelGlobals kg,
ccl_private const RNGState *rng_state,
@@ -314,45 +311,19 @@ ccl_device bool light_tree_sample_from_position(KernelGlobals kg,
const uint32_t path_flag,
ccl_private LightSample *ls)
{
- /*
- const int num_distant_lights = kernel_data.integrator.num_distant_lights;
- const int num_light_tree_prims = kernel_data.integrator.num_distribution - num_distant_lights;
- */
-
float pdf_factor = 1.0f;
- bool ret = light_tree_sample<false>(
- kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
- /*
- bool ret = false;
- if (num_distant_lights == 0) {
+ bool ret;
+ float tree_u = path_state_rng_1D(kg, rng_state, 1);
+ if (tree_u < kernel_data.integrator.pdf_light_tree) {
+ pdf_factor *= kernel_data.integrator.pdf_light_tree;
ret = light_tree_sample<false>(
kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
}
- else if (num_light_tree_prims == 0) {
+ else {
+ pdf_factor *= (1 - kernel_data.integrator.pdf_light_tree);
ret = light_tree_sample_distant_lights<false>(
kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
}
- else {
- const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, 0);
- const float light_tree_importance = light_tree_cluster_importance(kg, P, N, knode);
- const float distant_light_importance = light_tree_distant_light_importance(kg, P, N, num_distant_lights);
-
- const float light_tree_probability = light_tree_importance /
- (light_tree_importance +
- distant_light_importance);
-
- if (randu < light_tree_probability) {
- ret = light_tree_sample<false>(
- kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
- pdf_factor *= light_tree_probability;
- }
- else {
- ret = light_tree_sample_distant_lights<false>(
- kg, rng_state, randu, randv, time, N, P, bounce, path_flag, ls, &pdf_factor);
- pdf_factor *= (1 - light_tree_probability);
- }
- }
- */
ls->pdf *= pdf_factor;
return ret;
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index f360940b54a..3e9fcd19609 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -1300,11 +1300,12 @@ typedef struct KernelIntegrator {
int direct_light_sampling_type;
/* Light tree. */
+ float pdf_light_tree;
int use_light_tree;
float splitting_threshold;
/* padding */
- int pad1, pad2;
+ int pad1;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index c7f252d13f9..242665387ca 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -383,7 +383,11 @@ void LightManager::device_update_distribution(Device *device,
object_id++;
}
- if (light_tree_enabled) {
+ size_t num_distribution = num_triangles + num_lights;
+ VLOG_INFO << "Total " << num_distribution << " of light distribution primitives.";
+
+ float pdf_light_tree = 0.0f;
+ if (light_tree_enabled && num_distribution > 0) {
/* For now, we'll start with a smaller number of max lights in a node.
* More benchmarking is needed to determine what number works best. */
LightTree light_tree(light_prims, scene, 8);
@@ -392,10 +396,15 @@ void LightManager::device_update_distribution(Device *device,
/* First initialize the light tree's nodes. */
const vector<PackedLightTreeNode> &linearized_bvh = light_tree.get_nodes();
KernelLightTreeNode *light_tree_nodes = dscene->light_tree_nodes.alloc(linearized_bvh.size());
+ float light_tree_energy = 0.0f;
for (int index = 0; index < linearized_bvh.size(); index++) {
const PackedLightTreeNode &node = linearized_bvh[index];
light_tree_nodes[index].energy = node.energy;
+ if (index == 0) {
+ light_tree_energy = node.energy;
+ }
+
for (int i = 0; i < 3; i++) {
light_tree_nodes[index].bounding_box_min[i] = node.bbox.min[i];
light_tree_nodes[index].bounding_box_max[i] = node.bbox.max[i];
@@ -471,8 +480,8 @@ void LightManager::device_update_distribution(Device *device,
/* We also add distant lights to a separate group. */
KernelLightTreeDistantEmitter *light_tree_distant_group =
- dscene->light_tree_distant_group.alloc(num_distant_lights + 1);
- float total_energy = 0.0f;
+ dscene->light_tree_distant_group.alloc(num_distant_lights);
+ float distant_light_energy = 0.0f;
for (int index = 0; index < num_distant_lights; index++) {
LightTreePrimitive prim = distant_lights[index];
Light *light = scene->lights[prim.lamp_id];
@@ -502,24 +511,16 @@ void LightManager::device_update_distribution(Device *device,
}
light_tree_distant_group[index].energy = energy;
- total_energy += energy;
+ distant_light_energy += energy;
}
- /* The final node is just used to store the total energy. */
- if (num_distant_lights > 0) {
- light_tree_distant_group[num_distant_lights].energy = total_energy;
- for (int i = 0; i < 3; i++) {
- light_tree_distant_group[num_distant_lights].direction[i] = 0.0f;
- }
- light_tree_distant_group[num_distant_lights].bounding_radius = 0.0f;
+ if (light_tree_energy > 0.0f) {
+ pdf_light_tree = light_tree_energy / (light_tree_energy + distant_light_energy);
}
dscene->light_tree_distant_group.copy_to_device();
}
- size_t num_distribution = num_triangles + num_lights;
- VLOG_INFO << "Total " << num_distribution << " of light distribution primitives.";
-
/* emission area */
KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
float totarea = 0.0f;
@@ -670,6 +671,7 @@ void LightManager::device_update_distribution(Device *device,
/* pdf_lights is used when sampling lights, and assumes that
* the light has been sampled through the light distribution.
* Therefore, we override it for now and adjust the pdf manually in the light tree.*/
+ kintegrator->pdf_light_tree = pdf_light_tree;
if (light_tree_enabled) {
kintegrator->pdf_triangles = 1.0f;
kintegrator->pdf_lights = 1.0f;
More information about the Bf-blender-cvs
mailing list