Introduced --near-far-mode into osgshadow and ShadowSettings::setComputeNearFarModeOverride(..) to allow user control of how the cull traversal is optimized for computing the depth range of the shadow map.

This commit is contained in:
Robert Osfield 2012-08-03 16:14:14 +00:00
parent 35816e6b25
commit fb83c2b061
4 changed files with 40 additions and 3 deletions

View File

@ -741,6 +741,7 @@ int main(int argc, char** argv)
arguments.getApplicationUsage()->addCommandLineOption("-4", "Use test model four - island scene."); arguments.getApplicationUsage()->addCommandLineOption("-4", "Use test model four - island scene.");
arguments.getApplicationUsage()->addCommandLineOption("--two-sided", "Use two-sided stencil extension for shadow volumes."); arguments.getApplicationUsage()->addCommandLineOption("--two-sided", "Use two-sided stencil extension for shadow volumes.");
arguments.getApplicationUsage()->addCommandLineOption("--two-pass", "Use two-pass stencil for shadow volumes."); arguments.getApplicationUsage()->addCommandLineOption("--two-pass", "Use two-pass stencil for shadow volumes.");
arguments.getApplicationUsage()->addCommandLineOption("--near-far-mode","COMPUTE_NEAR_USING_PRIMITIVES, COMPUTE_NEAR_FAR_USING_PRIMITIVES, COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES, DO_NOT_COMPUTE_NEAR_FAR");
// construct the viewer. // construct the viewer.
osgViewer::Viewer viewer(arguments); osgViewer::Viewer viewer(arguments);
@ -840,6 +841,25 @@ int main(int argc, char** argv)
settings->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); settings->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask);
settings->setCastsShadowTraversalMask(CastsShadowTraversalMask); settings->setCastsShadowTraversalMask(CastsShadowTraversalMask);
std::string nearFarMode("");
if (arguments.read("--near-far-mode",nearFarMode))
{
if (nearFarMode=="COMPUTE_NEAR_USING_PRIMITIVES") settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_USING_PRIMITIVES);
else if (nearFarMode=="COMPUTE_NEAR_FAR_USING_PRIMITIVES") settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
else if (nearFarMode=="DO_NOT_COMPUTE_NEAR_FAR") settings->setComputeNearFarModeOverride(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
else if (nearFarMode=="COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES") settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);
OSG_NOTICE<<"ComputeNearFarModeOverride set to ";
switch(settings->getComputeNearFarModeOverride())
{
case(osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES): OSG_NOTICE<<"COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES"; break;
case(osg::CullSettings::COMPUTE_NEAR_USING_PRIMITIVES): OSG_NOTICE<<"COMPUTE_NEAR_USING_PRIMITIVES"; break;
case(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES): OSG_NOTICE<<"COMPUTE_NEAR_FAR_USING_PRIMITIVES"; break;
case(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR): OSG_NOTICE<<"DO_NOT_COMPUTE_NEAR_FAR"; break;
}
OSG_NOTICE<<std::endl;
}
osg::ref_ptr<osgShadow::MinimalShadowMap> msm = NULL; osg::ref_ptr<osgShadow::MinimalShadowMap> msm = NULL;
if (arguments.read("--no-shadows")) if (arguments.read("--no-shadows"))
{ {

View File

@ -15,6 +15,7 @@
#define OSGSHADOW_SHADOWSETTINGS 1 #define OSGSHADOW_SHADOWSETTINGS 1
#include <osg/Uniform> #include <osg/Uniform>
#include <osg/CullSettings>
#include <osgShadow/Export> #include <osgShadow/Export>
namespace osgShadow { namespace osgShadow {
@ -34,6 +35,10 @@ class OSGSHADOW_EXPORT ShadowSettings : public osg::Object
void setCastsShadowTraversalMask(unsigned int mask) { _castsShadowTraversalMask = mask; } void setCastsShadowTraversalMask(unsigned int mask) { _castsShadowTraversalMask = mask; }
unsigned int getCastsShadowTraversalMask() const { return _castsShadowTraversalMask; } unsigned int getCastsShadowTraversalMask() const { return _castsShadowTraversalMask; }
void setComputeNearFarModeOverride(osg::CullSettings::ComputeNearFarMode cnfn) { _computeNearFearModeOverride = cnfn; }
osg::CullSettings::ComputeNearFarMode getComputeNearFarModeOverride() const { return _computeNearFearModeOverride; }
/** Set the LightNum of the light in the scene to assign a shadow for. /** Set the LightNum of the light in the scene to assign a shadow for.
* Default value is -1, which signifies that shadow technique should automatically select an active light * Default value is -1, which signifies that shadow technique should automatically select an active light
* to assign a shadow, typically this will be the first active light found. */ * to assign a shadow, typically this will be the first active light found. */
@ -113,6 +118,8 @@ class OSGSHADOW_EXPORT ShadowSettings : public osg::Object
unsigned int _receivesShadowTraversalMask; unsigned int _receivesShadowTraversalMask;
unsigned int _castsShadowTraversalMask; unsigned int _castsShadowTraversalMask;
osg::CullSettings::ComputeNearFarMode _computeNearFearModeOverride;
int _lightNum; int _lightNum;
unsigned int _baseShadowTextureUnit; unsigned int _baseShadowTextureUnit;
bool _useShadowMapTextureOverride; bool _useShadowMapTextureOverride;

View File

@ -18,6 +18,7 @@ using namespace osgShadow;
ShadowSettings::ShadowSettings(): ShadowSettings::ShadowSettings():
_receivesShadowTraversalMask(0xffffffff), _receivesShadowTraversalMask(0xffffffff),
_castsShadowTraversalMask(0xffffffff), _castsShadowTraversalMask(0xffffffff),
_computeNearFearModeOverride(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR),
_lightNum(-1), _lightNum(-1),
_baseShadowTextureUnit(1), _baseShadowTextureUnit(1),
_useShadowMapTextureOverride(true), _useShadowMapTextureOverride(true),
@ -31,12 +32,15 @@ ShadowSettings::ShadowSettings():
// _shaderHint(PROVIDE_FRAGMENT_SHADER), // _shaderHint(PROVIDE_FRAGMENT_SHADER),
_debugDraw(false) _debugDraw(false)
{ {
//_computeNearFearModeOverride = osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES;
//_computeNearFearModeOverride = osg::CullSettings::COMPUTE_NEAR_USING_PRIMITIVES);
} }
ShadowSettings::ShadowSettings(const ShadowSettings& ss, const osg::CopyOp& copyop): ShadowSettings::ShadowSettings(const ShadowSettings& ss, const osg::CopyOp& copyop):
Object(ss,copyop), Object(ss,copyop),
_receivesShadowTraversalMask(ss._receivesShadowTraversalMask), _receivesShadowTraversalMask(ss._receivesShadowTraversalMask),
_castsShadowTraversalMask(ss._castsShadowTraversalMask), _castsShadowTraversalMask(ss._castsShadowTraversalMask),
_computeNearFearModeOverride(ss._computeNearFearModeOverride),
_lightNum(ss._lightNum), _lightNum(ss._lightNum),
_baseShadowTextureUnit(ss._baseShadowTextureUnit), _baseShadowTextureUnit(ss._baseShadowTextureUnit),
_useShadowMapTextureOverride(ss._useShadowMapTextureOverride), _useShadowMapTextureOverride(ss._useShadowMapTextureOverride),

View File

@ -746,6 +746,8 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
return; return;
} }
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
OSG_INFO<<"cv->getProjectionMatrix()="<<*cv.getProjectionMatrix()<<std::endl; OSG_INFO<<"cv->getProjectionMatrix()="<<*cv.getProjectionMatrix()<<std::endl;
osg::CullSettings::ComputeNearFarMode cachedNearFarMode = cv.getComputeNearFarMode(); osg::CullSettings::ComputeNearFarMode cachedNearFarMode = cv.getComputeNearFarMode();
@ -775,8 +777,10 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
} }
// set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible // set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible
cv.setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); if (settings->getComputeNearFarModeOverride()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
//cv.setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_USING_PRIMITIVES); {
cv.setComputeNearFarMode(settings->getComputeNearFarModeOverride());
}
// 1. Traverse main scene graph // 1. Traverse main scene graph
cv.pushStateSet( _shadowRecievingPlaceholderStateSet.get() ); cv.pushStateSet( _shadowRecievingPlaceholderStateSet.get() );
@ -795,6 +799,9 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
cv.computeNearPlane(); cv.computeNearPlane();
} }
//minZNear = osg::maximum(10.0,minZNear);
//maxZFar = osg::minimum(60.0,maxZFar);
Frustum frustum(&cv, minZNear, maxZFar); Frustum frustum(&cv, minZNear, maxZFar);
// return compute near far mode back to it's original settings // return compute near far mode back to it's original settings
@ -807,7 +814,6 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
// create a list of light sources + their matrices to place them // create a list of light sources + their matrices to place them
selectActiveLights(&cv, vdd); selectActiveLights(&cv, vdd);
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
unsigned int pos_x = 0; unsigned int pos_x = 0;
unsigned int textureUnit = settings->getBaseShadowTextureUnit(); unsigned int textureUnit = settings->getBaseShadowTextureUnit();