[Bf-blender-cvs] [05b342c0a3e] cycles_path_guiding: Fix T103977: Cycles handling ray visibility inconsistent for forward and nee

Sebastian Herholz noreply at git.blender.org
Thu Jan 26 20:15:05 CET 2023


Commit: 05b342c0a3e5a396103caed88ce62b380175977f
Author: Sebastian Herholz
Date:   Fri Jan 20 18:32:41 2023 +0100
Branches: cycles_path_guiding
https://developer.blender.org/rB05b342c0a3e5a396103caed88ce62b380175977f

Fix T103977: Cycles handling ray visibility inconsistent for forward and nee

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

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/integrator/shade_background.h
M	intern/cycles/kernel/integrator/shade_light.h
M	intern/cycles/kernel/integrator/shade_surface.h
M	intern/cycles/kernel/integrator/state_template.h
M	intern/cycles/kernel/integrator/surface_shader.h
A	intern/cycles/kernel/light/visibility.h

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 78bd71988c0..48e9bd7b1ba 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -294,6 +294,7 @@ set(SRC_KERNEL_LIGHT_HEADERS
   light/spot.h
   light/tree.h
   light/triangle.h
+  light/visibility.h
 )
 
 set(SRC_KERNEL_SAMPLE_HEADERS
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 3c01a162d01..dde7284847b 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -11,6 +11,7 @@
 
 #include "kernel/light/light.h"
 #include "kernel/light/sample.h"
+#include "kernel/light/visibility.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -22,20 +23,18 @@ ccl_device Spectrum integrator_eval_background_shader(KernelGlobals kg,
   const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
 
   /* Use visibility flag to skip lights. */
+  Spectrum light_visibility = one_spectrum();
   if (shader & SHADER_EXCLUDE_ANY) {
-    if (((shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
-        ((shader & SHADER_EXCLUDE_GLOSSY) && ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
-                                              (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
-        ((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
-        ((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
+    if (((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
         ((shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
       return zero_spectrum();
+    light_visibility_correction(kg, state, shader, &light_visibility);
   }
 
   /* Use fast constant background color if available. */
   Spectrum L = zero_spectrum();
   if (surface_shader_constant_emission(kg, shader, &L)) {
-    return L;
+    return light_visibility * L;
   }
 
   /* Evaluate background shader. */
@@ -57,7 +56,7 @@ ccl_device Spectrum integrator_eval_background_shader(KernelGlobals kg,
   surface_shader_eval<KERNEL_FEATURE_NODE_MASK_SURFACE_BACKGROUND>(
       kg, state, emission_sd, render_buffer, path_flag | PATH_RAY_EMISSION);
 
-  return surface_shader_background(emission_sd);
+  return light_visibility * surface_shader_background(emission_sd);
 }
 
 ccl_device_inline void integrate_background(KernelGlobals kg,
@@ -138,18 +137,14 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
   for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) {
     if (distant_light_sample_from_intersection(kg, ray_D, lamp, &ls)) {
       /* Use visibility flag to skip lights. */
+      Spectrum light_visibility = one_spectrum();
 #ifdef __PASSES__
       const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
-
       if (ls.shader & SHADER_EXCLUDE_ANY) {
-        if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
-            ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
-             ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
-              (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
-            ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
-            ((ls.shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
+        if (((ls.shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
             ((ls.shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
           return;
+        light_visibility_correction(kg, state, ls.shader, &light_visibility);
       }
 #endif
 
@@ -168,6 +163,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
       ShaderDataTinyStorage emission_sd_storage;
       ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
       Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
+      light_eval *= light_visibility;
       if (is_zero(light_eval)) {
         return;
       }
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 1f09ac4e6d8..f732961f464 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -35,17 +35,13 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
   }
 
   /* Use visibility flag to skip lights. */
+  Spectrum light_visibility = one_spectrum();
 #ifdef __PASSES__
   const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
-
   if (ls.shader & SHADER_EXCLUDE_ANY) {
-    if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
-        ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
-         ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
-          (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
-        ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
-        ((ls.shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
+    if (((ls.shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
       return;
+    light_visibility_correction(kg, state, ls.shader, &light_visibility);
   }
 #endif
 
@@ -54,6 +50,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
   ShaderDataTinyStorage emission_sd_storage;
   ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
   Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
+  light_eval *= light_visibility;
   if (is_zero(light_eval)) {
     return;
   }
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index dbeb5f91ce7..548867c7551 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -16,6 +16,7 @@
 #include "kernel/integrator/volume_stack.h"
 
 #include "kernel/light/sample.h"
+#include "kernel/light/visibility.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -426,6 +427,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
   /* Update throughput. */
   const Spectrum bsdf_weight = bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
   INTEGRATOR_STATE_WRITE(state, path, throughput) *= bsdf_weight;
+  INTEGRATOR_STATE_WRITE(state, path, scatter_eval) = bsdf_eval;
 
   if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
     if (INTEGRATOR_STATE(state, path, bounce) == 0) {
diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h
index 0fc7ed655d3..7b87f1fb046 100644
--- a/intern/cycles/kernel/integrator/state_template.h
+++ b/intern/cycles/kernel/integrator/state_template.h
@@ -48,6 +48,7 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
 KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING)
 /* Throughput. */
 KERNEL_STRUCT_MEMBER(path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING)
+KERNEL_STRUCT_MEMBER(path, BsdfEval, scatter_eval, KERNEL_FEATURE_PATH_TRACING)
 /* Factor to multiple with throughput to get remove any guiding PDFS.
  * Such throughput without guiding PDFS is used for Russian roulette termination. */
 KERNEL_STRUCT_MEMBER(path, float, unguided_throughput, KERNEL_FEATURE_PATH_GUIDING)
diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h
index 86e20e88a0a..ebca9810cbe 100644
--- a/intern/cycles/kernel/integrator/surface_shader.h
+++ b/intern/cycles/kernel/integrator/surface_shader.h
@@ -235,12 +235,14 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg,
     }
 
     if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
-      if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) {
+      if (CLOSURE_IS_BSDF(sc->type)) {
         float bsdf_pdf = 0.0f;
         Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf);
 
         if (bsdf_pdf != 0.0f) {
-          bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
+          if (!_surface_shader_exclude(sc->type, light_shader_flags)) {
+            bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
+          }
           sum_pdf += bsdf_pdf * sc->sample_weight;
         }
       }
diff --git a/intern/cycles/kernel/light/visibility.h b/intern/cycles/kernel/light/visibility.h
new file mode 100644
index 00000000000..fbc66733c7c
--- /dev/null
+++ b/intern/cycles/kernel/light/visibility.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_inline void light_visibility_correction(KernelGlobals kg,
+                                                IntegratorState state,
+                                                const int shader,
+                                                Spectrum* light_visibility)
+{
+    Spectrum visible_components = zero_spectrum();
+    const BsdfEval scatter_eval = INTEGRATOR_STATE(state, path, scatter_eval);
+    Spectrum transmission = scatter_eval.sum - (scatter_eval.glossy + scatter_eval.diffuse);
+    if (!(shader & SHADER_EXCLUDE_DIFFUSE))
+    {
+        visible_components += scatter_eval.diffuse;
+    }
+
+    if (!(shader & SHADER_EXCLUDE_GLOSSY))
+    {
+        visible_components += scatter_eval.glossy;
+    }
+
+    if (!(shader & SHADER_EXCLUDE_TRANSMIT))
+    {
+        visible_components += transmission;
+    }
+
+    *light_visibility = safe_divide(visible_components , scatter_eval.sum);
+}
+
+CCL_NAMESPACE_END
\ No newline at end of file



More information about the Bf-blender-cvs mailing list