[Bf-blender-cvs] [ce42906b896] master: Fix wrong spot light blend circle radius in viewport

Weizhen Huang noreply at git.blender.org
Tue Jan 31 16:31:03 CET 2023


Commit: ce42906b8962155b50cc043b3a0b5b24f191a41c
Author: Weizhen Huang
Date:   Tue Jan 31 16:26:51 2023 +0100
Branches: master
https://developer.blender.org/rBce42906b8962155b50cc043b3a0b5b24f191a41c

Fix wrong spot light blend circle radius in viewport

Was using squared cosine instead of cosine. The problem is obvious for large spread angles.
|before|after
|{F14220946}|{F14220948}
The images are generating by returning `floor(spotmask)` in function `spot_attenuation()` in `lights_lib.glsl`.

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

M	source/blender/draw/engines/overlay/overlay_extra.cc

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

diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc
index c366e64347c..2bb3bb5f8d8 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.cc
+++ b/source/blender/draw/engines/overlay/overlay_extra.cc
@@ -649,16 +649,19 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
     const float3 scale_vec = {10.0f, 10.0f, 10.0f};
     rescale_m4(instdata.mat, scale_vec);
     /* For cycles and eevee the spot attenuation is
-     * y = (1/(1 + x^2) - a)/((1 - a) b)
+     * y = (1/sqrt(1 + x^2) - a)/((1 - a) b)
+     * x being the tangent of the angle between the light direction and the generatrix of the cone.
      * We solve the case where spot attenuation y = 1 and y = 0
-     * root for y = 1 is  (-1 - c) / c
-     * root for y = 0 is  (1 - a) / a
+     * root for y = 1 is sqrt(1/c^2 - 1)
+     * root for y = 0 is sqrt(1/a^2 - 1)
      * and use that to position the blend circle. */
     float a = cosf(la->spotsize * 0.5f);
     float b = la->spotblend;
     float c = a * b - a - b;
+    float a2 = a * a;
+    float c2 = c * c;
     /* Optimized version or root1 / root0 */
-    instdata.spot_blend = sqrtf((-a - c * a) / (c - c * a));
+    instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2));
     instdata.spot_cosine = a;
     /* HACK: We pack the area size in alpha color. This is decoded by the shader. */
     color[3] = -max_ff(la->radius, FLT_MIN);



More information about the Bf-blender-cvs mailing list