[Bf-blender-cvs] [c8e0de4b9cc] soc-2022-many-lights-sampling: Cleanup: abandon adaptive splitting
Weizhen Huang
noreply at git.blender.org
Wed Nov 16 19:36:01 CET 2022
Commit: c8e0de4b9cc6ddb077bc2e3fbce792fcd80733f1
Author: Weizhen Huang
Date: Wed Nov 16 19:35:35 2022 +0100
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rBc8e0de4b9cc6ddb077bc2e3fbce792fcd80733f1
Cleanup: abandon adaptive splitting
===================================================================
M intern/cycles/kernel/integrator/shade_volume.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
===================================================================
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index 90b26f4759a..6889e01f517 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -700,7 +700,6 @@ ccl_device_forceinline bool integrate_volume_sample_light(
float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_VOLUME_SEGMENT_LIGHT);
if (!light_sample_from_volume_segment(kg,
- rng_state,
rand_light.x,
rand_light.y,
sd->time,
diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h
index a9bb9bdbc44..5f6b981a369 100644
--- a/intern/cycles/kernel/light/sample.h
+++ b/intern/cycles/kernel/light/sample.h
@@ -321,7 +321,6 @@ ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg,
* Uses either a flat distribution or light tree. */
ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg,
- ccl_private const RNGState *rng_state,
float randu,
const float randv,
const float time,
@@ -333,18 +332,8 @@ ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg,
ccl_private LightSample *ls)
{
if (kernel_data.integrator.use_light_tree) {
- return light_tree_sample<true>(kg,
- rng_state,
- randu,
- randv,
- time,
- P,
- D,
- t,
- SD_BSDF_HAS_TRANSMISSION,
- bounce,
- path_flag,
- ls);
+ return light_tree_sample<true>(
+ kg, randu, randv, time, P, D, t, SD_BSDF_HAS_TRANSMISSION, bounce, path_flag, ls);
}
else {
return light_distribution_sample<true>(kg, randu, randv, time, P, bounce, path_flag, ls);
@@ -365,7 +354,7 @@ ccl_device bool light_sample_from_position(KernelGlobals kg,
{
if (kernel_data.integrator.use_light_tree) {
return light_tree_sample<false>(
- kg, rng_state, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls);
+ kg, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls);
}
else {
return light_distribution_sample<false>(kg, randu, randv, time, P, bounce, path_flag, ls);
@@ -439,7 +428,7 @@ ccl_device_inline float light_sample_mis_weight_forward_surface(KernelGlobals kg
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object);
uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object);
- pdf *= light_tree_pdf(kg, state, ray_P, N, path_flag, sd->prim - prim_offset + lookup_offset);
+ pdf *= light_tree_pdf(kg, ray_P, N, path_flag, sd->prim - prim_offset + lookup_offset);
}
else {
/* Handled in triangle_light_pdf for effeciency. */
@@ -460,7 +449,7 @@ ccl_device_inline float light_sample_mis_weight_forward_lamp(KernelGlobals kg,
/* Light selection pdf. */
if (kernel_data.integrator.use_light_tree) {
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- pdf *= light_tree_pdf(kg, state, P, N, path_flag, ~ls->lamp);
+ pdf *= light_tree_pdf(kg, P, N, path_flag, ~ls->lamp);
}
else {
pdf *= light_distribution_pdf_lamp(kg);
diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h
index d0d4e7f58ef..ec28df7df8e 100644
--- a/intern/cycles/kernel/light/tree.h
+++ b/intern/cycles/kernel/light/tree.h
@@ -168,41 +168,6 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D,
}
}
-/* This is uniformly sampling the reservoir for now. */
-ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg,
- const float3 P,
- const float3 N,
- int emitter_index)
-{
- if (emitter_index < 0) {
- return 0.0f;
- }
-
- /* TODO: reservoir is disabled for now */
- return 1.0f;
-
- ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters,
- emitter_index);
- const int prim = kemitter->prim_id;
-
- /* Triangles are handled normally for now. */
- if (prim < 0) {
- const int lamp = -prim - 1;
- const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
-
- /* We use a special calculation to check if a light is
- * within the bounds of a spot or area light. */
- if (klight->type == LIGHT_SPOT) {
- return spot_light_tree_weight(klight, P, N);
- }
- else if (klight->type == LIGHT_AREA) {
- return area_light_tree_weight(klight, P, N);
- }
- }
-
- return 1.0f;
-}
-
template<bool in_volume_segment>
ccl_device void light_tree_emitter_importance(KernelGlobals kg,
const float3 P,
@@ -310,50 +275,6 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
min_importance);
}
-ccl_device bool light_tree_should_split(KernelGlobals kg,
- const float3 P,
- const ccl_global KernelLightTreeNode *knode)
-{
- /* TODO: don't split because it introduces variance. Maybe delete relevant field and functions
- * later. */
- return false;
-
- const float splitting_threshold = 0.5f;
- if (splitting_threshold == 0.0f) {
- return false;
- }
- else if (splitting_threshold == 1.0f) {
- return true;
- }
-
- 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]);
- const float3 centroid = 0.5f * bbox_min + 0.5f * bbox_max;
-
- const float radius = len(bbox_max - centroid);
- const float distance = len(P - centroid);
-
- if (distance <= radius) {
- return true;
- }
-
- const float a = distance - radius;
- const float b = distance + radius;
-
- const float E_g = 1.0f / (a * b);
- const float E_e = knode->energy;
-
- /* This is a simplified version of the expression given in the paper. */
- const float V_g = (b - a) * (b - a) * E_g * E_g * E_g / 3.0f;
- const float V_e = knode->energy_variance;
-
- const float total_variance = V_e * V_g + V_e * E_g * E_g + E_e * E_e * V_g;
- const float normalized_variance = sqrt(sqrt(1.0f / (1.0f + sqrt(total_variance))));
- return (normalized_variance < splitting_threshold);
-}
-
template<bool in_volume_segment>
ccl_device void light_tree_node_importance(KernelGlobals kg,
const float3 P,
@@ -561,7 +482,6 @@ ccl_device_inline bool get_left_probability(KernelGlobals kg,
template<bool in_volume_segment>
ccl_device bool light_tree_sample(KernelGlobals kg,
- ccl_private const RNGState *rng_state,
ccl_private float *randu,
const float randv,
const float time,
@@ -574,113 +494,56 @@ ccl_device bool light_tree_sample(KernelGlobals kg,
ccl_private LightSample *ls,
ccl_private float *pdf_factor)
{
- /* We keep track of the currently selected primitive and its weight,
- * as well as the total weight as part of the weighted reservoir sampling. */
- int current_light = -1;
- float current_reservoir_weight = -1.0f;
- float total_reservoir_weight = 0.0f;
- float pdf_node_emitter_selection = 1.0f;
-
- /* We need a stack to substitute for recursion. */
- const int stack_size = 32;
- int stack[stack_size];
- float pdfs_node_selection[stack_size];
- int stack_index = 0;
- stack[0] = 0;
- pdfs_node_selection[0] = 1.0f;
-
- /* First traverse the light tree until a leaf node is reached.
- * Also keep track of the probability of traversing to a given node,
- * so that we can scale our PDF accordingly later. */
- while (stack_index >= 0) {
- const float pdf_node_selection = pdfs_node_selection[stack_index];
- const int index = stack[stack_index];
- const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, index);
-
- /* If we're at a leaf node, we choose a primitive. Otherwise, we check if we should split
- * or traverse down the light tree. */
- if (knode->child_index <= 0) {
- float pdf_emitter_selection = 1.0f;
- const int selected_light = light_tree_cluster_select_emitter<in_volume_segment>(
- kg, randu, P, N_or_D, t, has_transmission, knode, &pdf_emitter_selection);
+ int selected_light = -1;
+ float pdf_emitter_selection = 1.0f;
- if (selected_light < 0) {
- stack_index--;
- continue;
- }
+ int node_index = 0; /* root node */
- const float light_reservoir_weight = light_tree_emitter_reservoir_weight(
- kg, P, N_or_D, selected_light);
+ /* Traverse the light tree until a leaf node is reached. */
+ while (true) {
+ const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index);
- /* TODO: make pdf_node_emitter_selection part of the light_reservoir_weight, otherwise result
- * is suboptimal, or disable splitting and remove reservoir-related code . */
- if (light_reservoir_weight == 0.0f) {
- stack_index--;
- continue;
- }
- total_reservoir_weight +
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list