[Bf-blender-cvs] [1e350811e5a] soc-2022-many-lights-sampling: Refactor kernel light code

Brecht Van Lommel noreply at git.blender.org
Tue Oct 25 14:17:11 CEST 2022


Commit: 1e350811e5abc530c8b28e9fcdb5810dbc02216b
Author: Brecht Van Lommel
Date:   Tue Oct 25 13:43:07 2022 +0200
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB1e350811e5abc530c8b28e9fcdb5810dbc02216b

Refactor kernel light code

* Split light types into own files, move light type specific code from
  light tree and MNEE.
* Move flat light distribution code into own file. Refactor code to
  ensure light distribution pdfs do not affect the light tree case.
* Isolate differences between distribution and tree sampling into
  light/, with common API in light/sample.h for the integrator to use.
* Better separate calculation of pdf for selecting a light, and pdf for
  sampling a point on the light. The selection pdf is now also stored in
  LightSampling for MNEE to correctly recalculate the full pdf when the
  shading position changes but the point on the light remains fixed.
* Fix errors in volume light sampling by using the light tree for sampling
  once we know the shading position (but not for equiangular yet). This
  fixes errors in volume rendering where the pdfs were mismatched due to
  sampling the distribution but assuming light tree for pdf computation.

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

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/data_template.h
M	intern/cycles/kernel/integrator/intersect_closest.h
M	intern/cycles/kernel/integrator/mnee.h
M	intern/cycles/kernel/integrator/path_state.h
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/shade_volume.h
A	intern/cycles/kernel/light/area.h
M	intern/cycles/kernel/light/background.h
M	intern/cycles/kernel/light/common.h
A	intern/cycles/kernel/light/distant.h
A	intern/cycles/kernel/light/distribution.h
M	intern/cycles/kernel/light/light.h
A	intern/cycles/kernel/light/point.h
M	intern/cycles/kernel/light/sample.h
A	intern/cycles/kernel/light/spot.h
A	intern/cycles/kernel/light/tree.h
A	intern/cycles/kernel/light/triangle.h
M	intern/cycles/kernel/types.h
M	intern/cycles/scene/light.cpp

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index c52a3503da1..052ae6a3435 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -267,11 +267,17 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS
 )
 
 set(SRC_KERNEL_LIGHT_HEADERS
-  light/light.h
-  light/light_tree.h
+  light/area.h
   light/background.h
   light/common.h
+  light/distant.h
+  light/distribution.h
+  light/light.h
+  light/point.h
   light/sample.h
+  light/spot.h
+  light/tree.h
+  light/triangle.h
 )
 
 set(SRC_KERNEL_SAMPLE_HEADERS
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index 9b133d23ed2..6b1113adce9 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -151,8 +151,8 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_direct_light)
 KERNEL_STRUCT_MEMBER(integrator, int, num_distribution)
 KERNEL_STRUCT_MEMBER(integrator, int, num_distant_lights)
 KERNEL_STRUCT_MEMBER(integrator, int, num_all_lights)
-KERNEL_STRUCT_MEMBER(integrator, float, pdf_triangles)
-KERNEL_STRUCT_MEMBER(integrator, float, pdf_lights)
+KERNEL_STRUCT_MEMBER(integrator, float, distribution_pdf_triangles)
+KERNEL_STRUCT_MEMBER(integrator, float, distribution_pdf_lights)
 KERNEL_STRUCT_MEMBER(integrator, float, light_inv_rr_threshold)
 /* Bounces. */
 KERNEL_STRUCT_MEMBER(integrator, int, min_bounce)
diff --git a/intern/cycles/kernel/integrator/intersect_closest.h b/intern/cycles/kernel/integrator/intersect_closest.h
index b9a81e25bcc..1a0a0af5bbb 100644
--- a/intern/cycles/kernel/integrator/intersect_closest.h
+++ b/intern/cycles/kernel/integrator/intersect_closest.h
@@ -11,10 +11,10 @@
 #include "kernel/integrator/path_state.h"
 #include "kernel/integrator/shadow_catcher.h"
 
-#include "kernel/light/light.h"
-
 #include "kernel/geom/geom.h"
 
+#include "kernel/light/light.h"
+
 #include "kernel/bvh/bvh.h"
 
 CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index 23885306885..7f5f2c97497 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -108,48 +108,6 @@ ccl_device_inline float mat22_inverse(const float4 m, ccl_private float4 &m_inve
   return det;
 }
 
-/* Update light sample */
-ccl_device_forceinline void mnee_update_light_sample(KernelGlobals kg,
-                                                     const float3 P,
-                                                     ccl_private LightSample *ls)
-{
-  /* correct light sample position/direction and pdf
-   * NOTE: preserve pdf in area measure */
-  const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
-
-  if (ls->type == LIGHT_POINT || ls->type == LIGHT_SPOT) {
-    ls->D = normalize_len(ls->P - P, &ls->t);
-    ls->Ng = -ls->D;
-
-    float2 uv = map_to_sphere(ls->Ng);
-    ls->u = uv.x;
-    ls->v = uv.y;
-
-    float invarea = klight->spot.invarea;
-    ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
-    ls->pdf = invarea;
-
-    if (ls->type == LIGHT_SPOT) {
-      /* spot light attenuation */
-      float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
-      ls->eval_fac *= spot_light_attenuation(
-          dir, klight->spot.spot_angle, klight->spot.spot_smooth, ls->Ng);
-    }
-  }
-  else if (ls->type == LIGHT_AREA) {
-    float invarea = fabsf(klight->area.invarea);
-    ls->D = normalize_len(ls->P - P, &ls->t);
-    ls->pdf = invarea;
-    if (klight->area.tan_spread > 0.f) {
-      ls->eval_fac = 0.25f * invarea;
-      ls->eval_fac *= light_spread_attenuation(
-          ls->D, ls->Ng, klight->area.tan_spread, klight->area.normalize_spread);
-    }
-  }
-
-  ls->pdf *= kernel_data.integrator.pdf_lights;
-}
-
 /* Manifold vertex setup from ray and intersection data */
 ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
                                                        ccl_private ManifoldVertex *vtx,
@@ -819,7 +777,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
 
   /* Update light sample with new position / direct.ion
    * and keep pdf in vertex area measure */
-  mnee_update_light_sample(kg, vertices[vertex_count - 1].p, ls);
+  light_sample_update_position(kg, ls, vertices[vertex_count - 1].p);
 
   /* Save state path bounce info in case a light path node is used in the refractive interface or
    * light shader graph. */
diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h
index bb32e54bfe0..9d8ecdc47b4 100644
--- a/intern/cycles/kernel/integrator/path_state.h
+++ b/intern/cycles/kernel/integrator/path_state.h
@@ -128,7 +128,7 @@ ccl_device_inline void path_state_next(KernelGlobals kg,
 #ifdef __VOLUME__
   if (label & LABEL_VOLUME_SCATTER) {
     /* volume scatter */
-    flag |= PATH_RAY_VOLUME_SCATTER;
+    flag |= PATH_RAY_VOLUME_SCATTER | PATH_RAY_MIS_HAD_TRANSMISSION;
     flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
     if (!(flag & PATH_RAY_ANY_PASS)) {
       flag |= PATH_RAY_VOLUME_PASS;
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index e16f283b442..03626a78b66 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -9,7 +9,6 @@
 #include "kernel/integrator/surface_shader.h"
 
 #include "kernel/light/light.h"
-#include "kernel/light/light_tree.h"
 #include "kernel/light/sample.h"
 
 CCL_NAMESPACE_BEGIN
@@ -116,18 +115,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
     /* Check if background light exists or if we should skip pdf. */
     if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_MIS_SKIP) &&
         kernel_data.background.use_mis) {
-      const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
-      const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
-      const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
-
-      /* 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);
-      if (kernel_data.integrator.use_light_tree) {
-        const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
-        pdf *= distant_lights_pdf(kg, ray_P, N, path_flag, kernel_data.background.light_index);
-      }
-      mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
+      mis_weight = light_sample_mis_weight_forward_background(kg, state, path_flag);
     }
 
     guiding_record_background(kg, state, L, mis_weight);
@@ -146,7 +134,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
   const float ray_time = INTEGRATOR_STATE(state, ray, time);
   LightSample ls ccl_optional_struct_init;
   for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
-    if (light_sample_from_distant_ray(kg, ray_D, lamp, &ls)) {
+    if (distant_light_sample_from_intersection(kg, ray_D, lamp, &ls)) {
       /* Use visibility flag to skip lights. */
 #ifdef __PASSES__
       const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
@@ -185,15 +173,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
       /* MIS weighting. */
       float mis_weight = 1.0f;
       if (!(path_flag & PATH_RAY_MIS_SKIP)) {
-        /* multiple importance sampling, get regular light pdf,
-         * and compute weight with respect to BSDF pdf */
-        const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
-        if (kernel_data.integrator.use_light_tree) {
-          const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
-          const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
-          ls.pdf *= distant_lights_pdf(kg, ray_P, N, path_flag, lamp);
-        }
-        mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
+        mis_weight = light_sample_mis_weight_forward_distant(kg, state, path_flag, &ls);
       }
 
       /* Write to render buffer. */
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 23ec965902f..1f09ac4e6d8 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -61,14 +61,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
   /* MIS weighting. */
   float mis_weight = 1.0f;
   if (!(path_flag & PATH_RAY_MIS_SKIP)) {
-    /* multiple importance sampling, get regular light pdf,
-     * and compute weight with respect to BSDF pdf */
-    const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
-    if (kernel_data.integrator.use_light_tree) {
-      const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
-      ls.pdf *= light_tree_pdf(kg, state, ray_P, N, path_flag, ~ls.lamp);
-    }
-    mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
+    mis_weight = light_sample_mis_weight_forward_lamp(kg, state, path_flag, &ls, ray_P);
   }
 
   /* Write to render buffer. */
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 47a2c4cce13..fd31ac42946 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -15,8 +15,6 @@
 #include "kernel/integrator/surface_shader.h"
 #include "kernel/integrator/volume_stack.h"
 
-#include "kernel/light/light.h"
-#include "kernel/light/light_tree.h"
 #include "kernel/light/sample.h"
 
 CCL_NAMESPACE_BEGIN
@@ -121,21 +119,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
   if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
 #endif
   {
-    const float bsdf_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
-    const float t = sd->ray_length;
-
-    /* Multiple importance sampling, get triangle light pdf,
-     * and compute weight with respect to BSDF pdf. */
-    float pdf = triangle_light_pdf(kg, sd, t);
-    if (kernel_data.integrator.use_light_tree) {
-      float3 ray_P = INTEGRATOR_STATE(state, ray, P);
-      const float3

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list