[Bf-blender-cvs] [bbf4c9d6475] soc-2022-many-lights-sampling: Cycles: update MIS calculations when light tree is enabled

Jeffrey Liu noreply at git.blender.org
Sat Jul 9 06:57:06 CEST 2022


Commit: bbf4c9d6475518976f59b4d78e17a455ecc89c7f
Author: Jeffrey Liu
Date:   Thu Jul 7 16:49:34 2022 -0400
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rBbbf4c9d6475518976f59b4d78e17a455ecc89c7f

Cycles: update MIS calculations when light tree is enabled

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

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

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

diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 4791a963ae6..495bcb1cdaa 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -6,6 +6,7 @@
 #include "kernel/film/accumulate.h"
 #include "kernel/integrator/shader_eval.h"
 #include "kernel/light/light.h"
+#include "kernel/light/light_tree.h"
 #include "kernel/light/sample.h"
 
 CCL_NAMESPACE_BEGIN
@@ -66,7 +67,11 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg,
 
     /* 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_ray_t, ray_D);
+    float pdf = background_light_pdf(kg, ray_P - ray_D * mis_ray_t, 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, kernel_data.background.light_index);
+    }
     const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
     L *= mis_weight;
   }
@@ -180,6 +185,11 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
         /* 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, lamp);
+        }
         const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
         light_eval *= mis_weight;
       }
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index be926c78439..4053e01737c 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -72,6 +72,10 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
     /* 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, ray_P, N, ~isect.prim);
+    }
     const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
     light_eval *= mis_weight;
   }
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index ca44daad5cf..a01b03ad9d0 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -83,6 +83,11 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
     /* 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) {
+      const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
+      const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
+      pdf *= light_tree_pdf(kg, ray_P, N, sd->prim);
+    }
     float mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
     L *= mis_weight;
   }
@@ -364,6 +369,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
   else {
     INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = bsdf_pdf;
     INTEGRATOR_STATE_WRITE(state, path, mis_ray_t) = 0.0f;
+    INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N;
     INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
         bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
   }
diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h
index e7e6db037b0..236855af5ec 100644
--- a/intern/cycles/kernel/integrator/state_template.h
+++ b/intern/cycles/kernel/integrator/state_template.h
@@ -42,6 +42,7 @@ KERNEL_STRUCT_MEMBER(path, uint8_t, mnee, KERNEL_FEATURE_PATH_TRACING)
  * compute the complete distance through transparent surfaces and volumes. */
 KERNEL_STRUCT_MEMBER(path, float, mis_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
 KERNEL_STRUCT_MEMBER(path, float, mis_ray_t, KERNEL_FEATURE_PATH_TRACING)
+KERNEL_STRUCT_MEMBER(path, packed_float3, mis_origin_n, KERNEL_FEATURE_PATH_TRACING)
 /* Filter glossy. */
 KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
 /* Continuation probability for path termination. */
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index 1e7a333d013..e9140298257 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -642,15 +642,17 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
     }
     else {
       float area = 1.0f;
-      if (has_motion) {
-        /* get the center frame vertices, this is what the PDF was calculated from */
-        triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
-        area = triangle_area(V[0], V[1], V[2]);
-      }
-      else {
-        area = 0.5f * len(N);
+      if (!kernel_data.integrator.use_light_tree) {
+        if (has_motion) {
+          /* get the center frame vertices, this is what the PDF was calculated from */
+          triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
+          area = triangle_area(V[0], V[1], V[2]);
+        }
+        else {
+          area = 0.5f * len(N);
+        }
       }
-      const float pdf = area * kernel_data.integrator.pdf_triangles;
+      float pdf = area * kernel_data.integrator.pdf_triangles;
       return pdf / solid_angle;
     }
   }
@@ -665,9 +667,10 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg,
        * area = the area the sample was taken from
        * area_pre = the are from which pdf_triangles was calculated from */
       triangle_world_space_vertices(kg, sd->object, sd->prim, -1.0f, V);
-      const float area_pre = triangle_area(V[0], V[1], V[2]);
+      const float area_pre = (kernel_data.integrator.use_light_tree) ? 1.0 : triangle_area(V[0], V[1], V[2]);
       pdf = pdf * area_pre / area;
     }
+
     return pdf;
   }
 }
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index cf7e9c2ee18..4df1dd7adc7 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -206,28 +206,6 @@ ccl_device int light_tree_sample(KernelGlobals kg,
         triangle_light_sample<in_volume_segment>(kg, prim, object, randu, randv, time, ls, P);
         ls->shader |= shader_flag;
 
-        /* triangle_light sample also multiplies the pdf by the triangle's area
-         * because of the precomputed light distribution PDF.
-         * We need to reverse this because it's not needed here.*/
-        float area = 0.0f;
-
-        float3 V[3];
-        bool has_motion = triangle_world_space_vertices(kg, object, prim, time, V);
-
-        const float3 e0 = V[1] - V[0];
-        const float3 e1 = V[2] - V[0];
-        const float3 e2 = V[2] - V[1];
-
-        const float3 N0 = cross(e0, e1);
-        if (has_motion) {
-          /* get the center frame vertices, this is what the PDF was calculated from */
-          triangle_world_space_vertices(kg, object, prim, -1.0f, V);
-          area = triangle_area(V[0], V[1], V[2]);
-        }
-        else {
-          area = 0.5f * len(N0);
-        }
-        ls->pdf /= area;
         return (ls->pdf > 0.0f);
       }
 
@@ -350,7 +328,7 @@ ccl_device float light_tree_pdf(KernelGlobals kg, const float3 P, const float3 N
   for (int i = 0; i < kleaf->num_prims; i++) {
     int prim = i - kleaf->child_index; /* At a leaf node, the negative value is the index into first prim. */
     const float importance = light_tree_emitter_importance(kg, P, N, prim);
-    if (i == emitter) {
+    if (prim == emitter) {
       emitter_importance = importance;
     }
     total_importance += importance;
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index fc43a1b735a..9def2e5690b 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -1229,8 +1229,11 @@ typedef struct KernelBackground {
 
   int lightgroup;
 
+  /* index into lights array */
+  int light_index;
+
   /* Padding */
-  int pad1, pad2;
+  int pad1;
 } KernelBackground;
 static_assert_align(KernelBackground, 16);
 
diff --git a/intern/cycles/scene/background.cpp b/intern/cycles/scene/background.cpp
index bffc8895bfd..0779313e5ba 100644
--- a/intern/cycles/scene/background.cpp
+++ b/intern/cycles/scene/background.cpp
@@ -4,6 +4,7 @@
 #include "scene/background.h"
 #include "device/device.h"
 #include "scene/integrator.h"
+#include "scene/light.h"
 #include "scene/scene.h"
 #include "scene/shader.h"
 #include "scene/shader_graph.h"
@@ -103,6 +104,19 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
       kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
   }
 
+  /* Find background index in lights. */
+  int device_light_index = 0;
+  int background_light_index = -1;
+  foreach (Light *light, scene->lights) {
+    if (light->get_is_enabled()) {
+      if (light->get_light_type() == LIGHT_BACKGROUND) {
+        background_light_index = device_light_index;
+      }
+      device_light_index++;
+    }
+  }
+  kbackground->light_index = background_light_index;
+
   /* Light group. */
   auto it = scene->lightgroups.find(lightgroup);
   if (it != scene->lightgroups.end()) {
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index aeb8cd7a341..6278e3efd93 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -353,15 +353,16 @@ void LightManager::device_update_distribution(Device *device,
     if (progress.get_cancel())
       return;
 
+    /* Count emissive triangles. */
+    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list