diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-03-19 22:28:33 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-03-19 23:11:06 +0300 |
commit | b96acd0663b589e5519a97c4f435d37e507fb8c1 (patch) | |
tree | 8fc0c7528b45ee4ab8ec8e00962162d3cf76fac9 /source/blender/draw/engines/eevee/eevee_lights.c | |
parent | 89ef0da5513a2bc85a518b0941807ecdd6980a66 (diff) |
EEVEE: Volumetrics: Add back support for light clamp
The new clamping works by modifying the lamp internal radius which
then soften the light contribution.
However this does remove more light compare to the old solution.
This is because the clamp now affects the light over a much larger
distance since it is smoother. Old scene needs manual tweaking.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lights.c')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_lights.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index dff69bcdd52..cba86d058ea 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -243,11 +243,27 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) linfo->num_light++; } -void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata)) +void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_LightsInfo *linfo = sldata->lights; sldata->common_data.la_num_light = linfo->num_light; + /* Clamp volume lights power. */ + float upper_bound = vedata->stl->effects->volume_light_clamp; + for (int i = 0; i < linfo->num_light; i++) { + EEVEE_Light *evli = linfo->light_data + i; + + float power = max_fff(UNPACK3(evli->color)) * evli->volume; + if (power > 0.0f && evli->light_type != LA_SUN) { + /* The limit of the power attenuation function when the distance to the light goes to 0 is + * 2 / r² where r is the light radius. We need to find the right radius that emits at most + * the volume light upper bound. Inverting the function we get: */ + float min_radius = 1.0f / sqrtf(0.5f * upper_bound / power); + /* Square it here to avoid a multiplication inside the shader. */ + evli->volume_radius = square_f(max_ff(min_radius, evli->radius)); + } + } + GPU_uniformbuf_update(sldata->light_ubo, &linfo->light_data); } |