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.
This commit is contained in:
parent
89ef0da551
commit
b96acd0663
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -489,7 +489,7 @@ typedef struct EEVEE_Light {
|
|||
float rightvec[3], sizex;
|
||||
float upvec[3], sizey;
|
||||
float forwardvec[3], light_type;
|
||||
float diff, spec, volume, _pad0[1];
|
||||
float diff, spec, volume, volume_radius;
|
||||
} EEVEE_Light;
|
||||
|
||||
/* Special type for elliptic area lights, matches lamps_lib.glsl */
|
||||
|
@ -717,6 +717,7 @@ typedef struct EEVEE_EffectsInfo {
|
|||
struct GPUTexture *sss_stencil;
|
||||
/* Volumetrics */
|
||||
int volume_current_sample;
|
||||
float volume_light_clamp;
|
||||
struct GPUTexture *volume_scatter;
|
||||
struct GPUTexture *volume_transmit;
|
||||
/* SSR */
|
||||
|
|
|
@ -184,9 +184,7 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||
|
||||
float integration_start = scene_eval->eevee.volumetric_start;
|
||||
float integration_end = scene_eval->eevee.volumetric_end;
|
||||
/* TODO(fclem) Use clamp to modulate the light radius for
|
||||
* volume lighting and avoid very bright highlights. */
|
||||
// common_data->vol_light_clamp = scene_eval->eevee.volumetric_light_clamp;
|
||||
effects->volume_light_clamp = scene_eval->eevee.volumetric_light_clamp;
|
||||
common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples;
|
||||
if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) {
|
||||
common_data->vol_shadow_steps = 0;
|
||||
|
@ -218,10 +216,9 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||
}
|
||||
|
||||
/* Disable clamp if equal to 0. */
|
||||
/* TODO(fclem) Re-implement */
|
||||
// if (common_data->vol_light_clamp == 0.0) {
|
||||
// common_data->vol_light_clamp = FLT_MAX;
|
||||
// }
|
||||
if (effects->volume_light_clamp == 0.0) {
|
||||
effects->volume_light_clamp = FLT_MAX;
|
||||
}
|
||||
|
||||
common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
|
||||
common_data->vol_use_soft_shadows = (scene_eval->eevee.flag & SCE_EEVEE_SHADOW_SOFT) != 0;
|
||||
|
|
|
@ -19,7 +19,7 @@ struct LightData {
|
|||
vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
|
||||
vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
|
||||
vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
|
||||
vec4 diff_spec_volume; /* xyz: Diffuse/Spec/Volume power, w: unused. */
|
||||
vec4 diff_spec_volume; /* xyz: Diffuse/Spec/Volume power, w: radius for volumetric. */
|
||||
};
|
||||
|
||||
/* convenience aliases */
|
||||
|
@ -27,6 +27,7 @@ struct LightData {
|
|||
#define l_diff diff_spec_volume.x
|
||||
#define l_spec diff_spec_volume.y
|
||||
#define l_volume diff_spec_volume.z
|
||||
#define l_volume_radius diff_spec_volume.w
|
||||
#define l_position position_influence.xyz
|
||||
#define l_influence position_influence.w
|
||||
#define l_influence_volume color_influence_volume.w
|
||||
|
|
|
@ -73,7 +73,7 @@ vec3 light_volume(LightData ld, vec4 l_vector)
|
|||
**/
|
||||
float d = l_vector.w;
|
||||
float d_sqr = sqr(d);
|
||||
float r_sqr = sqr(ld.l_radius);
|
||||
float r_sqr = ld.l_volume_radius;
|
||||
/* Using reformulation that has better numerical percision. */
|
||||
power = 2.0 / (d_sqr + r_sqr + d * sqrt(d_sqr + r_sqr));
|
||||
|
||||
|
|
Loading…
Reference in New Issue