[Bf-blender-cvs] [01f1b51a2e7] blender-v3.1-release: Fix T93565: revert Cycles to old normal behavior for point lights

Sebastian Herholz noreply at git.blender.org
Thu Feb 3 14:51:14 CET 2022


Commit: 01f1b51a2e75e7cd0ece3ecb622a3df907af726e
Author: Sebastian Herholz
Date:   Wed Feb 2 14:56:21 2022 +0100
Branches: blender-v3.1-release
https://developer.blender.org/rB01f1b51a2e75e7cd0ece3ecb622a3df907af726e

Fix T93565: revert Cycles to old normal behavior for point lights

This patch reverts the normal behavior of the spotlights. In the last fix,
the returned normal of a spot light was equal to its direction. This broke
some texturing methods used by artists.

Differential Revision: https://developer.blender.org/D13991

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

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

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

diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index b9c0b533518..089cf29821f 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -113,22 +113,29 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
     ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]);
 
     if (type == LIGHT_SPOT) {
-      ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
-      float radius = klight->spot.radius;
+      const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+      const float radius = klight->spot.radius;
+      const float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+      /* disk oriented normal */
+      const float3 lightN = normalize(P - center);
+      ls->P = center;
 
       if (radius > 0.0f)
-        /* sphere light */
-        ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
+        /* disk light */
+        ls->P += disk_light_sample(lightN, randu, randv) * radius;
+
+	  const float invarea = klight->spot.invarea;
+      ls->pdf = invarea;
 
       ls->D = normalize_len(ls->P - P, &ls->t);
+      /* we set the light normal to the outgoing direction to support texturing */
+      ls->Ng = -ls->D;
 
-      float invarea = klight->spot.invarea;
       ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
-      ls->pdf = invarea;
 
       /* spot light attenuation */
       ls->eval_fac *= spot_light_attenuation(
-          ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
+          dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
       if (!in_volume_segment && ls->eval_fac == 0.0f) {
         return false;
       }
@@ -137,32 +144,33 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
       ls->u = uv.x;
       ls->v = uv.y;
 
-      ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+      ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
     }
     else if (type == LIGHT_POINT) {
       float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
       float radius = klight->spot.radius;
+      /* disk oriented normal */
+      const float3 lightN = normalize(P - center);
       ls->P = center;
-      float pdf = 1.0;
 
       if (radius > 0.0f) {
-        ls->Ng = normalize(P - center);
-        ls->P += disk_light_sample(ls->Ng, randu, randv) * radius;
-        pdf = klight->spot.invarea;
-        ls->D = normalize_len(ls->P - P, &ls->t);
-      }
-      else {
-        ls->Ng = normalize(P - center);
+        ls->P += disk_light_sample(lightN, randu, randv) * radius;         
       }
+      ls->pdf = klight->spot.invarea; 
 
       ls->D = normalize_len(ls->P - P, &ls->t);
-      ls->pdf = pdf;
+      /* we set the light normal to the outgoing direction to support texturing */
+      ls->Ng = -ls->D;
+
       ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea;
+      if (!in_volume_segment && ls->eval_fac == 0.0f) {
+        return false;
+      }
 
       float2 uv = map_to_sphere(ls->Ng);
       ls->u = uv.x;
       ls->v = uv.y;
-      ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+      ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
     }
     else {
       /* area light */
@@ -263,14 +271,16 @@ ccl_device bool lights_intersect(KernelGlobals kg,
 
     if (type == LIGHT_SPOT) {
       /* Spot/Disk light. */
+      const float mis_ray_t = INTEGRATOR_STATE(state, path, mis_ray_t);
+      const float3 ray_P = ray->P - ray->D * mis_ray_t;
+
       const float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]);
-      const float3 lightN = make_float3(
-          klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
       const float radius = klight->spot.radius;
       if (radius == 0.0f) {
         continue;
       }
-
+      /* disk oriented normal */
+      const float3 lightN = normalize(ray_P - lightP);
       /* One sided. */
       if (dot(ray->D, lightN) >= 0.0f) {
         continue;
@@ -292,9 +302,10 @@ ccl_device bool lights_intersect(KernelGlobals kg,
         continue;
       }
 
+      /* disk oriented normal */
+      const float3 lightN = normalize(ray_P - lightP);
       float3 P;
-      const float3 lsN = normalize(ray_P - lightP);
-      if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lsN, radius, &P, &t)) {
+      if (!ray_disk_intersect(ray->P, ray->D, ray->t, lightP, lightN, radius, &P, &t)) {
         continue;
       }
     }
@@ -427,7 +438,12 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
   ls->D = ray_D;
 
   if (type == LIGHT_SPOT) {
-    ls->Ng = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+    const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+    const float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+    /* the normal of the oriented disk */ 
+    const float3 lightN = normalize(ray_P - center);
+    /* we set the light normal to the outgoing direction to support texturing*/
+    ls->Ng = -ls->D;
 
     float invarea = klight->spot.invarea;
     ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
@@ -435,7 +451,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
 
     /* spot light attenuation */
     ls->eval_fac *= spot_light_attenuation(
-        ls->Ng, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
+        dir, klight->spot.spot_angle, klight->spot.spot_smooth, -ls->D);
 
     if (ls->eval_fac == 0.0f) {
       return false;
@@ -447,23 +463,32 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
 
     /* compute pdf */
     if (ls->t != FLT_MAX)
-      ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+      ls->pdf *= lamp_light_pdf(kg, lightN, -ls->D, ls->t);
+    else
+      ls->pdf = 0.f;
   }
   else if (type == LIGHT_POINT) {
-    float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+    const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
+    const float3 lighN = normalize(ray_P - center);
 
-    ls->Ng = normalize(ray_P - center);
+    /* we set the light normal to the outgoing direction to support texturing*/
+    ls->Ng = -ls->D;
+    
     float invarea = klight->spot.invarea;
     ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
     ls->pdf = invarea;
 
+    if (ls->eval_fac == 0.0f) {
+      return false;
+    }
+
     float2 uv = map_to_sphere(ls->Ng);
     ls->u = uv.x;
     ls->v = uv.y;
 
     /* compute pdf */
     if (ls->t != FLT_MAX)
-      ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+      ls->pdf *= lamp_light_pdf(kg, lighN, -ls->D, ls->t);
     else
       ls->pdf = 0.f;
   }
@@ -921,4 +946,4 @@ ccl_device_inline bool light_distribution_sample_new_position(KernelGlobals kg,
   }
 }
 
-CCL_NAMESPACE_END
+CCL_NAMESPACE_END
\ No newline at end of file



More information about the Bf-blender-cvs mailing list