mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-20 15:40:32 +00:00
allows to skip ComputeLightSpaceBounds traversal (#3152)
Currently, we always traverse the scene graph an additional time with a ComputeLightSpaceBounds visitor during shadow casting. ComputeLightSpaceBounds is only useful when the shadow casting mask allows us to shrink the bounds of the rendered scene, so we guard its traversal with a check against getCastsShadowTraversalMask. In practice, this guard never works because we build the traversal mask inclusively. With this PR we limit the getCastsShadowTraversalMask check to relevant masks. This new check allows us to skip a superfluous ComputeLightSpaceBounds traversal with most settings.
This commit is contained in:
parent
66a6b80df9
commit
98f8295765
@ -195,7 +195,7 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
|
||||
camera->setNodeMask(Mask_RenderToTexture);
|
||||
|
||||
// Disable small feature culling, it's not going to be reliable for this camera
|
||||
osg::Camera::CullingMode cullingMode = (osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING) & ~(osg::CullStack::SMALL_FEATURE_CULLING);
|
||||
osg::Camera::CullingMode cullingMode = (osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING) & ~(osg::Camera::SMALL_FEATURE_CULLING);
|
||||
camera->setCullingMode(cullingMode);
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||
|
@ -340,14 +340,14 @@ namespace MWRender
|
||||
shadowCastingTraversalMask |= Mask_Actor;
|
||||
if (Settings::Manager::getBool("player shadows", "Shadows"))
|
||||
shadowCastingTraversalMask |= Mask_Player;
|
||||
if (Settings::Manager::getBool("terrain shadows", "Shadows"))
|
||||
shadowCastingTraversalMask |= Mask_Terrain;
|
||||
|
||||
int indoorShadowCastingTraversalMask = shadowCastingTraversalMask;
|
||||
if (Settings::Manager::getBool("object shadows", "Shadows"))
|
||||
shadowCastingTraversalMask |= (Mask_Object|Mask_Static);
|
||||
if (Settings::Manager::getBool("terrain shadows", "Shadows"))
|
||||
shadowCastingTraversalMask |= Mask_Terrain;
|
||||
|
||||
mShadowManager.reset(new SceneUtil::ShadowManager(sceneRoot, mRootNode, shadowCastingTraversalMask, indoorShadowCastingTraversalMask, mResourceSystem->getSceneManager()->getShaderManager()));
|
||||
mShadowManager.reset(new SceneUtil::ShadowManager(sceneRoot, mRootNode, shadowCastingTraversalMask, indoorShadowCastingTraversalMask, Mask_Terrain|Mask_Object|Mask_Static, mResourceSystem->getSceneManager()->getShaderManager()));
|
||||
|
||||
Shader::ShaderManager::DefineMap shadowDefines = mShadowManager->getShadowDefines();
|
||||
Shader::ShaderManager::DefineMap lightDefines = sceneRoot->getLightDefines();
|
||||
|
@ -357,8 +357,6 @@ MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds() :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
|
||||
{
|
||||
setCullingMode(osg::CullSettings::VIEW_FRUSTUM_CULLING);
|
||||
|
||||
setName("SceneUtil::MWShadowTechnique::ComputeLightSpaceBounds,AcceptedByComponentsTerrainQuadTreeWorld");
|
||||
}
|
||||
|
||||
void MWShadowTechnique::ComputeLightSpaceBounds::reset()
|
||||
@ -393,14 +391,6 @@ void MWShadowTechnique::ComputeLightSpaceBounds::apply(osg::Drawable& drawable)
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void MWShadowTechnique::ComputeLightSpaceBounds::apply(Terrain::QuadTreeWorld & quadTreeWorld)
|
||||
{
|
||||
// For now, just expand the bounds fully as terrain will fill them up and possible ways to detect which terrain definitely won't cast shadows aren't implemented.
|
||||
|
||||
update(osg::Vec3(-1.0, -1.0, 0.0));
|
||||
update(osg::Vec3(1.0, 1.0, 0.0));
|
||||
}
|
||||
|
||||
void MWShadowTechnique::ComputeLightSpaceBounds::apply(osg::Billboard&)
|
||||
{
|
||||
OSG_INFO << "Warning Billboards not yet supported" << std::endl;
|
||||
@ -1122,7 +1112,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||
|
||||
// if we are using multiple shadow maps and CastShadowTraversalMask is being used
|
||||
// traverse the scene to compute the extents of the objects
|
||||
if (/*numShadowMapsPerLight>1 &&*/ _shadowedScene->getCastsShadowTraversalMask()!=0xffffffff)
|
||||
if (/*numShadowMapsPerLight>1 &&*/ (_shadowedScene->getCastsShadowTraversalMask() & _worldMask) == 0)
|
||||
{
|
||||
// osg::ElapsedTime timer;
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <osgShadow/ShadowTechnique>
|
||||
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
#include <components/terrain/quadtreeworld.hpp>
|
||||
|
||||
namespace SceneUtil {
|
||||
|
||||
@ -96,8 +95,6 @@ namespace SceneUtil {
|
||||
|
||||
void apply(osg::Drawable& drawable) override;
|
||||
|
||||
void apply(Terrain::QuadTreeWorld& quadTreeWorld);
|
||||
|
||||
void apply(osg::Billboard&) override;
|
||||
|
||||
void apply(osg::Projection&) override;
|
||||
@ -237,6 +234,8 @@ namespace SceneUtil {
|
||||
|
||||
virtual osg::StateSet* prepareStateSetForRenderingShadow(ViewDependentData& vdd, unsigned int traversalNumber) const;
|
||||
|
||||
void setWorldMask(unsigned int worldMask) { _worldMask = worldMask; }
|
||||
|
||||
protected:
|
||||
virtual ~MWShadowTechnique();
|
||||
|
||||
@ -270,6 +269,8 @@ namespace SceneUtil {
|
||||
|
||||
float _shadowFadeStart = 0.0;
|
||||
|
||||
unsigned int _worldMask = ~0u;
|
||||
|
||||
class DebugHUD final : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
@ -1,10 +1,13 @@
|
||||
#include "shadow.hpp"
|
||||
|
||||
#include <osgShadow/ShadowedScene>
|
||||
#include <osgShadow/ShadowSettings>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "mwshadowtechnique.hpp"
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
using namespace osgShadow;
|
||||
@ -94,7 +97,7 @@ namespace SceneUtil
|
||||
}
|
||||
}
|
||||
|
||||
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager) : mShadowedScene(new osgShadow::ShadowedScene),
|
||||
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, unsigned int worldMask, Shader::ShaderManager &shaderManager) : mShadowedScene(new osgShadow::ShadowedScene),
|
||||
mShadowTechnique(new MWShadowTechnique),
|
||||
mOutdoorShadowCastingMask(outdoorShadowCastingMask),
|
||||
mIndoorShadowCastingMask(indoorShadowCastingMask)
|
||||
@ -109,10 +112,15 @@ namespace SceneUtil
|
||||
setupShadowSettings();
|
||||
|
||||
mShadowTechnique->setupCastingShader(shaderManager);
|
||||
mShadowTechnique->setWorldMask(worldMask);
|
||||
|
||||
enableOutdoorMode();
|
||||
}
|
||||
|
||||
ShadowManager::~ShadowManager()
|
||||
{
|
||||
}
|
||||
|
||||
Shader::ShaderManager::DefineMap ShadowManager::getShadowDefines()
|
||||
{
|
||||
if (!mEnableShadows)
|
||||
|
@ -1,15 +1,22 @@
|
||||
#ifndef COMPONENTS_SCENEUTIL_SHADOW_H
|
||||
#define COMPONENTS_SCENEUTIL_SHADOW_H
|
||||
|
||||
#include <osgShadow/ShadowSettings>
|
||||
#include <osgShadow/ShadowedScene>
|
||||
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
|
||||
#include "mwshadowtechnique.hpp"
|
||||
namespace osg
|
||||
{
|
||||
class StateSet;
|
||||
class Group;
|
||||
}
|
||||
namespace osgShadow
|
||||
{
|
||||
class ShadowSettings;
|
||||
class ShadowedScene;
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
class MWShadowTechnique;
|
||||
class ShadowManager
|
||||
{
|
||||
public:
|
||||
@ -17,7 +24,8 @@ namespace SceneUtil
|
||||
|
||||
static Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
|
||||
|
||||
ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager);
|
||||
ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, unsigned int worldMask, Shader::ShaderManager &shaderManager);
|
||||
~ShadowManager();
|
||||
|
||||
void setupShadowSettings();
|
||||
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include <osgUtil/CullVisitor>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/PolygonMode>
|
||||
#include <osg/Material>
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
#include <components/misc/constants.hpp>
|
||||
#include <components/sceneutil/mwshadowtechnique.hpp>
|
||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||
#include <components/loadinglistener/reporter.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
@ -257,10 +257,10 @@ public:
|
||||
{
|
||||
osg::Vec3f center = { chunkCenter.x(), chunkCenter.y(), 0 };
|
||||
auto chunkBorder = CellBorder::createBorderGeometry(center.x() - size / 2.f, center.y() - size / 2.f, size, mStorage, mSceneManager, mNodeMask, 5.f, { 1, 0, 0, 0 });
|
||||
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(osg::Matrixf::translate(-center*Constants::CellSizeInUnits));
|
||||
trans->setDataVariance(osg::Object::STATIC);
|
||||
trans->addChild(chunkBorder);
|
||||
return trans;
|
||||
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> pat = new SceneUtil::PositionAttitudeTransform;
|
||||
pat->setPosition(-center*Constants::CellSizeInUnits);
|
||||
pat->addChild(chunkBorder);
|
||||
return pat;
|
||||
}
|
||||
unsigned int getNodeMask() { return mNodeMask; }
|
||||
private:
|
||||
@ -440,19 +440,7 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
|
||||
{
|
||||
bool isCullVisitor = nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR;
|
||||
if (!isCullVisitor && nv.getVisitorType() != osg::NodeVisitor::INTERSECTION_VISITOR)
|
||||
{
|
||||
if (nv.getName().find("AcceptedByComponentsTerrainQuadTreeWorld") != std::string::npos)
|
||||
{
|
||||
if (nv.getName().find("SceneUtil::MWShadowTechnique::ComputeLightSpaceBounds") != std::string::npos)
|
||||
{
|
||||
SceneUtil::MWShadowTechnique::ComputeLightSpaceBounds* clsb = static_cast<SceneUtil::MWShadowTechnique::ComputeLightSpaceBounds*>(&nv);
|
||||
clsb->apply(*this);
|
||||
}
|
||||
else
|
||||
nv.apply(*mRootNode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Object * viewer = isCullVisitor ? static_cast<osgUtil::CullVisitor*>(&nv)->getCurrentCamera() : nullptr;
|
||||
bool needsUpdate = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user