mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Merge branch 'close_lights' into 'master'
[Postprocessing] Pass sorted lights and ones with associated geometry See merge request OpenMW/openmw!1976
This commit is contained in:
commit
5725b5a29c
@ -1140,32 +1140,32 @@ namespace SceneUtil
|
||||
l.mLightSource = transform.mLightSource;
|
||||
l.mViewBound = viewBound;
|
||||
it->second.push_back(l);
|
||||
|
||||
if (mPPLightBuffer && it->first->getName() == Constants::SceneCamera)
|
||||
{
|
||||
const auto* light = l.mLightSource->getLight(frameNum);
|
||||
if (light->getDiffuse().x() >= 0.f)
|
||||
{
|
||||
mPPLightBuffer->setLight(frameNum, light->getPosition(),
|
||||
light->getDiffuse(),
|
||||
light->getConstantAttenuation(),
|
||||
light->getLinearAttenuation(),
|
||||
light->getQuadraticAttenuation(),
|
||||
l.mLightSource->getRadius());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
if (it->second.size() > static_cast<size_t>(getMaxLightsInScene() - 1))
|
||||
const bool fillPPLights = mPPLightBuffer && it->first->getName() == Constants::SceneCamera;
|
||||
|
||||
if (fillPPLights || getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
auto sorter = [] (const LightSourceViewBound& left, const LightSourceViewBound& right) {
|
||||
return left.mViewBound.center().length2() - left.mViewBound.radius2() < right.mViewBound.center().length2() - right.mViewBound.radius2();
|
||||
};
|
||||
std::sort(it->second.begin() + 1, it->second.end(), sorter);
|
||||
it->second.erase((it->second.begin() + 1) + (getMaxLightsInScene() - 2), it->second.end());
|
||||
|
||||
std::sort(it->second.begin(), it->second.end(), sorter);
|
||||
|
||||
if (fillPPLights)
|
||||
{
|
||||
for (const auto& bound : it->second)
|
||||
{
|
||||
if (bound.mLightSource->getEmpty())
|
||||
continue;
|
||||
const auto* light = bound.mLightSource->getLight(frameNum);
|
||||
if (light->getDiffuse().x() >= 0.f)
|
||||
mPPLightBuffer->setLight(frameNum, light, bound.mLightSource->getRadius());
|
||||
}
|
||||
}
|
||||
|
||||
if (it->second.size() > static_cast<size_t>(getMaxLightsInScene() - 1))
|
||||
it->second.resize(getMaxLightsInScene() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace SceneUtil
|
||||
mIndex[frame % 2] = 0;
|
||||
}
|
||||
|
||||
void setLight(size_t frame, const osg::Vec4f& position, osg::Vec4f diffuse, float ac, float al, float aq, float radius)
|
||||
void setLight(size_t frame, const osg::Light* light, float radius)
|
||||
{
|
||||
size_t frameId = frame % 2;
|
||||
size_t i = mIndex[frameId];
|
||||
@ -70,9 +70,9 @@ namespace SceneUtil
|
||||
|
||||
i *= 3;
|
||||
|
||||
mUniformBuffers[frameId]->setElement(i + 0, position);
|
||||
mUniformBuffers[frameId]->setElement(i + 1, diffuse);
|
||||
mUniformBuffers[frameId]->setElement(i + 2, osg::Vec4f(ac, al, aq, radius));
|
||||
mUniformBuffers[frameId]->setElement(i + 0, light->getPosition());
|
||||
mUniformBuffers[frameId]->setElement(i + 1, light->getDiffuse());
|
||||
mUniformBuffers[frameId]->setElement(i + 2, osg::Vec4f(light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(), radius));
|
||||
|
||||
mIndex[frameId]++;
|
||||
}
|
||||
@ -118,6 +118,8 @@ namespace SceneUtil
|
||||
|
||||
unsigned int mLastAppliedFrame;
|
||||
|
||||
bool mEmpty = false;
|
||||
|
||||
public:
|
||||
|
||||
META_Node(SceneUtil, LightSource)
|
||||
@ -147,6 +149,16 @@ namespace SceneUtil
|
||||
return mActorFade;
|
||||
}
|
||||
|
||||
void setEmpty(bool empty)
|
||||
{
|
||||
mEmpty = empty;
|
||||
}
|
||||
|
||||
bool getEmpty() const
|
||||
{
|
||||
return mEmpty;
|
||||
}
|
||||
|
||||
/// Get the osg::Light safe for modification in the given frame.
|
||||
/// @par May be used externally to animate the light's color/attenuation properties,
|
||||
/// and is used internally to synchronize the light's position with the position of the LightSource.
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <osg/Light>
|
||||
#include <osg/Group>
|
||||
|
||||
#include <osgParticle/ParticleSystem>
|
||||
|
||||
#include <components/esm3/loadligh.hpp>
|
||||
#include <components/fallback/fallback.hpp>
|
||||
|
||||
@ -11,6 +13,33 @@
|
||||
#include "util.hpp"
|
||||
#include "visitor.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class CheckEmptyLightVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
CheckEmptyLightVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
void apply(osg::Drawable& drawable) override
|
||||
{
|
||||
if (!mEmpty)
|
||||
return;
|
||||
|
||||
if (dynamic_cast<const osgParticle::ParticleSystem*>(&drawable))
|
||||
mEmpty = false;
|
||||
else
|
||||
traverse(drawable);
|
||||
}
|
||||
|
||||
void apply(osg::Geometry& geometry) override
|
||||
{
|
||||
mEmpty = false;
|
||||
}
|
||||
|
||||
bool mEmpty = true;
|
||||
};
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
|
||||
@ -64,6 +93,12 @@ namespace SceneUtil
|
||||
osg::Group* attachTo = visitor.mFoundNode ? visitor.mFoundNode : node;
|
||||
osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, lightMask, isExterior, osg::Vec4f(0,0,0,1));
|
||||
attachTo->addChild(lightSource);
|
||||
|
||||
CheckEmptyLightVisitor emptyVisitor;
|
||||
node->accept(emptyVisitor);
|
||||
|
||||
lightSource->setEmpty(emptyVisitor.mEmpty);
|
||||
|
||||
return lightSource;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user