[Bf-blender-cvs] [110eb230052] master: Fix T97056: Cycles MNEE caustics treated as direct instead of indirect light

Christophe Hery noreply at git.blender.org
Thu Apr 28 18:00:15 CEST 2022


Commit: 110eb2300526519681b44e154473b5fd087d191e
Author: Christophe Hery
Date:   Thu Apr 28 17:52:32 2022 +0200
Branches: master
https://developer.blender.org/rB110eb2300526519681b44e154473b5fd087d191e

Fix T97056: Cycles MNEE caustics treated as direct instead of indirect light

This fixes wrong render passs and bounce limits.

Differential Revision: https://developer.blender.org/D14737

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

M	intern/cycles/kernel/integrator/mnee.h
M	intern/cycles/kernel/integrator/shade_surface.h

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

diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index c523da8d3be..455d15b28c2 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -948,13 +948,13 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
 }
 
 /* Manifold next event estimation path sampling. */
-ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
-                                                    IntegratorState state,
-                                                    ccl_private ShaderData *sd,
-                                                    ccl_private ShaderData *sd_mnee,
-                                                    ccl_private const RNGState *rng_state,
-                                                    ccl_private LightSample *ls,
-                                                    ccl_private BsdfEval *throughput)
+ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg,
+                                                   IntegratorState state,
+                                                   ccl_private ShaderData *sd,
+                                                   ccl_private ShaderData *sd_mnee,
+                                                   ccl_private const RNGState *rng_state,
+                                                   ccl_private LightSample *ls,
+                                                   ccl_private BsdfEval *throughput)
 {
   /*
    * 1. send seed ray from shading point to light sample position (or along sampled light
@@ -998,11 +998,11 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
 
       /* Do we have enough slots. */
       if (vertex_count >= MNEE_MAX_CAUSTIC_CASTERS)
-        return false;
+        return 0;
 
       /* Reject caster if it is not a triangles mesh. */
       if (!(probe_isect.type & PRIMITIVE_TRIANGLE))
-        return false;
+        return 0;
 
       ccl_private ManifoldVertex &mv = vertices[vertex_count++];
 
@@ -1013,7 +1013,7 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
        * differential geometry can be created at any point on the surface which is not possible if
        * normals are not smooth. */
       if (!(sd_mnee->shader & SHADER_SMOOTH_NORMAL))
-        return false;
+        return 0;
 
       /* Last bool argument is the MNEE flag (for TINY_MAX_CLOSURE cap in kernel_shader.h). */
       shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW>(
@@ -1051,7 +1051,7 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
         }
       }
       if (!found_transimissive_microfacet_bsdf)
-        return false;
+        return 0;
     }
 
     probe_ray.self.object = probe_isect.object;
@@ -1065,23 +1065,22 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
   INTEGRATOR_STATE_WRITE(state, path, mnee) &= ~PATH_MNEE_VALID;
 
   if (vertex_count == 0)
-    return false;
+    return 0;
 
   /* Check whether the transmission depth limit is reached before continuing. */
-  const int transmission_bounce = INTEGRATOR_STATE(state, path, transmission_bounce) +
-                                  vertex_count;
-  if (transmission_bounce >= kernel_data.integrator.max_transmission_bounce)
-    return false;
+  if (INTEGRATOR_STATE(state, path, transmission_bounce) + vertex_count >=
+      kernel_data.integrator.max_transmission_bounce)
+    return 0;
 
   /* Check whether the diffuse depth limit is reached before continuing. */
-  const int diffuse_bounce = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1;
-  if (diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce)
-    return false;
+  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. */
-  const int bounce = INTEGRATOR_STATE(state, path, bounce) + diffuse_bounce + transmission_bounce;
-  if (bounce >= kernel_data.integrator.max_bounce)
-    return false;
+  if (INTEGRATOR_STATE(state, path, bounce) + 1 + vertex_count >=
+      kernel_data.integrator.max_bounce)
+    return 0;
 
   /* Mark the manifold walk valid to turn off mollification regardless of how successful the walk
    * is: this is noticeable when another mnee is performed deeper in the path, for an internally
@@ -1095,12 +1094,12 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg,
   if (mnee_newton_solver(kg, sd, sd_mnee, ls, vertex_count, vertices)) {
     /* 3. If a solution exists, calculate contribution of the corresponding path */
     if (!mnee_path_contribution(kg, state, sd, sd_mnee, ls, vertex_count, vertices, throughput))
-      return false;
+      return 0;
 
-    return true;
+    return vertex_count;
   }
 
-  return false;
+  return 0;
 }
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 55bb08044ae..1df84ba765e 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -136,7 +136,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
   const bool is_transmission = shader_bsdf_is_transmission(sd, ls.D);
 
 #  ifdef __MNEE__
-  bool skip_nee = false;
+  int mnee_vertex_count = 0;
   IF_KERNEL_NODES_FEATURE(RAYTRACE)
   {
     if (ls.lamp != LAMP_NONE) {
@@ -149,12 +149,12 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
 
         /* Are we on a caustic receiver? */
         if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER))
-          skip_nee = kernel_path_mnee_sample(
+          mnee_vertex_count = kernel_path_mnee_sample(
               kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
       }
     }
   }
-  if (skip_nee) {
+  if (mnee_vertex_count > 0) {
     /* Create shadow ray after successful manifold walk:
      * emission_sd contains the last interface intersection and
      * the light sample ls has been updated */
@@ -211,8 +211,6 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
   INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 1, prim) = ray.self.light_prim;
 
   /* Copy state from main path to shadow path. */
-  const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce);
-  const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
   uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
   shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
   const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
@@ -246,14 +244,34 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
   INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, sample) = INTEGRATOR_STATE(
       state, path, sample);
   INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
-  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = bounce;
-  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = transparent_bounce;
-  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(
-      state, path, diffuse_bounce);
+
+  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = INTEGRATOR_STATE(
+      state, path, transparent_bounce);
   INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, glossy_bounce) = INTEGRATOR_STATE(
       state, path, glossy_bounce);
-  INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = INTEGRATOR_STATE(
-      state, path, transmission_bounce);
+
+#  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_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;
+  }
+  else
+#  endif
+  {
+    INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = INTEGRATOR_STATE(
+        state, path, transmission_bounce);
+    INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(
+        state, path, diffuse_bounce);
+    INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = INTEGRATOR_STATE(
+        state, path, bounce);
+  }
+
   INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
 
   if (kernel_data.kernel_features & KERNEL_FEATURE_SHADOW_PASS) {



More information about the Bf-blender-cvs mailing list