[Bf-blender-cvs] [66c7d43a9e0] soc-2022-many-lights-sampling: Optimize light tree importance based on transmissive properties of materials

Brecht Van Lommel noreply at git.blender.org
Fri Oct 7 14:46:38 CEST 2022


Commit: 66c7d43a9e0932ae5050678bc5908204545aa393
Author: Brecht Van Lommel
Date:   Fri Oct 7 14:39:25 2022 +0200
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB66c7d43a9e0932ae5050678bc5908204545aa393

Optimize light tree importance based on transmissive properties of materials

If a light is guaranteed to be behind the surface we're sampling,
then we give it an importance of 0.
However, if the material we're sampling is transmissive/translucent,
then we don't apply this optimization as it introduces artifacts.

Still not 100% correct, see TODO comment.

https://developer.blender.org/D16097

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

M	intern/cycles/kernel/closure/bsdf_diffuse.h
M	intern/cycles/kernel/closure/bsdf_hair.h
M	intern/cycles/kernel/closure/bsdf_hair_principled.h
M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_microfacet_multi.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/light/light_tree.h
M	intern/cycles/kernel/types.h

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

diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index c9c26754651..827b762f4c7 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -69,7 +69,7 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
 ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
 {
   bsdf->type = CLOSURE_BSDF_TRANSLUCENT_ID;
-  return SD_BSDF | SD_BSDF_HAS_EVAL;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
 }
 
 ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index a8ba4044758..989714bd695 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -34,7 +34,7 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
   bsdf->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
   bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
   bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
-  return SD_BSDF | SD_BSDF_HAS_EVAL;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
 }
 
 ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index 857b3fbf3a6..5a6465c7af6 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -196,7 +196,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
 
   bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
 
-  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
 }
 
 #endif /* __HAIR__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 4eb7cd5df22..39d0fb8f5f5 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -346,7 +346,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *
 
   bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
 
-  return SD_BSDF | SD_BSDF_HAS_EVAL;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
 }
 
 ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float roughness)
@@ -776,7 +776,7 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetB
   bsdf->alpha_y = bsdf->alpha_x;
 
   bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
-  return SD_BSDF | SD_BSDF_HAS_EVAL;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
 }
 
 ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, float roughness)
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 73cc0d292a1..73bbe80b2d4 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -559,7 +559,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf
 
   bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
 
-  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+  return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
 }
 
 ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private MicrofacetBsdf *bsdf,
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 84ea3f62dbd..e16f283b442 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));
@@ -125,7 +125,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
       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, kernel_data.background.light_index);
+        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);
     }
@@ -191,7 +191,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
         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);
+          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);
       }
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 177dcaa1aee..23ec965902f 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -66,7 +66,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
     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, ~ls.lamp);
+      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);
   }
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 7cca49ba2b8..5d707cfe9ac 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -132,7 +132,8 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
       const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
       uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object);
       uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object);
-      pdf *= light_tree_pdf(kg, state, ray_P, N, sd->prim - prim_offset + lookup_offset);
+      pdf *= light_tree_pdf(
+          kg, state, ray_P, N, path_flag, sd->prim - prim_offset + lookup_offset);
     }
     mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
   }
@@ -170,6 +171,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
                                            sd->time,
                                            sd->P,
                                            sd->N,
+                                           sd->flag,
                                            bounce,
                                            path_flag,
                                            &ls)) {
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index dfd552e95e9..5ab9dfac254 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -35,6 +35,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min,
  * Both of the specialized functions obtain the necessary data before calling this function. */
 ccl_device float light_tree_node_importance(const float3 P,
                                             const float3 N,
+                                            const bool has_transmission,
                                             const float3 bbox_min,
                                             const float3 bbox_max,
                                             const float3 bcone_axis,
@@ -50,13 +51,8 @@ ccl_device float light_tree_node_importance(const float3 P,
   const float distance_squared = fmaxf(0.25f * len_squared(centroid - bbox_max),
                                        len_squared(centroid - P));
 
-  /* to-do: should there be a different importance calculations for different surfaces?
-   * opaque surfaces could just return 0 importance in this case. */
   const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid));
   float theta_i = fast_acosf(dot(point_to_centroid, N));
-  if (theta_i > M_PI_2_F) {
-    theta_i = M_PI_F - theta_i;
-  }
   const float theta_u = light_tree_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid);
 
   /* Avoid using cosine until needed. */
@@ -64,8 +60,18 @@ ccl_device float light_tree_node_importance(const float3 P,
   if (theta_prime >= theta_e) {
     return 0.0f;
   }
-  const float cos_theta_prime = fast_cosf(theta_prime);
 
+  /* If the node is guaranteed to be behind the surface we're sampling, and the surface is opaque,
+   * then we can give the node an importance of 0 as it contributes nothing to the surface. */
+  if (!has_transmission && (theta_i - theta_u > M_PI_2_F)) {
+    return 0.0f;
+  }
+
+  if (theta_i > M_PI_2_F) {
+    theta_i = M_PI_F - theta_i;
+  }
+
+  const float cos_theta_prime = fast_cosf(theta_prime);
   float cos_theta_i_prime = 1.0f;
   if (theta_i - theta_u > 0.0f) {
     cos_theta_i_prime = fabsf(fast_cosf(theta_i - theta_u));
@@ -147,6 +153,7 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg,
 ccl_device float light_tree_emitter_importance(KernelGlobals kg,
                                                const float3 P,
                                                const float3 N,
+             

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list