Fix: EEVEE-Next: Missing shadow near area light

This was caused by wrong assumption that `shadow_radius`
is also a radius for area light. To avoid the confusion,
use a new property for area light shadow scaling.
This commit is contained in:
Clément Foucault
2024-05-23 16:12:07 +02:00
parent 7b3e529462
commit 8b65908574
3 changed files with 7 additions and 6 deletions

View File

@@ -189,8 +189,8 @@ void Light::shape_parameters_set(const ::Light *la,
this->area.size = float2(la->area_size, is_irregular ? la->area_sizey : la->area_size);
/* Scale and clamp to minimum value before float imprecision artifacts appear. */
this->area.size *= scale.xy() / 2.0f;
/* In this case, this is just the scaling factor. */
this->local.shadow_radius = trace_scaling_fac;
this->area.shadow_scale = trace_scaling_fac;
this->local.shadow_radius = length(this->area.size) * trace_scaling_fac;
/* Set to default position. */
this->local.shadow_position = float3(0.0f);
/* Do not render lights that have no area. */

View File

@@ -918,7 +918,8 @@ struct LightAreaData {
/** Shape size. */
float2 size;
float _pad5;
/** Scale to apply on top of `size` to get shadow tracing shape size. */
float shadow_scale;
float _pad6;
};
BLI_STATIC_ASSERT(sizeof(LightAreaData) == sizeof(LightLocalData), "Data size must match")
@@ -1174,6 +1175,7 @@ static inline LightAreaData light_area_data_get(LightData light)
SAFE_ASSIGN_FLOAT(shadow_radius, shadow_radius)
SAFE_ASSIGN_INT(tilemaps_count, tilemaps_count)
SAFE_ASSIGN_FLOAT2(size, _pad3)
SAFE_ASSIGN_FLOAT(shadow_scale, _pad4)
return SAFE_READ_END();
}

View File

@@ -242,9 +242,9 @@ ShadowRayPunctual shadow_ray_generate_punctual(LightData light, vec2 random_2d,
vec3 direction;
if (is_area_light(light.type)) {
random_2d *= light_area_data_get(light).size;
random_2d *= light_area_data_get(light).size * light_area_data_get(light).shadow_scale;
vec3 point_on_light_shape = vec3(random_2d * shape_radius, 0.0);
vec3 point_on_light_shape = vec3(random_2d, 0.0);
direction = point_on_light_shape - lP;
direction = shadow_ray_above_horizon_ensure(direction, lNg, shape_radius);
@@ -257,7 +257,6 @@ ShadowRayPunctual shadow_ray_generate_punctual(LightData light, vec2 random_2d,
make_orthonormal_basis(lL, right, up);
if (is_sphere_light(light.type)) {
/* FIXME(weizhen): this is not well-defined when `dist < light.spot.radius`. */
shape_radius = light_sphere_disk_radius(shape_radius, dist);
}
random_2d *= shape_radius;