From f83722d62b97f4e6497572689a115f4a453b3ae2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 6 Sep 2011 10:12:45 +0000 Subject: [PATCH] Added s/getPerspectiveShadowMapCutOffAngle() and use of this when setting up light space to avoid sigularaties when the light and view directions are co-incident. --- include/osgShadow/ViewDependentShadowMap | 10 ++++++ src/osgShadow/ViewDependentShadowMap.cpp | 40 +++++++++++++++--------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/include/osgShadow/ViewDependentShadowMap b/include/osgShadow/ViewDependentShadowMap index d76bd15d4..a923f5245 100644 --- a/include/osgShadow/ViewDependentShadowMap +++ b/include/osgShadow/ViewDependentShadowMap @@ -177,6 +177,15 @@ class OSGSHADOW_EXPORT ViewDependentShadowMap : public ShadowTechnique void setShadowMapProjectionHint(ShadowMapProjectionHint hint) { _shadowMapProjectionHint = hint; } ShadowMapProjectionHint getShadowMapProjectionHint() const { return _shadowMapProjectionHint; } + /** Set the cut off angle, in degrees, between the light direction and the view direction + * that determines whether perspective shadow mapping is appropriate, or thar orthographic shadow + * map should be used instead. Default is 2 degrees so that for any angle greater than 2 degrees + * perspective shadow map will be used, and any angle less than 2 degrees orthographic shadow map + * will be used. Note, if ShadowMapProjectionHint is set to ORTHOGRAPHIC_SHADOW_MAP then an + * orthographic shadow map will always be used.*/ + void setPerspectiveShadowMapCutOffAngle(double angle) { _perspectiveShadowMapCutOffAngle = angle; } + double getPerspectiveShadowMapCutOffAngle() const { return _perspectiveShadowMapCutOffAngle; } + enum ShaderHint { NO_SHADERS, @@ -233,6 +242,7 @@ protected: double _minimumShadowMapNearFarRatio; ShadowMapProjectionHint _shadowMapProjectionHint; + double _perspectiveShadowMapCutOffAngle; ShaderHint _shaderHint; bool _debugDraw; diff --git a/src/osgShadow/ViewDependentShadowMap.cpp b/src/osgShadow/ViewDependentShadowMap.cpp index 6fa0f395a..57e56953a 100644 --- a/src/osgShadow/ViewDependentShadowMap.cpp +++ b/src/osgShadow/ViewDependentShadowMap.cpp @@ -526,6 +526,7 @@ ViewDependentShadowMap::ViewDependentShadowMap(): _textureSize(2048,2048), _minimumShadowMapNearFarRatio(0.01), _shadowMapProjectionHint(PERSPECTIVE_SHADOW_MAP), + _perspectiveShadowMapCutOffAngle(2.0), _shaderHint(NO_SHADERS), // _shaderHint(PROVIDE_FRAGMENT_SHADER), _debugDraw(false) @@ -539,6 +540,7 @@ ViewDependentShadowMap::ViewDependentShadowMap(const ViewDependentShadowMap& vds _textureSize(vdsm._textureSize), _minimumShadowMapNearFarRatio(vdsm._minimumShadowMapNearFarRatio), _shadowMapProjectionHint(vdsm._shadowMapProjectionHint), + _perspectiveShadowMapCutOffAngle(vdsm._perspectiveShadowMapCutOffAngle), _shaderHint(vdsm._shaderHint), _debugDraw(vdsm._debugDraw) { @@ -1040,21 +1042,32 @@ bool ViewDependentShadowMap::computeShadowCameraSettings(Frustum& frustum, Light { OSG_INFO<<"standardShadowMapCameraSettings()"< lightSide_z.length()) ? lightSide_y : lightSide_z; - lightSide.normalize(); -#else - osg::Vec3d lightSide = positionedLight.lightDir ^ frustum.frustumCenterLine; lightSide.normalize(); -#endif + osg::Vec3d lightSide; + + double dotProduct_v = positionedLight.lightDir * frustum.frustumCenterLine; + double gamma_v = acos(dotProduct_v); + if (gamma_vosg::DegreesToRadians(180.0-_perspectiveShadowMapCutOffAngle)) + { + OSG_INFO<<"View direction and Light direction below tolerance"<