Moved ViewDependetShadowMap parameter settings into a dedicated ShadowSettings object in prep for making it possible to scale the API to handle multiple lights and multiple shadow maps per light.

This commit is contained in:
Robert Osfield
2011-09-07 15:55:54 +00:00
parent 772c7d75c5
commit 3a79bc343d
9 changed files with 223 additions and 116 deletions

View File

@@ -15,6 +15,7 @@ SET(TARGET_H
${HEADER_PATH}/ShadowTexture
${HEADER_PATH}/ShadowVolume
${HEADER_PATH}/ShadowedScene
${HEADER_PATH}/ShadowSettings
${HEADER_PATH}/SoftShadowMap
${HEADER_PATH}/ParallelSplitShadowMap
${HEADER_PATH}/Version
@@ -38,6 +39,7 @@ SET(TARGET_SRC
ShadowTexture.cpp
ShadowVolume.cpp
ShadowedScene.cpp
ShadowSettings.cpp
SoftShadowMap.cpp
ParallelSplitShadowMap.cpp
Version.cpp

View File

@@ -0,0 +1,44 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2011 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgShadow/ShadowSettings>
using namespace osgShadow;
ShadowSettings::ShadowSettings():
_baseShadowTextureUnit(1),
_textureSize(2048,2048),
_minimumShadowMapNearFarRatio(0.01),
_shadowMapProjectionHint(PERSPECTIVE_SHADOW_MAP),
_perspectiveShadowMapCutOffAngle(2.0),
_shaderHint(NO_SHADERS),
// _shaderHint(PROVIDE_FRAGMENT_SHADER),
_debugDraw(false)
{
}
ShadowSettings::ShadowSettings(const ShadowSettings& ss, const osg::CopyOp& copyop):
Object(ss,copyop),
_baseShadowTextureUnit(ss._baseShadowTextureUnit),
_textureSize(ss._textureSize),
_minimumShadowMapNearFarRatio(ss._minimumShadowMapNearFarRatio),
_shadowMapProjectionHint(ss._shadowMapProjectionHint),
_perspectiveShadowMapCutOffAngle(ss._perspectiveShadowMapCutOffAngle),
_shaderHint(ss._shaderHint),
_debugDraw(ss._debugDraw)
{
}
ShadowSettings::~ShadowSettings()
{
}

View File

@@ -23,23 +23,34 @@ using namespace osgShadow;
ShadowedScene::ShadowedScene(ShadowTechnique* st):
_receivesShadowTraversalMask(0xffffffff),
_castsShadowTraversalMask(0xffffffff)
_castsShadowTraversalMask(0xffffffff)
{
setNumChildrenRequiringUpdateTraversal(1);
if (st) setShadowTechnique(st);
setShadowSettings(new ShadowSettings);
if (st) setShadowTechnique(st);
}
ShadowedScene::ShadowedScene(const ShadowedScene& copy, const osg::CopyOp& copyop):
osg::Group(copy,copyop),
_receivesShadowTraversalMask(copy._receivesShadowTraversalMask),
_castsShadowTraversalMask(copy._castsShadowTraversalMask)
ShadowedScene::ShadowedScene(const ShadowedScene& ss, const osg::CopyOp& copyop):
osg::Group(ss,copyop),
_receivesShadowTraversalMask(ss._receivesShadowTraversalMask),
_castsShadowTraversalMask(ss._castsShadowTraversalMask)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
if (copy._shadowTechnique.valid())
if (ss._shadowTechnique.valid())
{
setShadowTechnique( dynamic_cast<osgShadow::ShadowTechnique*>(copy._shadowTechnique->clone(copyop)) );
setShadowTechnique( dynamic_cast<osgShadow::ShadowTechnique*>(ss._shadowTechnique->clone(copyop)) );
}
if (ss._shadowSettings)
{
setShadowSettings(ss._shadowSettings.get());
}
else
{
setShadowSettings(new ShadowSettings);
}
}
@@ -61,6 +72,11 @@ void ShadowedScene::traverse(osg::NodeVisitor& nv)
}
}
void ShadowedScene::setShadowSettings(ShadowSettings* ss)
{
_shadowSettings = ss;
}
void ShadowedScene::setShadowTechnique(ShadowTechnique* technique)
{
if (_shadowTechnique == technique) return;

View File

@@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2011 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@@ -285,7 +285,10 @@ ViewDependentShadowMap::ShadowData::ShadowData(ViewDependentShadowMap::ViewDepen
_viewDependentData(vdd),
_textureUnit(0)
{
bool debug = vdd->getViewDependentShadowMap()->getDebugDraw();
const ShadowSettings* settings = vdd->getViewDependentShadowMap()->getShadowedScene()->getShadowSettings();
bool debug = settings->getDebugDraw();
// set up texgen
_texgen = new osg::TexGen;
@@ -293,7 +296,7 @@ ViewDependentShadowMap::ShadowData::ShadowData(ViewDependentShadowMap::ViewDepen
// set up the texture
_texture = new osg::Texture2D;
osg::Vec2s textureSize = debug ? osg::Vec2s(512,512) : vdd->getViewDependentShadowMap()->getTextureSize();
osg::Vec2s textureSize = debug ? osg::Vec2s(512,512) : settings->getTextureSize();
_texture->setTextureSize(textureSize.x(), textureSize.y());
if (debug)
@@ -522,28 +525,13 @@ void ViewDependentShadowMap::ViewDependentData::releaseGLObjects(osg::State* sta
// ViewDependentShadowMap
//
ViewDependentShadowMap::ViewDependentShadowMap():
ShadowTechnique(),
_baseShadowTextureUnit(1),
_textureSize(2048,2048),
_minimumShadowMapNearFarRatio(0.01),
_shadowMapProjectionHint(PERSPECTIVE_SHADOW_MAP),
_perspectiveShadowMapCutOffAngle(2.0),
_shaderHint(NO_SHADERS),
// _shaderHint(PROVIDE_FRAGMENT_SHADER),
_debugDraw(false)
ShadowTechnique()
{
_shadowRecievingPlaceholderStateSet = new osg::StateSet;
}
ViewDependentShadowMap::ViewDependentShadowMap(const ViewDependentShadowMap& vdsm, const osg::CopyOp& copyop):
ShadowTechnique(vdsm,copyop),
_baseShadowTextureUnit(vdsm._baseShadowTextureUnit),
_textureSize(vdsm._textureSize),
_minimumShadowMapNearFarRatio(vdsm._minimumShadowMapNearFarRatio),
_shadowMapProjectionHint(vdsm._shadowMapProjectionHint),
_perspectiveShadowMapCutOffAngle(vdsm._perspectiveShadowMapCutOffAngle),
_shaderHint(vdsm._shaderHint),
_debugDraw(vdsm._debugDraw)
ShadowTechnique(vdsm,copyop)
{
_shadowRecievingPlaceholderStateSet = new osg::StateSet;
}
@@ -662,8 +650,10 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
// create a list of light sources + their matrices to place them
selectActiveLights(&cv, vdd);
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
unsigned int pos_x = 0;
unsigned int textureUnit = _baseShadowTextureUnit;
unsigned int textureUnit = settings->getBaseShadowTextureUnit();
unsigned int numValidShadows = 0;
ShadowDataList& sdl = vdd->getShadowDataList();
@@ -698,7 +688,7 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
osg::ref_ptr<osg::Camera> camera = sd->_camera;
if (_debugDraw)
if (settings->getDebugDraw())
{
camera->getViewport()->x() = pos_x;
pos_x += camera->getViewport()->width() + 40;
@@ -744,7 +734,7 @@ void ViewDependentShadowMap::cull(osgUtil::CullVisitor& cv)
cv.popStateSet();
if (!orthographicViewFrustum && _shadowMapProjectionHint==PERSPECTIVE_SHADOW_MAP)
if (!orthographicViewFrustum && settings->getShadowMapProjectionHint()==ShadowSettings::PERSPECTIVE_SHADOW_MAP)
{
adjustPerspectiveShadowMapCameraSettings(vdsmCallback->getRenderStage(), frustum, pl, camera.get());
if (vdsmCallback->getProjectionMatrix())
@@ -838,7 +828,9 @@ void ViewDependentShadowMap::createShaders()
_shadowCastingStateSet = new osg::StateSet;
if (!_debugDraw)
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
if (!settings->getDebugDraw())
{
// note soft (attribute only no mode override) setting. When this works ?
// 1. for objects prepared for backface culling
@@ -876,21 +868,21 @@ void ViewDependentShadowMap::createShaders()
osg::ref_ptr<osg::Uniform> baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit);
_uniforms.push_back(baseTextureUnit.get());
osg::ref_ptr<osg::Uniform> shadowTextureSampler = new osg::Uniform("shadowTexture",(int)_baseShadowTextureUnit);
osg::ref_ptr<osg::Uniform> shadowTextureSampler = new osg::Uniform("shadowTexture",(int)(settings->getBaseShadowTextureUnit()));
_uniforms.push_back(shadowTextureSampler.get());
osg::ref_ptr<osg::Uniform> shadowTextureUnit = new osg::Uniform("shadowTextureUnit",(int)_baseShadowTextureUnit);
osg::ref_ptr<osg::Uniform> shadowTextureUnit = new osg::Uniform("shadowTextureUnit",(int)(settings->getBaseShadowTextureUnit()));
_uniforms.push_back(shadowTextureUnit.get());
switch(_shaderHint)
switch(settings->getShaderHint())
{
case(NO_SHADERS):
case(ShadowSettings::NO_SHADERS):
{
OSG_NOTICE<<"No shaders provided by, user must supply own shaders"<<std::endl;
break;
}
case(PROVIDE_VERTEX_AND_FRAGMENT_SHADER):
case(PROVIDE_FRAGMENT_SHADER):
case(ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER):
case(ShadowSettings::PROVIDE_FRAGMENT_SHADER):
{
//osg::ref_ptr<osg::Shader> fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
osg::ref_ptr<osg::Shader> fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_withBaseTexture);
@@ -1045,9 +1037,11 @@ bool ViewDependentShadowMap::computeShadowCameraSettings(Frustum& frustum, Light
osg::Vec3d lightSide;
const ShadowSettings* settings = getShadowedScene()->getShadowSettings();
double dotProduct_v = positionedLight.lightDir * frustum.frustumCenterLine;
double gamma_v = acos(dotProduct_v);
if (gamma_v<osg::DegreesToRadians(_perspectiveShadowMapCutOffAngle) || gamma_v>osg::DegreesToRadians(180.0-_perspectiveShadowMapCutOffAngle))
if (gamma_v<osg::DegreesToRadians(settings->getPerspectiveShadowMapCutOffAngle()) || gamma_v>osg::DegreesToRadians(180.0-settings->getPerspectiveShadowMapCutOffAngle()))
{
OSG_INFO<<"View direction and Light direction below tolerance"<<std::endl;
osg::Vec3d viewSide = osg::Matrixd::transform3x3(frustum.modelViewMatrix, osg::Vec3d(1.0,0.0,0.0));
@@ -1507,6 +1501,7 @@ struct RenderLeafBounds
bool ViewDependentShadowMap::adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera)
{
const ShadowSettings* settings = getShadowedScene()->getShadowSettings();
//frustum.projectionMatrix;
//frustum.modelViewMatrix;
@@ -1608,7 +1603,7 @@ bool ViewDependentShadowMap::adjustPerspectiveShadowMapCameraSettings(osgUtil::R
double dotProduct_v = lightdir * viewdir_v;
double gamma_v = acos(dotProduct_v);
if (gamma_v<osg::DegreesToRadians(_perspectiveShadowMapCutOffAngle) || gamma_v>osg::DegreesToRadians(180-_perspectiveShadowMapCutOffAngle))
if (gamma_v<osg::DegreesToRadians(settings->getPerspectiveShadowMapCutOffAngle()) || gamma_v>osg::DegreesToRadians(180-settings->getPerspectiveShadowMapCutOffAngle()))
{
// OSG_NOTICE<<"Light and view vectors near parrallel - use standard shadow map."<<std::endl;
return true;
@@ -1640,7 +1635,7 @@ bool ViewDependentShadowMap::adjustPerspectiveShadowMapCameraSettings(osgUtil::R
double alpha = osg::DegreesToRadians(30.0);
double n = tan(alpha)*tan(osg::PI_2-gamma_v)*tan(osg::PI_2-gamma_v);
//double n = tan(alpha)*tan(osg::PI_2-gamma_v);
double min_n = osg::maximum(-1.0-eye_ls.y(), _minimumShadowMapNearFarRatio);
double min_n = osg::maximum(-1.0-eye_ls.y(), settings->getMinimumShadowMapNearFarRatio());
if (n<min_n)
{
OSG_INFO<<"Clamping n to eye point"<<std::endl;