Commit: e8e0669785cdd3b88f431e560a7323ae45958142
Author: Erik Englesson
Date:   Wed Aug 1 09:40:14 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rBe8e0669785cdd3b88f431e560a7323ae45958142

Cycles: Picking position and normal fix for MIS

The picking position and normal has been changed to
use the position and normal from the last
non-transparent bounce.

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

M       intern/cycles/kernel/kernel_bake.h
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_types.h
M       intern/cycles/kernel/kernel_volume.h
M       intern/cycles/kernel/split/kernel_do_volume.h

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

diff --git a/intern/cycles/kernel/kernel_bake.h 
b/intern/cycles/kernel/kernel_bake.h
index b6d01fe0987..75e1963a402 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -69,7 +69,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
                /* sample emission */
                if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & 
SD_EMISSION)) {
                        bool is_volume_boundary = (state.volume_bounce > 0) || 
(state.volume_bounds_bounce > 0);
-                       float3 emission = indirect_primitive_emission(kg, sd, 
0.0f, state.flag, state.ray_pdf, is_volume_boundary);
+                       float3 emission = indirect_primitive_emission(kg, sd, 
0.0f, sd->P_pick, sd->N_pick, state.flag, state.ray_pdf, is_volume_boundary);
                        path_radiance_accum_emission(&L_sample, &state, 
throughput, emission);
                }
 
@@ -143,7 +143,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
                /* sample emission */
                if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & 
SD_EMISSION)) {
                        bool is_volume_boundary = (state.volume_bounce > 0) || 
(state.volume_bounds_bounce > 0);
-                       float3 emission = indirect_primitive_emission(kg, sd, 
0.0f, state.flag, state.ray_pdf, is_volume_boundary);
+                       float3 emission = indirect_primitive_emission(kg, sd, 
0.0f, sd->P_pick, sd->N_pick, state.flag, state.ray_pdf, is_volume_boundary);
                        path_radiance_accum_emission(&L_sample, &state, 
throughput, emission);
                }
 
diff --git a/intern/cycles/kernel/kernel_emission.h 
b/intern/cycles/kernel/kernel_emission.h
index 0f54ea66205..8fe773f5a4b 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, 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 is_volume_boundary)
 {
        /* 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, sd->P_pick, sd->N_pick, 
sd->prim, sd->object, is_volume_boundary);
+               pdf *= light_distribution_pdf(kg, P, N, sd->prim, sd->object, 
is_volume_boundary);
                float mis_weight = power_heuristic(bsdf_pdf, pdf);
 
                return L*mis_weight;
@@ -226,6 +226,7 @@ ccl_device_noinline float3 
indirect_primitive_emission(KernelGlobals *kg, Shader
 ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
                                                 ShaderData *emission_sd,
                                                 ccl_addr_space PathState 
*state,
+                                                float3 N,
                                                 Ray *ray,
                                                 float3 *emission)
 {
@@ -280,7 +281,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, 
emission_sd->N_pick, ~ls.lamp, -1, is_inside_volume);
+                       ls.pdf *= light_distribution_pdf(kg, ray->P, N, 
~ls.lamp, -1, is_inside_volume);
                        float mis_weight = power_heuristic(state->ray_pdf, 
ls.pdf);
                        L *= mis_weight;
                }
@@ -328,6 +329,17 @@ ccl_device_noinline float3 
indirect_background(KernelGlobals *kg,
 
 #ifdef __BACKGROUND_MIS__
 
+       /* consider shading point at previous non-transparent bounce */
+       float3 P_pick;
+       float3 N_pick;
+       if(state->ray_t == 0.0f){ // Non-transparent bounce
+               P_pick = emission_sd->P_pick;
+               N_pick = emission_sd->N_pick;
+       } else { // Transparent bounce
+               P_pick = ray->P - state->ray_t*ray->D;
+               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;
@@ -343,9 +355,9 @@ ccl_device_noinline float3 
indirect_background(KernelGlobals *kg,
        if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
                /* multiple importance sampling, get background light pdf for 
ray
                 * direction, and compute weight with respect to BSDF pdf */
-               float pdf = background_light_pdf(kg, ray->P, ray->D);
+               float pdf = background_light_pdf(kg, P_pick, ray->D);
                int background_index = 
kernel_data.integrator.background_light_index;
-               pdf *= light_distribution_pdf(kg, ray->P, N, ~background_index, 
-1, is_on_volume_boundary);
+               pdf *= light_distribution_pdf(kg, P_pick, N_pick, 
~background_index, -1, is_on_volume_boundary);
                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 2e494a884dd..409831081ae 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -35,11 +35,13 @@ typedef struct LightSample {
 
 /* This normal is used in the light picking when using the light tree */
 ccl_device void kernel_update_light_picking(
-       ShaderData *sd)
+       ShaderData *sd,
+       ccl_addr_space PathState *state)
 {
        bool transmission = false;
        bool reflective = false;
        bool glass = false;
+       bool transparent = false;
        for(int i = 0; i < sd->num_closure; ++i){
                const ShaderClosure *sc = &sd->closure[i];
                if(CLOSURE_IS_GLASS(sc->type)){
@@ -51,6 +53,9 @@ ccl_device void kernel_update_light_picking(
                if(CLOSURE_IS_BSDF_DIFFUSE(sc->type) || 
CLOSURE_IS_BSDF_GLOSSY(sc->type)){
                        reflective = true;
                }
+               if(CLOSURE_IS_BSDF_TRANSPARENT(sc->type)){
+                       transparent = true;
+               }
        }
 
        if(glass || (reflective && transmission)){
@@ -62,6 +67,15 @@ ccl_device void kernel_update_light_picking(
        }
 
        sd->P_pick = sd->P;
+
+#if defined(__LAMP_MIS__) || defined(__EMISSION__) || 
defined(__BACKGROUND_MIS__)
+       if(!transparent){
+               state->ray_N = sd->N_pick;
+       }
+       // todo: what if there is a transparent but it is not this BSDF that is
+       // sampled in surface_bounce() ?
+#endif
+
 }
 
 /* Area light sampling */
diff --git a/intern/cycles/kernel/kernel_path.h 
b/intern/cycles/kernel/kernel_path.h
index 01d3d0e8129..097c5640f54 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -109,18 +109,25 @@ ccl_device_forceinline void kernel_path_lamp_emission(
        if(kernel_data.integrator.use_lamp_mis && !(state->flag & 
PATH_RAY_CAMERA)) {
                /* ray starting from previous non-transparent bounce */
                Ray light_ray;
+               float3 N_pick;
+               if(state->ray_t == 0.0f){
+                       light_ray.P = emission_sd->P_pick;
+                       N_pick = emission_sd->N_pick;
+               } else {
+                       /* Current bounce was on a transparent surface */
+                       light_ray.P = ray->P - state->ray_t*ray->D;
+                       N_pick = state->ray_N;
+               }
 
-               light_ray.P = ray->P - state->ray_t*ray->D;
-               state->ray_t += isect->t;
                light_ray.D = ray->D;
-               light_ray.t = state->ray_t;
+               light_ray.t = state->ray_t + isect->t;
                light_ray.time = ray->time;
                light_ray.dD = ray->dD;
                light_ray.dP = ray->dP;
 
                /* intersect with lamp */
                float3 emission;
-               if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, 
&emission))
+               if(indirect_lamp_emission(kg, emission_sd, state, N_pick, 
&light_ray, &emission))
                        path_radiance_accum_emission(L, state, throughput, 
emission);
        }
 #endif  /* __LAMP_MIS__ */
@@ -199,7 +206,7 @@ ccl_device_forceinline VolumeIntegrateResult 
kernel_path_volume(
                kernel_volume_decoupled_record(kg, state,
                        &volume_ray, sd, &volume_segment, heterogeneous);
 
-               kernel_update_light_picking(sd);
+               kernel_update_light_picking(sd, state);
 
                volume_segment.sampling_method = sampling_method;
 
@@ -249,7 +256,7 @@ ccl_device_forceinline VolumeIntegrateResult 
kernel_path_volume(
                VolumeIntegrateResult result = kernel_volume_integrate(
                        kg, state, sd, &volume_ray, L, throughput, 
heterogeneous);
 
-               kernel_update_light_picking(sd);
+               kernel_update_light_picking(sd, state);
 
 #  ifdef __VOLUME_SCATTER__
                if(result == VOLUME_PATH_SCATTERED) {
@@ -342,12 +349,30 @@ ccl_device_forceinline bool kernel_path_shader_apply(
 #ifdef __EMISSION__
        /* emission */
        if(sd->flag & SD_EMISSION) {
+
+               /* ray starting from previous non-transparent bounce */
+               float3 P_pick;
+               float3 N_pick;
+               if(state->ray_t == 0.0f){ // Non-transparent bounce
+                       P_pick = sd->P_pick;
+                       N_pick = sd->N_pick;
+               } else { // Transparent bounce
+                       P_pick = ray->P - state->ray_t*ray->D;
+                       N_pick = state->ray_N;
+               }
+
+               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, 
sd->ray_length, 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, is_volume_boundary);
                path_radiance_accum_emission(L, state, throughput, emission);
        }
 #endif  /* __EMISSION__ */
 
+#if defined(__LAMP_MIS__) || defined(__EMISSION__) || 
defined(__BACKGROUND_MIS__)
+       state->ray_t += sd->ray_length;
+#endif
+
        return true;
 }
 
@@ -493,7 +518,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                        throughput /= probability;
                }
 
-               kernel_update_light_picking(sd);
+               kernel_update_light_picking(sd, state);
 
                kernel_update_denoising_features(kg, sd, state, L);
 
@@ -588,6 +613,7 @@ ccl_device_forceinline void kernel_path_integrate(
 
        /* path iteration */
        for(;;) {
+
                /* Find intersection with objects in scene. */
                Intersection isect;
                bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, 
L);
@@ -665,7 +691,7 @@ ccl_device_forceinline void kernel_path_integrate(
                        throughput /= probability;
                }
 
-               kernel_update_light_picking(&sd);
+               kernel_update_light_picking(&sd, state);
 
                kernel_update_denoising_features(kg, &sd, state, L);
 
@@ -704,6 +730,7 @@ ccl_device_forceinline voi

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to