From 40723ca8acb9dd3ca015f329e469e4e16b4bf865 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 18 Sep 2008 13:05:24 +0000 Subject: [PATCH] From Chris Denham, " I think I may have discovered a bug in osgShadow/ShadowMap.cpp that results in incomplete shadows being generated. The problem seems to caused by an incorrect interpretation of the spot light cutoff angle. The valid ranges for spot cutoff are 0-90 and 180, i.e half the 'field of view' for the spotlight. Whereas the shadow map code seems to assume the the spot cutoff is equal to the field of view. This results in the shadows generated by the spotlight getting clipped at half the spot cutoff angle. I have fixed this in my copy of ShadowMap.cpp: =============================== //Original code from OSG 2.6: if(selectLight->getSpotCutoff() < 180.0f) // spotlight, then we don't need the bounding box { osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); float spotAngle = selectLight->getSpotCutoff(); _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0); _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); } =============================== // My modifications: float fov = selectLight->getSpotCutoff() * 2; if(fov < 180.0f) // spotlight, then we don't need the bounding box { osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); _camera->setProjectionMatrixAsPerspective(fov, 1.0, 0.1, 1000.0); _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); } This change seems correct for spot cutoff in the range 0, 90, but since OpenGL doesn't claim to support cutoffs >90 && <180, I'm not sure how shadow map should deal with those cases, but ignoring spot cut off greater than 90 here seems reasonable to me. " --- src/osgShadow/ShadowMap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgShadow/ShadowMap.cpp b/src/osgShadow/ShadowMap.cpp index 6ad8719b3..24c8295ce 100644 --- a/src/osgShadow/ShadowMap.cpp +++ b/src/osgShadow/ShadowMap.cpp @@ -400,11 +400,11 @@ void ShadowMap::cull(osgUtil::CullVisitor& cv) //std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff "<getSpotCutoff()<getSpotCutoff() < 180.0f) // spotlight, then we don't need the bounding box + float fov = selectLight->getSpotCutoff() * 2; + if(fov < 180.0f) // spotlight, then we don't need the bounding box { osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); - float spotAngle = selectLight->getSpotCutoff(); - _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0); + _camera->setProjectionMatrixAsPerspective(fov, 1.0, 0.1, 1000.0); _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); } else