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`.
This commit is contained in:
Weizhen Huang 2023-01-31 16:26:51 +01:00
parent 1cb04af1df
commit ce42906b89
1 changed files with 7 additions and 4 deletions

View File

@ -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);