Sort lights when we can only render a limited number of them

This ensures that higher priority lights and lights that are closer to the viewer get rendered.
This commit is contained in:
Fernando García Liñán
2021-04-01 03:14:12 +02:00
parent eb761fc7ee
commit 00a6f02a55
2 changed files with 33 additions and 7 deletions

View File

@@ -31,9 +31,9 @@ public:
};
enum Priority {
LOW,
HIGH,
MEDIUM,
HIGH
LOW
};
class UpdateCallback : public osg::NodeCallback {

View File

@@ -28,6 +28,8 @@
#include <simgear/constants.h>
#include <simgear/structure/exception.hxx>
#include "CompositorUtil.hxx"
namespace simgear {
namespace compositor {
@@ -35,8 +37,13 @@ ClusteredShading::ClusteredShading(osg::Camera *camera,
const SGPropertyNode *config) :
_camera(camera)
{
_max_pointlights = config->getIntValue("max-pointlights", 1024);
_max_spotlights = config->getIntValue("max-spotlights", 1024);
const SGPropertyNode *p_max_pointlights =
getPropertyChild(config, "max-pointlights");
_max_pointlights = p_max_pointlights ? p_max_pointlights->getIntValue() : 1024;
const SGPropertyNode *p_max_spotlights =
getPropertyChild(config, "max-spotlights");
_max_spotlights = p_max_spotlights ? p_max_spotlights->getIntValue() : 1024;
_max_light_indices = config->getIntValue("max-light-indices", 256);
_tile_size = config->getIntValue("tile-size", 128);
_depth_slices = config->getIntValue("depth-slices", 1);
@@ -220,9 +227,28 @@ ClusteredShading::update(const SGLightList &light_list)
_spot_bounds.push_back(spot);
}
}
if (_point_bounds.size() > static_cast<unsigned int>(_max_pointlights) ||
_spot_bounds.size() > static_cast<unsigned int>(_max_spotlights)) {
throw sg_range_exception("Maximum amount of visible lights surpassed");
if (_point_bounds.size() > static_cast<unsigned int>(_max_pointlights)) {
// We prefer to render higher priority lights and lights that are close
// to the viewer
std::sort(_point_bounds.begin(), _point_bounds.end(),
[](auto &a, auto &b) {
if (a.light->getPriority() != b.light->getPriority())
return a.light->getPriority() < b.light->getPriority();
return a.position.length() < b.position.length();
});
_point_bounds.resize(_max_pointlights);
}
if (_spot_bounds.size() > static_cast<unsigned int>(_max_spotlights)) {
std::sort(_spot_bounds.begin(), _spot_bounds.end(),
[](auto &a, auto &b) {
if (a.light->getPriority() != b.light->getPriority())
return a.light->getPriority() < b.light->getPriority();
return a.bounding_sphere.center.length() <
b.bounding_sphere.center.length();
});
_spot_bounds.resize(_max_spotlights);
}
float l = 0.f, r = 0.f, b = 0.f, t = 0.f;