Commit: ff4833a6b395eef84e2a60a32f934c2f3a0e7d63
Author: Erik Englesson
Date:   Thu Jul 12 16:40:58 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rBff4833a6b395eef84e2a60a32f934c2f3a0e7d63

Cycles: Bug fixes

- Stopping recursive tree traversal if
  negative PDFs are encountered.

- accum_light_tree_contribution() now
  takes a scale factor as input which
  is passed through to accum_light_contribution

- light_bvh_sample now changes randu. This
  is similar to the other *_sample functions.
  This fixed a bug where recursive traversal
  with no splitting gave a different result
  compared to just using light_sample.

===================================================================

M       intern/cycles/kernel/kernel_light.h
M       intern/cycles/kernel/kernel_path_surface.h

===================================================================

diff --git a/intern/cycles/kernel/kernel_light.h 
b/intern/cycles/kernel/kernel_light.h
index 8346aea1386..73e12fe4824 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1205,25 +1205,24 @@ ccl_device void light_background_sample(KernelGlobals 
*kg, float3 P, float *rand
 /* picks a light from the light BVH and returns its index and the probability 
of
  * picking this light. */
 ccl_device void light_bvh_sample(KernelGlobals *kg, float3 P, float3 N,
-                                 float randu, int *index, float *pdf_factor)
+                                 float *randu, int *index, float *pdf_factor)
 {
        int sampled_index = -1;
        *pdf_factor = 1.0f;
 
-       /* read in first part of root node of light BVH */
-       int secondChildOffset, distribution_id, num_emitters;
-       update_parent_node(kg, 0, &secondChildOffset, &distribution_id, 
&num_emitters);
-
        int offset = 0;
+       int secondChildOffset, distribution_id, num_emitters;
        do{
 
+               /* read in first part of node of light BVH */
+               update_parent_node(kg, offset, &secondChildOffset, 
&distribution_id, &num_emitters);
+
                /* Found a leaf - Choose which light to use */
                if(secondChildOffset == -1){ // Found a leaf
                        if(num_emitters == 1){
-
                                sampled_index = distribution_id;
                        } else { // Leaf with several lights. Pick one randomly.
-                               int light = min((int)(randu* 
(float)num_emitters), num_emitters-1);
+                               int light = min((int)(*randu * 
(float)num_emitters), num_emitters-1);
                                sampled_index = distribution_id +light;
                                *pdf_factor *= 1.0f / (float)num_emitters;
                        }
@@ -1235,33 +1234,28 @@ ccl_device void light_bvh_sample(KernelGlobals *kg, 
float3 P, float3 N,
                        int child_offsetR = 4*secondChildOffset;
                        float I_L = calc_node_importance(kg, P, N, 
child_offsetL);
                        float I_R = calc_node_importance(kg, P, N, 
child_offsetR);
-                       if( (I_L==0.0f) && (I_R == 0.0f)){
+                       if((I_L == 0.0f) && (I_R == 0.0f)){
                                *pdf_factor = 0.0f;
                                break;
                        }
+
                        float P_L = I_L / ( I_L + I_R);
 
                        /* choose which node to go down */
-                       if(randu <= P_L){ // Going down left node
+                       if(*randu <= P_L){ // Going down left node
                                /* rescale random number */
-                               randu = randu / P_L;
+                               *randu = *randu / P_L;
 
                                offset = child_offsetL;
                                *pdf_factor *= P_L;
                        } else { // Going down right node
                                /* rescale random number */
-                               randu = (randu * (I_L + I_R) - I_L)/I_R;
+                               *randu = (*randu * (I_L + I_R) - I_L)/I_R;
 
                                offset = child_offsetR;
                                *pdf_factor *= 1.0f - P_L;
                        }
-
-                       /* update parent node info for next iteration */
-                       update_parent_node(kg, offset, &secondChildOffset,
-                                          &distribution_id, &num_emitters);
                }
-
-
        } while(true);
 
        *index = sampled_index;
@@ -1417,7 +1411,7 @@ ccl_device void light_distribution_sample(KernelGlobals 
*kg, float3 P, float3 N,
                float group_prob = kernel_tex_fetch(__light_group_sample_prob, 
group);
 
                if(group == LIGHTGROUP_TREE){
-                       light_bvh_sample(kg, P, N, *randu, index, pdf);
+                       light_bvh_sample(kg, P, N, randu, index, pdf);
                } else if(group == LIGHTGROUP_DISTANT) {
                        light_distant_sample(kg, P, randu, index, pdf);
                } else if(group == LIGHTGROUP_BACKGROUND) {
diff --git a/intern/cycles/kernel/kernel_path_surface.h 
b/intern/cycles/kernel/kernel_path_surface.h
index 77ca9f7e3d7..8e7697af2ea 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -121,7 +121,8 @@ ccl_device bool split(KernelGlobals *kg, float3 P, int 
node_offset)
 ccl_device void accum_light_tree_contribution(KernelGlobals *kg, float randu,
                                               float randv, int offset,
                                               float pdf_factor, bool can_split,
-                                              float3 throughput, PathRadiance 
*L,
+                                              float3 throughput, float 
scale_factor,
+                                              PathRadiance *L,
                                               ccl_addr_space PathState * state,
                                               ShaderData *sd, ShaderData 
*emission_sd,
                                               int *num_lights,
@@ -139,7 +140,6 @@ ccl_device void accum_light_tree_contribution(KernelGlobals 
*kg, float randu,
 
        /* Found a leaf - Choose which light to use */
        if(secondChildOffset == -1){ // Found a leaf
-
                if(num_emitters == 1){
                        (*num_lights)++; // used for debugging purposes
                        // Distribution_id is the index
@@ -150,10 +150,7 @@ ccl_device void 
accum_light_tree_contribution(KernelGlobals *kg, float randu,
                        /* combine pdfs */
                        ls.pdf *= pdf_factor;
 
-                       if(ls.pdf == 0.0f){
-                               return;
-                       }
-
+                       if(ls.pdf <= 0.0f) return;
 
                        Ray light_ray;
                        BsdfEval L_light;
@@ -161,7 +158,8 @@ ccl_device void accum_light_tree_contribution(KernelGlobals 
*kg, float randu,
                        float terminate = path_state_rng_light_termination(kg, 
state);
                        accum_light_contribution(kg, sd, emission_sd, &ls, 
state,
                                                 &light_ray, &L_light, L, 
&is_lamp,
-                                                terminate, throughput, 1.0f);
+                                                terminate, throughput, 
scale_factor);
+
 
                } // TODO: do else, i.e. with several lights per node
 
@@ -175,11 +173,15 @@ ccl_device void 
accum_light_tree_contribution(KernelGlobals *kg, float randu,
                if(can_split && split(kg, P, offset)){
                        /* go down both child nodes */
                        accum_light_tree_contribution(kg, randu, randv, 
child_offsetL,
-                                                     pdf_factor, true, 
throughput, L,
-                                                     state, sd, emission_sd, 
num_lights, num_lights_fail);
+                                                     pdf_factor, true, 
throughput,
+                                                     scale_factor, L, state, 
sd,
+                                                     emission_sd, num_lights,
+                                                     num_lights_fail);
                        accum_light_tree_contribution(kg, randu, randv, 
child_offsetR,
-                                                     pdf_factor, true, 
throughput, L,
-                                                     state, sd, emission_sd, 
num_lights, num_lights_fail);
+                                                     pdf_factor, true, 
throughput,
+                                                     scale_factor, L, state, 
sd,
+                                                     emission_sd, num_lights,
+                                                     num_lights_fail);
                } else {
                        /* go down one of the child nodes */
 
@@ -187,13 +189,14 @@ ccl_device void 
accum_light_tree_contribution(KernelGlobals *kg, float randu,
                        float I_L = calc_node_importance(kg, P, N, 
child_offsetL);
                        float I_R = calc_node_importance(kg, P, N, 
child_offsetR);
 
-                       if( (I_L == 0.0f) && (I_R == 0.0f) ){
+                       if((I_L == 0.0f) && (I_R == 0.0f)){
                                (*num_lights_fail)++; // used for debugging 
purposes
                                return;
                        }
 
                        float P_L = I_L / ( I_L + I_R);
 
+                       /* choose which node to go down */
                        if(randu <= P_L){ // Going down left node
                                /* rescale random number */
                                randu = randu / P_L;
@@ -209,8 +212,9 @@ ccl_device void accum_light_tree_contribution(KernelGlobals 
*kg, float randu,
                        }
 
                        accum_light_tree_contribution(kg, randu, randv, offset, 
pdf_factor,
-                                                     false, throughput, L, 
state, sd,
-                                                     emission_sd, num_lights, 
num_lights_fail);
+                                                     false, throughput, 
scale_factor, L,
+                                                     state, sd, emission_sd, 
num_lights,
+                                                     num_lights_fail);
                }
        }
 }
@@ -257,8 +261,9 @@ ccl_device_noinline void 
kernel_branched_path_surface_connect_light(
                        int num_lights = 0;
                        int num_lights_fail = 0;
                        accum_light_tree_contribution(kg, randu, randv, 0, 
group_prob, true,
-                                                     throughput, L, state, sd, 
emission_sd,
-                                                     &num_lights, 
&num_lights_fail);
+                                                     throughput, 
num_samples_adjust, L, // todo: is num_samples_adjust correct here?
+                                                     state, sd, emission_sd, 
&num_lights,
+                                                     &num_lights_fail);
 
                        /*
                        if(num_lights_fail > 1){ // Debug print
@@ -286,7 +291,7 @@ ccl_device_noinline void 
kernel_branched_path_surface_connect_light(
                /* combine pdfs */
                ls.pdf *= group_prob;
 
-               if(ls.pdf == 0.0f) return;
+               if(ls.pdf <= 0.0f) return;
 
                /* accumulate the contribution of this distant/background light 
to L */
                float terminate = path_state_rng_light_termination(kg, state);

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to