Show
Ignore:
Timestamp:
09/18/08 15:05:24 (6 years ago)
Author:
robert
Message:

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.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgShadow/ShadowMap.cpp

    r7974 r8886  
    401401        //std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff "<<selectLight->getSpotCutoff()<<std::endl; 
    402402 
    403         if(selectLight->getSpotCutoff() < 180.0f)   // spotlight, then we don't need the bounding box 
     403        float fov = selectLight->getSpotCutoff() * 2; 
     404        if(fov < 180.0f)   // spotlight, then we don't need the bounding box 
    404405        { 
    405406            osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); 
    406             float spotAngle = selectLight->getSpotCutoff(); 
    407             _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0); 
     407            _camera->setProjectionMatrixAsPerspective(fov, 1.0, 0.1, 1000.0); 
    408408            _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); 
    409409        }