[Bf-blender-cvs] [ac51d331dfb] master: Refactor: Cycles light sampling code reorganization

Brecht Van Lommel noreply at git.blender.org
Wed Nov 30 21:31:57 CET 2022


Commit: ac51d331dfbdccb3ec6d4b7cb60909fe01d1a333
Author: Brecht Van Lommel
Date:   Wed Nov 30 20:17:45 2022 +0100
Branches: master
https://developer.blender.org/rBac51d331dfbdccb3ec6d4b7cb60909fe01d1a333

Refactor: Cycles light sampling code reorganization

* Split light types into own files, move light type specific code from
  light tree and MNEE.
* Move flat light distribution code into own kernel file and host side
  building function, in preparation of light tree addition. Add light/sample.h
  as main entry point to kernel light sampling.
* 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.
* Improvement to kernel light storage, using packed_float3, better variable
  names, etc.

Includes contributions by Brecht Van Lommel and Weizhen Huang.

Ref T77889

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

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/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/triangle.h
M	intern/cycles/kernel/types.h
M	intern/cycles/scene/background.cpp
M	intern/cycles/scene/light.cpp
M	intern/cycles/scene/light.h

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 3f03118b105..dd96cfd5058 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -285,10 +285,16 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS
 )
 
 set(SRC_KERNEL_LIGHT_HEADERS
-  light/light.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/triangle.h
 )
 
 set(SRC_KERNEL_SAMPLE_HEADERS
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index c7b50b20c70..9a44b21543c 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -23,24 +23,19 @@ KERNEL_STRUCT_MEMBER(background, int, volume_shader)
 KERNEL_STRUCT_MEMBER(background, float, volume_step_size)
 KERNEL_STRUCT_MEMBER(background, int, transparent)
 KERNEL_STRUCT_MEMBER(background, float, transparent_roughness_squared_threshold)
-/* Portal sampling. */
-KERNEL_STRUCT_MEMBER(background, float, portal_weight)
-KERNEL_STRUCT_MEMBER(background, int, num_portals)
-KERNEL_STRUCT_MEMBER(background, int, portal_offset)
 /* Sun sampling. */
 KERNEL_STRUCT_MEMBER(background, float, sun_weight)
 /* Importance map sampling. */
 KERNEL_STRUCT_MEMBER(background, float, map_weight)
+KERNEL_STRUCT_MEMBER(background, float, portal_weight)
 KERNEL_STRUCT_MEMBER(background, int, map_res_x)
 KERNEL_STRUCT_MEMBER(background, int, map_res_y)
 /* Multiple importance sampling. */
 KERNEL_STRUCT_MEMBER(background, int, use_mis)
 /* Lightgroup. */
 KERNEL_STRUCT_MEMBER(background, int, lightgroup)
-/* Padding. */
-KERNEL_STRUCT_MEMBER(background, int, pad1)
-KERNEL_STRUCT_MEMBER(background, int, pad2)
-KERNEL_STRUCT_MEMBER(background, int, pad3)
+/* Light Index. */
+KERNEL_STRUCT_MEMBER(background, int, light_index)
 KERNEL_STRUCT_END(KernelBackground)
 
 /* BVH: own BVH2 if no native device acceleration struct used. */
@@ -147,10 +142,17 @@ KERNEL_STRUCT_END(KernelFilm)
 KERNEL_STRUCT_BEGIN(KernelIntegrator, integrator)
 /* Emission. */
 KERNEL_STRUCT_MEMBER(integrator, int, use_direct_light)
+KERNEL_STRUCT_MEMBER(integrator, int, use_light_mis)
+KERNEL_STRUCT_MEMBER(integrator, int, num_lights)
+KERNEL_STRUCT_MEMBER(integrator, int, num_distant_lights)
+KERNEL_STRUCT_MEMBER(integrator, int, num_background_lights)
+/* Portal sampling. */
+KERNEL_STRUCT_MEMBER(integrator, int, num_portals)
+KERNEL_STRUCT_MEMBER(integrator, int, portal_offset)
+/* Flat light distribution. */
 KERNEL_STRUCT_MEMBER(integrator, int, num_distribution)
-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)
@@ -177,8 +179,6 @@ KERNEL_STRUCT_MEMBER(integrator, int, seed)
 /* Clamp. */
 KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_direct)
 KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect)
-/* MIS. */
-KERNEL_STRUCT_MEMBER(integrator, int, use_lamp_mis)
 /* Caustics. */
 KERNEL_STRUCT_MEMBER(integrator, int, use_caustics)
 /* Sampling pattern. */
@@ -195,7 +195,6 @@ KERNEL_STRUCT_MEMBER(integrator, int, has_shadow_catcher)
 KERNEL_STRUCT_MEMBER(integrator, int, filter_closures)
 /* MIS debugging. */
 KERNEL_STRUCT_MEMBER(integrator, int, direct_light_sampling_type)
-
 /* Path Guiding */
 KERNEL_STRUCT_MEMBER(integrator, float, surface_guiding_probability)
 KERNEL_STRUCT_MEMBER(integrator, float, volume_guiding_probability)
diff --git a/intern/cycles/kernel/integrator/intersect_closest.h b/intern/cycles/kernel/integrator/intersect_closest.h
index b9a81e25bcc..dc171885755 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
@@ -387,7 +387,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
 #endif /* __MNEE__ */
 
   /* Light intersection for MIS. */
-  if (kernel_data.integrator.use_lamp_mis) {
+  if (kernel_data.integrator.use_light_mis) {
     /* NOTE: if we make lights visible to camera rays, we'll need to initialize
      * these in the path_state_init. */
     const int last_type = INTEGRATOR_STATE(state, isect, type);
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/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index f35a6d308f7..81fc7a46a0c 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -69,9 +69,9 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
   bool eval_background = true;
   float transparent = 0.0f;
 
+  int path_flag = INTEGRATOR_STATE(state, path, flag);
   const bool is_transparent_background_ray = kernel_data.background.transparent &&
-                                             (INTEGRATOR_STATE(state, path, flag) &
-                                              PATH_RAY_TRANSPARENT_BACKGROUND);
+                                             (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND);
 
   if (is_transparent_background_ray) {
     transparent = average(INTEGRATOR_STATE(state, path, throughput));
@@ -86,7 +86,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
 #ifdef __MNEE__
   if (INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_CULL_LIGHT_CONNECTION) {
     if (kernel_data.background.use_mis) {
-      for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
+      for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) {
         /* This path should have been resolved with mnee, it will
          * generate a firefly for small lights since it is improbable. */
         const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
@@ -116,14 +116,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 */
-      const float pdf = background_light_pdf(kg, ray_P, ray_D);
-      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);
@@ -142,8 +135,8 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
   const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
   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)) {
+  for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) {
+    if (distant_light_sample_from_inters

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list