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.
"
This commit is contained in:
@@ -400,11 +400,11 @@ void ShadowMap::cull(osgUtil::CullVisitor& cv)
|
||||
|
||||
//std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff "<<selectLight->getSpotCutoff()<<std::endl;
|
||||
|
||||
if(selectLight->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
|
||||
|
||||
Reference in New Issue
Block a user