Commit: 94af4326e3fc22fe1b229a3e2435fb6ccfe36ce9
Author: Erik Englesson
Date:   Thu Aug 2 19:21:01 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rB94af4326e3fc22fe1b229a3e2435fb6ccfe36ce9

Cycles: Light tree: volume and MIS fixes

Now using a more reliable way of knowing if a shading point
is inside or on the boundary of a volume.

Fixed a bug in light_background_sample() that used an index
into the lights array as an index into the distribution array.

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

M       intern/cycles/kernel/kernel_emission.h
M       intern/cycles/kernel/kernel_light.h
M       intern/cycles/kernel/kernel_path.h
M       intern/cycles/kernel/kernel_path_branched.h
M       intern/cycles/kernel/kernel_path_surface.h
M       intern/cycles/kernel/kernel_path_volume.h
M       intern/cycles/kernel/kernel_types.h
M       
intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h

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

diff --git a/intern/cycles/kernel/kernel_emission.h 
b/intern/cycles/kernel/kernel_emission.h
index 8fe773f5a4b..95aebe1246f 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -198,7 +198,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg,
 
 /* Indirect Primitive Emission */
 
-ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, 
ShaderData *sd, float t, float3 P, float3 N, int path_flag, float bsdf_pdf, 
bool is_volume_boundary)
+ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, 
ShaderData *sd, float t, float3 P, float3 N, int path_flag, float bsdf_pdf, 
bool has_volume)
 {
        /* evaluate emissive closure */
        float3 L = shader_emissive_eval(kg, sd);
@@ -212,7 +212,7 @@ ccl_device_noinline float3 
indirect_primitive_emission(KernelGlobals *kg, Shader
                /* multiple importance sampling, get triangle light pdf,
                 * and compute weight with respect to BSDF pdf */
                float pdf = triangle_light_pdf(kg, sd, t);
-               pdf *= light_distribution_pdf(kg, P, N, sd->prim, sd->object, 
is_volume_boundary);
+               pdf *= light_distribution_pdf(kg, P, N, sd->prim, sd->object, 
has_volume);
                float mis_weight = power_heuristic(bsdf_pdf, pdf);
 
                return L*mis_weight;
@@ -260,7 +260,7 @@ ccl_device_noinline bool 
indirect_lamp_emission(KernelGlobals *kg,
                                                ls.t,
                                                ray->time);
 
-               bool is_inside_volume = false;
+               bool has_volume = false;
 #ifdef __VOLUME__
                if(state->volume_stack[0].shader != SHADER_NONE) {
                        /* shadow attenuation */
@@ -271,9 +271,7 @@ ccl_device_noinline bool 
indirect_lamp_emission(KernelGlobals *kg,
                        L *= volume_tp;
                }
 
-               if((state->volume_bounce > 0 || (state->volume_bounds_bounce > 
0)) && (emission_sd->flag & SD_HAS_VOLUME)) {
-                       is_inside_volume = true;
-               }
+               has_volume = ((emission_sd->flag & SD_HAS_VOLUME) != 0);
 #endif
 
                if(!(state->flag & PATH_RAY_MIS_SKIP)) {
@@ -281,7 +279,7 @@ ccl_device_noinline bool 
indirect_lamp_emission(KernelGlobals *kg,
                         * and compute weight with respect to BSDF pdf */
 
                        /* multiply with light picking probablity to pdf */
-                       ls.pdf *= light_distribution_pdf(kg, ray->P, N, 
~ls.lamp, -1, is_inside_volume);
+                       ls.pdf *= light_distribution_pdf(kg, ray->P, N, 
~ls.lamp, -1, has_volume);
                        float mis_weight = power_heuristic(state->ray_pdf, 
ls.pdf);
                        L *= mis_weight;
                }
@@ -315,6 +313,11 @@ ccl_device_noinline float3 
indirect_background(KernelGlobals *kg,
                        return make_float3(0.0f, 0.0f, 0.0f);
        }
 
+       bool has_volume = false;
+#if defined(__BACKGROUND_MIS__) && defined(__VOLUME__)
+       /* This has to be done before shader_setup_* below. */
+       has_volume = ((emission_sd->flag & SD_HAS_VOLUME) != 0);
+#endif
        /* evaluate background closure */
 #  ifdef __SPLIT_KERNEL__
        Ray priv_ray = *ray;
@@ -340,15 +343,6 @@ ccl_device_noinline float3 
indirect_background(KernelGlobals *kg,
                N_pick = state->ray_N;
        }
 
-       /* todo: looks like this only happens for volume boundaries and not 
inside.
-        * is this expected? */
-       bool is_on_volume_boundary = false;
-#ifdef __VOLUME__
-       if((state->volume_bounce > 0) || (state->volume_bounds_bounce > 0)) {
-               is_on_volume_boundary = true;
-       }
-#endif
-
        /* check if background light exists or if we should skip pdf */
        int res_x = kernel_data.integrator.pdf_background_res_x;
 
@@ -357,7 +351,7 @@ ccl_device_noinline float3 
indirect_background(KernelGlobals *kg,
                 * direction, and compute weight with respect to BSDF pdf */
                float pdf = background_light_pdf(kg, P_pick, ray->D);
                int background_index = 
kernel_data.integrator.background_light_index;
-               pdf *= light_distribution_pdf(kg, P_pick, N_pick, 
~background_index, -1, is_on_volume_boundary);
+               pdf *= light_distribution_pdf(kg, P_pick, N_pick, 
~background_index, -1, has_volume);
                float mis_weight = power_heuristic(state->ray_pdf, pdf);
 
                return L*mis_weight;
diff --git a/intern/cycles/kernel/kernel_light.h 
b/intern/cycles/kernel/kernel_light.h
index 409831081ae..26f93aba12a 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1256,7 +1256,7 @@ ccl_device void light_distant_sample(KernelGlobals *kg, 
float3 P, float *randu,
 /* picks one of the background lights and computes the probability of picking 
it */
 ccl_device void light_background_sample(KernelGlobals *kg, float3 P, float 
*randu,
                                      int *index, float *pdf){
-       *index = kernel_data.integrator.background_light_index;
+       *index = kernel_tex_fetch(__lamp_to_distribution, 
kernel_data.integrator.background_light_index);
        *pdf = 1.0f;
 }
 
@@ -1464,7 +1464,7 @@ ccl_device float light_bvh_pdf(KernelGlobals *kg, float3 
P, float3 N,
 /* computes the the probability of picking the given light out of all lights */
 ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N,
                                         int prim_id, int object_id,
-                                        bool is_inside_volume)
+                                        bool has_volume)
 {
        /* convert from triangle/lamp to light distribution */
        int distribution_id;
@@ -1479,7 +1479,7 @@ ccl_device float light_distribution_pdf(KernelGlobals 
*kg, float3 P, float3 N,
                      (distribution_id < 
kernel_data.integrator.num_distribution));
 
        /* compute picking pdf for this light */
-       if (kernel_data.integrator.use_light_bvh && !is_inside_volume){
+       if (kernel_data.integrator.use_light_bvh && !has_volume){
                /* find out which group of lights to sample */
                int group;
                if(prim_id >= 0){
@@ -1520,10 +1520,10 @@ ccl_device float light_distribution_pdf(KernelGlobals 
*kg, float3 P, float3 N,
 
 /* picks a light and returns its index and the probability of picking it */
 ccl_device void light_distribution_sample(KernelGlobals *kg, float3 P, float3 
N,
-                                          bool is_in_volume, float *randu,
+                                          bool has_volume, float *randu,
                                           int *index, float *pdf)
 {
-       if (kernel_data.integrator.use_light_bvh && !is_in_volume){
+       if (kernel_data.integrator.use_light_bvh && !has_volume){
                /* sample light type distribution */
                int   group      = light_group_distribution_sample(kg, randu);
                float group_prob = kernel_tex_fetch(__light_group_sample_prob, 
group);
@@ -1592,12 +1592,12 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg,
                                       float3 N,
                                       int bounce,
                                       LightSample *ls,
-                                      bool is_in_volume)
+                                      bool has_volume)
 {
        /* sample index and compute light picking pdf */
        float pdf_factor = 0.0f;
        int index = -1;
-       light_distribution_sample(kg, P, N, is_in_volume, &randu, &index, 
&pdf_factor);
+       light_distribution_sample(kg, P, N, has_volume, &randu, &index, 
&pdf_factor);
 
        if(pdf_factor == 0.0f){
                return false;
diff --git a/intern/cycles/kernel/kernel_path.h 
b/intern/cycles/kernel/kernel_path.h
index 097c5640f54..83283247483 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -286,7 +286,8 @@ ccl_device_forceinline bool kernel_path_shader_apply(
        float3 throughput,
        ShaderData *emission_sd,
        PathRadiance *L,
-       ccl_global float *buffer)
+       ccl_global float *buffer,
+       bool has_volume)
 {
 #ifdef __SHADOW_TRICKS__
        if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
@@ -363,8 +364,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(
 
                float ray_length = state->ray_t + sd->ray_length;
 
-               bool is_volume_boundary = (state->volume_bounce > 0) || 
(state->volume_bounds_bounce > 0);
-               float3 emission = indirect_primitive_emission(kg, sd, 
ray_length, P_pick, N_pick, state->flag, state->ray_pdf, is_volume_boundary);
+               float3 emission = indirect_primitive_emission(kg, sd, 
ray_length, P_pick, N_pick, state->flag, state->ray_pdf, has_volume);
                path_radiance_accum_emission(L, state, throughput, emission);
        }
 #endif  /* __EMISSION__ */
@@ -477,6 +477,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                }
 
                /* Setup shader data. */
+               bool has_volume = (sd->flag & SD_HAS_VOLUME) != 0;
                shader_setup_from_ray(kg, sd, &isect, ray);
 
                /* Skip most work for volume bounding surface. */
@@ -496,7 +497,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                                             throughput,
                                             emission_sd,
                                             L,
-                                            NULL))
+                                            NULL,
+                                            has_volume))
                {
                        break;
                }
@@ -651,6 +653,7 @@ ccl_device_forceinline void kernel_path_integrate(
                }
 
                /* Setup shader data. */
+               bool has_volume = (sd.flag & SD_HAS_VOLUME) != 0;
                shader_setup_from_ray(kg, &sd, &isect, ray);
 
                /* Skip most work for volume bounding surface. */
@@ -670,7 +673,8 @@ ccl_device_forceinline void kernel_path_integrate(
                                             throughput,
                                             emission_sd,
                                             L,
-                                            buffer))
+                                            buffer,
+                                            has_volume))
                {
                        break;
                }
diff --git a/intern/cycles/kernel/kernel_path_branched.h 
b/intern/cycles/kernel/kernel_path_branched.h
index d9e1433acda..b1c815b6a15 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -463,6 +463,7 @@ ccl_device void 
kernel_branched_path_integrate(KernelGlobals *kg,
         * Indirect bounces are handled in 
kernel_branched_path_surface_indirect_light().
         */
        for(;;) {
+
                /* Find intersection with objects in scene. */
                Intersection isect;
                bool hit = kernel_path_scene_intersect(kg, &state, &ray, 
&isect, L);
@@ -488,6 +489,7 @@ ccl_device void 
kernel_branched_path_integrate(KernelGlobals *kg,
                }
 
                /* Setup and evaluate shader. */
+               bool has_volume = (sd.flag & SD_HAS_VOLUME) != 0;
                shader_setup_from_ray(kg, &sd, &isect, &ray);
 
                /* Skip most work for volume bounding surface. */
@@ -50

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to