Show
Ignore:
Timestamp:
03/04/08 17:22:47 (6 years ago)
Author:
robert
Message:

From Wojciech Lewandowski, "Attached is modified osgShadow::ShadowMap?. I changed following things:


1:
Shadow map camera sets ABSOLUTE_RF_INHERIT_VIEWPOINT refernce frame.


2:
Light Direction by matrix multiplications replaced with transform3x3 multiplication.


3:
I made DebugingHUD functional by adding special draw callback. Former version was simply drawing pale square.


4:
I was tempted to make 4 th change but decided to not do it. Instead I put it whith #if VIEW_DEPNDENT_TEXGEN. If you decide you may let it go.


When objects are not centered at 0,0,0 coord but in some distant location (for example at surface of earth ellipsoid) shadow texgen suffers from inadequate precision of float matrices. I changed that by premultiplying Texgen matrix (using OSG double matrices) with inverse modelview and applying it later with ModelView? identity matrix. This tweak may be appropriate for OverlayNode? texgen as well.


I left former version because I suspect that this change will make osgShadow::ShadowMap? view dependant. Currently texgen matrix remains the same no matter what View displays it. With my change it wuld be different for each view. This touches the subject of View Dependent Shadow Techniques that J-S asked recently."

Files:
1 modified

Legend:

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

    r7811 r7913  
    2929#include <osgDB/ReadFile> 
    3030#include <osgText/Text> 
     31 
     32#define IMPROVE_TEXGEN_PRECISION 1 
    3133 
    3234////////////////////////////////////////////////////////////////// 
     
    7577    "{ \n" 
    7678    "   vec4 texResult = texture2D(osgShadow_shadowTexture, gl_TexCoord[0].st ); \n" 
    77     "   float value = texResult.r + 0.5; \n" 
     79    "   float value = texResult.r; \n" 
    7880    "   gl_FragColor = vec4( value, value, value, 0.8 ); \n" 
    7981    "} \n"; 
     
    180182        // create the camera 
    181183        _camera = new osg::Camera; 
     184 
     185        _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT); 
    182186 
    183187        _camera->setCullCallback(new CameraCullCallback(this)); 
     
    364368            { 
    365369                lightpos = light->getPosition() * (*matrix); 
    366                 lightDir = light->getDirection() * (*matrix); 
     370                lightDir = osg::Matrix::transform3x3( light->getDirection(), *matrix ); 
    367371            } 
    368372            else  
     
    378382    eyeToWorld.invert(*cv.getModelViewMatrix()); 
    379383 
    380     lightpos = lightpos * eyeToWorld; 
    381     //MR do we do this for the direction also ? preliminary Yes, but still no good result 
    382     lightDir = lightDir * eyeToWorld; 
     384    lightpos = lightpos * eyeToWorld;      
     385    lightDir = osg::Matrix::transform3x3( lightDir, eyeToWorld ); 
    383386    lightDir.normalize(); 
    384387 
     
    395398            osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); 
    396399            float spotAngle = selectLight->getSpotCutoff(); 
    397             _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 
    398400            _camera->setProjectionMatrixAsPerspective(spotAngle, 1.0, 0.1, 1000.0); 
    399401            _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); 
     
    423425                float right = top; 
    424426 
    425                 _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 
    426427                _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); 
    427428                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); 
     
    446447                float right = top; 
    447448 
    448                 _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 
    449449                _camera->setProjectionMatrixAsOrtho(-right, right, -top, top, znear, zfar); 
    450450                _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); 
     
    453453 
    454454        } 
    455             // compute the matrix which takes a vertex from local coords into tex coords 
    456             // will use this later to specify osg::TexGen.. 
    457             osg::Matrix MVPT = _camera->getViewMatrix() *  
    458                 _camera->getProjectionMatrix() * 
    459                 osg::Matrix::translate(1.0,1.0,1.0) * 
    460                 osg::Matrix::scale(0.5f,0.5f,0.5f); 
    461  
    462             _texgen->setMode(osg::TexGen::EYE_LINEAR); 
    463             _texgen->setPlanesFromMatrix(MVPT); 
    464455 
    465456        cv.setTraversalMask( traversalMask &  
     
    469460        _camera->accept(cv); 
    470461 
     462        _texgen->setMode(osg::TexGen::EYE_LINEAR); 
     463 
     464#if IMPROVE_TEXGEN_PRECISION 
     465        // compute the matrix which takes a vertex from local coords into tex coords 
     466        // We actually use two matrices one used to define texgen 
     467        // and second that will be used as modelview when appling to OpenGL 
     468        _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() * 
     469                                      osg::Matrix::translate(1.0,1.0,1.0) * 
     470                                      osg::Matrix::scale(0.5f,0.5f,0.5f) ); 
     471 
     472        // Place texgen with modelview which removes big offsets (making it float friendly) 
     473        osg::RefMatrix * refMatrix = new osg::RefMatrix 
     474            ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() ); 
     475 
     476        cv.getRenderStage()->getPositionalStateContainer()-> 
     477             addPositionedTextureAttribute( _shadowTextureUnit, refMatrix, _texgen.get() ); 
     478#else  
     479        // compute the matrix which takes a vertex from local coords into tex coords 
     480        // will use this later to specify osg::TexGen.. 
     481        osg::Matrix MVPT = _camera->getViewMatrix() *  
     482               _camera->getProjectionMatrix() * 
     483               osg::Matrix::translate(1.0,1.0,1.0) * 
     484               osg::Matrix::scale(0.5f,0.5f,0.5f); 
     485 
     486        _texgen->setPlanesFromMatrix(MVPT); 
     487 
    471488        orig_rs->getPositionalStateContainer()->addPositionedTextureAttribute(_shadowTextureUnit, cv.getModelViewMatrix(), _texgen.get()); 
     489#endif 
    472490    } // if(selectLight) 
    473491 
     
    483501///////////////////// Debug Methods 
    484502 
     503//////////////////////////////////////////////////////////////////////////////// 
     504// Callback used by debugging hud to display Shadow Map in color buffer 
     505// OSG does not allow to use the same GL Texture Id with different glTexParams.  
     506// Callback simply turns shadow compare mode off via GL while rendering hud and  
     507// restores it afterwards.  
     508//////////////////////////////////////////////////////////////////////////////// 
     509class DrawableDrawWithDepthShadowComparisonOffCallback:  
     510    public osg::Drawable::DrawCallback 
     511{ 
     512public: 
     513    //  
     514    DrawableDrawWithDepthShadowComparisonOffCallback 
     515        ( osg::Texture2D * texture, unsigned stage = 0 ) 
     516            : _texture( texture ), _stage( stage ) 
     517    { 
     518    } 
     519 
     520    virtual void drawImplementation 
     521        ( osg::RenderInfo & ri,const osg::Drawable* drawable ) const 
     522    { 
     523        if( _texture.valid() ) { 
     524            // make sure proper texture is currently applied 
     525            ri.getState()->applyTextureAttribute( _stage, _texture.get() ); 
     526 
     527            // Turn off depth comparison mode 
     528            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,  
     529                             GL_NONE ); 
     530        } 
     531 
     532        drawable->drawImplementation(ri); 
     533 
     534        if( _texture.valid() ) { 
     535            // Turn it back on 
     536            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,  
     537                             GL_COMPARE_R_TO_TEXTURE_ARB ); 
     538        } 
     539    } 
     540 
     541    unsigned                       _stage; 
     542    osg::ref_ptr< osg::Texture2D > _texture; 
     543}; 
     544//////////////////////////////////////////////////////////////////////////////// 
    485545osg::ref_ptr<osg::Camera> ShadowMap::makeDebugHUD() 
    486546{ 
     547    // Make sure we attach initialized texture to HUD 
     548    if( !_texture.valid() )    init(); 
     549 
    487550    osg::ref_ptr<osg::Camera> camera = new osg::Camera; 
    488551 
     
    510573    osg::Vec3 position(10.0f,size.y()-100.0f,0.0f); 
    511574    osg::Vec3 delta(0.0f,-120.0f,0.0f);  
    512     float lenght = 300.0f; 
     575    float length = 300.0f; 
    513576 
    514577    // turn the text off to avoid linking with osgText 
     
    528591#endif 
    529592 
    530     osg::Vec3 widthVec(lenght, 0.0f, 0.0f); 
    531     osg::Vec3 depthVec(0.0f,lenght, 0.0f); 
    532     osg::Vec3 centerBase( 10.0f + lenght/2, size.y()-lenght/2, 0.0f); 
     593    osg::Vec3 widthVec(length, 0.0f, 0.0f); 
     594    osg::Vec3 depthVec(0.0f,length, 0.0f); 
     595    osg::Vec3 centerBase( 10.0f + length/2, size.y()-length/2, 0.0f); 
    533596    centerBase += delta; 
    534597 
    535     geode->addDrawable( osg::createTexturedQuadGeometry( centerBase-widthVec*0.5f-depthVec*0.5f,  
    536                                                          widthVec, depthVec) ); 
     598    osg::Geometry *geometry = osg::createTexturedQuadGeometry 
     599        ( centerBase-widthVec*0.5f-depthVec*0.5f, widthVec, depthVec ); 
     600 
     601    geode->addDrawable( geometry ); 
     602 
     603    geometry->setDrawCallback 
     604        ( new DrawableDrawWithDepthShadowComparisonOffCallback( _texture.get() ) ); 
    537605 
    538606    osg::StateSet* stateset = geode->getOrCreateStateSet(); 
     
    544612 
    545613    // test with regular texture 
    546     //stateset->setTextureAttributeAndModes(_baseTextureUnit, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb"))); 
    547  
    548     stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON); 
     614    //stateset->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb"))); 
     615 
     616    stateset->setTextureAttributeAndModes(0,_texture.get(),osg::StateAttribute::ON); 
    549617 
    550618    //test to check the texture coordinates generated during shadow pass