From b48adbc9d79c55b8dac368865098b34c7536d74f Mon Sep 17 00:00:00 2001 From: Olivier Maury Date: Tue, 17 May 2022 20:16:52 +0200 Subject: Fix T97921: Cycles MNEE issue with light path nodes Ensure the correct total/diffuse/transmission depth is set when evaluating shaders for MNEE, consistent with regular light shader evaluation. Differential Revision: https://developer.blender.org/D14902 --- intern/cycles/kernel/integrator/mnee.h | 32 +++++++++++++++++++++---- intern/cycles/kernel/integrator/shade_surface.h | 4 ++-- 2 files changed, 30 insertions(+), 6 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 7b86c660380..e924f408d59 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -813,6 +813,15 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, * and keep pdf in vertex area measure */ mnee_update_light_sample(kg, vertices[vertex_count - 1].p, ls); + /* Save state path bounce info in case a light path node is used in the refractive interface or + * light shader graph. */ + const int transmission_bounce = INTEGRATOR_STATE(state, path, transmission_bounce); + const int diffuse_bounce = INTEGRATOR_STATE(state, path, diffuse_bounce); + const int bounce = INTEGRATOR_STATE(state, path, bounce); + + /* Set diffuse bounce info . */ + INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = diffuse_bounce + 1; + /* Evaluate light sample * in case the light has a node-based shader: * 1. sd_mnee will be used to store light data, which is why we need to do @@ -820,6 +829,12 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, * interface data at the end of the call for the shadow ray setup to work. * 2. ls needs to contain the last interface data for the light shader to * evaluate properly */ + + /* Set bounce info in case a light path node is used in the light shader graph. */ + INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce + vertex_count - + 1; + INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + vertex_count; + float3 light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time); bsdf_eval_mul3(throughput, light_eval / ls->pdf); @@ -891,6 +906,11 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, false, LAMP_NONE); + /* Set bounce info in case a light path node is used in the refractive interface + * shader graph. */ + INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce + vi; + INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + 1 + vi; + /* Evaluate shader nodes at solution vi. */ shader_eval_surface( kg, state, sd_mnee, NULL, PATH_RAY_DIFFUSE, true); @@ -907,6 +927,11 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, bsdf_eval_mul3(throughput, bsdf_contribution); } + /* Restore original state path bounce info. */ + INTEGRATOR_STATE_WRITE(state, path, transmission_bounce) = transmission_bounce; + INTEGRATOR_STATE_WRITE(state, path, diffuse_bounce) = diffuse_bounce; + INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce; + return true; } @@ -1036,18 +1061,17 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg, return 0; /* Check whether the transmission depth limit is reached before continuing. */ - if (INTEGRATOR_STATE(state, path, transmission_bounce) + vertex_count >= + if ((INTEGRATOR_STATE(state, path, transmission_bounce) + vertex_count - 1) >= kernel_data.integrator.max_transmission_bounce) return 0; /* Check whether the diffuse depth limit is reached before continuing. */ - if (INTEGRATOR_STATE(state, path, diffuse_bounce) + 1 >= + if ((INTEGRATOR_STATE(state, path, diffuse_bounce) + 1) >= kernel_data.integrator.max_diffuse_bounce) return 0; /* Check whether the overall depth limit is reached before continuing. */ - if (INTEGRATOR_STATE(state, path, bounce) + 1 + vertex_count >= - kernel_data.integrator.max_bounce) + if ((INTEGRATOR_STATE(state, path, bounce) + vertex_count) >= kernel_data.integrator.max_bounce) return 0; /* Mark the manifold walk valid to turn off mollification regardless of how successful the walk diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 859c314b088..896e81b80ff 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -253,13 +253,13 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, # ifdef __MNEE__ if (mnee_vertex_count > 0) { INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = - INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count; + INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count - 1; INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1; INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, - bounce) = INTEGRATOR_STATE(state, path, bounce) + 1 + mnee_vertex_count; + bounce) = INTEGRATOR_STATE(state, path, bounce) + mnee_vertex_count; } else # endif -- cgit v1.2.3