Support setting cascade map splits in light options

This commit is contained in:
Nikita Lisitsa 2020-12-13 13:24:55 +03:00
parent 547b7e8a31
commit ed4d75c498
2 changed files with 18 additions and 9 deletions

View file

@ -72,6 +72,7 @@ namespace psemek::gfx
bool shadowed = true;
std::size_t shadow_map_size = 1024;
std::size_t cascades = 4;
std::vector<geom::interval<float>> cascade_ranges;
};
struct point_light

View file

@ -1497,20 +1497,31 @@ void main()
auto dir = geom::as_vector(camera_clip_planes[4]);
std::vector<geom::interval<float>> cascade_splits(l.cascades);
float offset;
{
float offset;
auto dir_length = geom::length(dir);
float near = camera_clip_planes[4][3] / dir_length;
dir /= dir_length;
offset = geom::dot(camera_position - geom::point<float, 3>::zero(), dir);
near += offset;
float far = -camera_clip_planes[5][3] / geom::length(geom::as_vector(camera_clip_planes[5])) - offset;
float lambda = 1.f / 24.f;
for (int i = 0; i < l.cascades; ++i)
if (l.cascade_ranges.empty())
{
cascade_splits[i].max = (1.f - lambda) * near * std::pow(far / near, i * 1.f / l.cascades) + lambda * (near + (far - near) * (i * 1.f / l.cascades));
cascade_splits[i].min = (1.f - lambda) * near * std::pow(far / near, (i + 1) * 1.f / l.cascades) + lambda * (near + (far - near) * ((i + 1) * 1.f / l.cascades));
cascade_splits[i] -= offset;
float lambda = 1.f / 24.f;
for (int i = 0; i < l.cascades; ++i)
{
cascade_splits[i].max = (1.f - lambda) * near * std::pow(far / near, i * 1.f / l.cascades) + lambda * (near + (far - near) * (i * 1.f / l.cascades));
cascade_splits[i].min = (1.f - lambda) * near * std::pow(far / near, (i + 1) * 1.f / l.cascades) + lambda * (near + (far - near) * ((i + 1) * 1.f / l.cascades));
cascade_splits[i] -= offset;
}
}
else
{
for (int i = 0; i < l.cascades; ++i)
{
cascade_splits[i] = - l.cascade_ranges[i] - offset;
}
}
}
@ -1578,10 +1589,7 @@ void main()
}
for (auto const & v : geom::vertices(casts_shadow_bbox))
{
// light_bbox[2].min = std::min(light_bbox[2].min, geom::dot(light_axes[2], v - origin));
light_bbox[2] |= geom::dot(light_axes[2], v - origin);
}
light_transform[cascade] = geom::orthographic_camera{light_bbox}.projection() * geom::homogeneous(geom::by_rows(light_axes[0], light_axes[1], light_axes[2]));