[Bf-blender-cvs] [357ca8f128b] soc-2022-many-lights-sampling: Fix: light tree handles spotlights poorly

Jeffrey Liu noreply at git.blender.org
Thu Aug 4 19:48:54 CEST 2022


Commit: 357ca8f128b29542138ea818e2c7ceba28efe7cf
Author: Jeffrey Liu
Date:   Thu Aug 4 13:47:54 2022 -0400
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB357ca8f128b29542138ea818e2c7ceba28efe7cf

Fix: light tree handles spotlights poorly

This fix has a special case for spotlights, which will check if the
point falls within the spotlight or not.

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

M	intern/cycles/kernel/light/light_tree.h

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

diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index decf7db8fe8..d44ed34cb15 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -119,7 +119,31 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg,
       return 0.0f;
     }
 
-    sampled = light_sample<false>(kg, lamp, randu, randv, P, path_flag, &ls);
+    const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
+
+    if (klight->type == LIGHT_SPOT) {
+      /* to-do: since spot light importance sampling isn't the best,
+       * we have a special case to check that the point is inside the cone. */
+      const float radius = klight->spot.radius;
+      const float cos_theta = klight->spot.spot_angle;
+      const float theta = fast_acosf(cos_theta);
+      const float3 light_P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+      const float3 light_dir = make_float3(
+          klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+
+      const float h1 = radius * fast_sinf(theta);
+      const float d1 = radius * cos_theta;
+      const float h2 = d1 / fast_tanf(theta);
+
+      const float3 apex = light_P - (h1 + h2) * light_dir;
+      const float3 apex_to_point = normalize(P - apex);
+      if (dot(apex_to_point, light_dir) < cos_theta) {
+        return 0.0f;
+      }
+    }
+    else {
+      sampled = light_sample<false>(kg, lamp, randu, randv, P, path_flag, &ls);
+    }
   }



More information about the Bf-blender-cvs mailing list