예제 #1
0
void PCSSShadowMapHandler::createColorMapFBO(RenderAction *a,
                                             DrawEnv      *pEnv)
{
    _pStage->pushPartition(a,
                           (RenderPartition::CopyWindow      |
                            RenderPartition::CopyViewing     |
                            RenderPartition::CopyProjection  |
                            RenderPartition::CopyFrustum     |
                            RenderPartition::CopyNearFar     |
                            RenderPartition::CopyViewportSize),
                           RenderPartition::StateSorting);
    {
        RenderPartition *pPart = a->getActivePartition();

        pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
        pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

        pPart->setRenderTarget(_pSceneFBO);
        pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT0_EXT);

        Node *parent = a->getActNode()->getParent();

        if(parent != NULL)
        {
            a->pushMatrix(parent->getToWorld());
        }
        
        pPart->setBackground(a->getBackground());

        _pStage->recurseFromThis(a);

        if(parent != NULL)
        {
            a->popMatrix();
        }

        if(_pStage->getBlitZBuffer() == true)
        {
            pPart->addPostRenderCallback(&ShadowTreeHandler::blitZBufferCB);
        }
    }
    _pStage->popPartition(a);
}
void VarianceShadowMapHandler::createShadowMapsFBO(RenderAction *a,
                                                   DrawEnv      *pEnv)
{
    UInt32  mSize = _pStage->getMapSize();

    if(mSize > 2048)
        mSize = 2048;

    //------Setting up Window to fit size of ShadowMap----------------


    // disable all lights more speed
    std::vector<bool> vLocalLightStates;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();

    const ShadowStageData::StatusStore &vExclActive  =
        _pStageData->getExcludeNodeActive();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // store old states.
        vLocalLightStates.push_back(vLights[i].second->getOn());
        vLights[i].second->setOn(false);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
        {
            if(vExclActive[i])
            {
                exnode->setTravMask(0);
            }
        }
    }

    UInt32 uiActiveLightCount = 0;

    ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        if(vLightStates[i] != 0)
        {
            if(_pStage->getGlobalShadowIntensity()    != 0.0 ||
                vLights[i].second->getShadowIntensity() != 0.0)
            {

                GLenum  *buffers = NULL;
                buffers = new GLenum[1];
                buffers[0] = GL_COLOR_ATTACHMENT0_EXT;

                Pnt3f   lPos;
                bool    isDirLight;
                Real32  sceneDiagLength;

                if(vLights[i].second->getType() == PointLight::getClassType())
                {
                    PointLight *tmpPoint;
                    tmpPoint = 
                        dynamic_cast<PointLight *>(vLights[i].second.get());

                    lPos = tmpPoint->getPosition();

                    if(tmpPoint->getBeacon() != NULL)
                    {
                        Matrix  m = tmpPoint->getBeacon()->getToWorld();
                        m.mult(lPos, lPos);
                    }
                    isDirLight = false;

                    Pnt3f           center;
                    _pStageData->getLightRoot(i)->getVolume().getCenter(center);

                    Vec3f           dir = lPos - center;
                    Real32          dirLength = dir.length();

                    Vec3f           diff =
                        (_pStageData->getLightRoot(i)->getVolume().getMax() -
                         center);
                    Real32          diffLength = diff.length();

                    sceneDiagLength = dirLength + diffLength;
                }

                else if(vLights[i].second->getType() == 
                                                     SpotLight::getClassType())
                {
                    SpotLight *tmpSpot;
                    tmpSpot = 
                        dynamic_cast<SpotLight *>(vLights[i].second.get());

                    lPos = tmpSpot->getPosition();
                    if(tmpSpot->getBeacon() != NULL)
                    {
                        Matrix  m = tmpSpot->getBeacon()->getToWorld();
                        m.mult(lPos, lPos);
                    }
                    isDirLight = false;
                    Pnt3f           center;
                    _pStageData->getLightRoot(i)->getVolume().getCenter(center);

                    Vec3f           dir = lPos - center;
                    Real32          dirLength = dir.length();

                    Vec3f           diff =
                        (_pStageData->getLightRoot(i)->getVolume().getMax() -
                         center);
                    Real32          diffLength = diff.length();

                    sceneDiagLength = dirLength + diffLength;
                }

                else
                {
                    isDirLight = true;
                    sceneDiagLength = 1.0;
                }

                if(_vDepthCmat.size() == uiActiveLightCount)
                {
                    _vDepthCmat.push_back(ChunkMaterial::createLocal());
                }
        
                OSG_ASSERT(uiActiveLightCount < _vDepthCmat.size());

                if(_vDepthSHLVar.size() == uiActiveLightCount)
                {
                    _vDepthSHLVar.push_back(
                        SimpleSHLVariableChunk::createLocal());
                    
#ifndef OSG_NEW_SHADER
                    _vDepthSHLVar[uiActiveLightCount]->setSHLChunk(_depthSHL);
#endif
                }

                OSG_ASSERT(uiActiveLightCount < _vDepthSHLVar.size());

                _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
                    "sceneDiagLength",
                    Real32(sceneDiagLength));

                _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
                    "isDirLight", bool(isDirLight));

                
                _vDepthCmat[uiActiveLightCount]->clearChunks();
                _vDepthCmat[uiActiveLightCount]->addChunk(_depthSHL);
                _vDepthCmat[uiActiveLightCount]->addChunk(
                    _vDepthSHLVar[uiActiveLightCount]);

                commitChanges();

                _pStage->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();

                    pPart->addPreRenderCallback(
                        &ShadowTreeHandler::setupAmbientModel);
                    pPart->addPostRenderCallback(
                        &ShadowTreeHandler::endAmbientModel);
                    
                    pPart->setRenderTarget(vShadowMaps[i].pFBO);

                    pPart->setDrawBuffer  (*buffers                      );

                    pPart->setWindow  (a->getWindow());

                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 mSize - 1,
                                                 mSize - 1,
                                                 
                                                 mSize,
                                                 mSize);


                    RenderFunctor f = 
                        boost::bind(&VarianceShadowMapHandler::genMipMapCB,
                                    this,
                                    _1,
                                    i);

                    pPart->addPreRenderCallback(f);

                    Matrix m, t;
                    
                    // set the projection
                    vLCams[i]->getProjection(
                        m, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    vLCams[i]->getProjectionTranslation(
                        t, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    vLCams[i]->getViewing(
                        m, 
                        pPart->getViewportWidth (),
                        pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (vLCams[i]->getNear());
                    pPart->setFar      (vLCams[i]->getFar ());
                    
                    pPart->calcFrustum();
                    
                    pPart->setBackground(_pClearSMapBack);
                    
                    Node *light  = vLights[i].first;
                    Node *parent = light->getParent();
                    
                    if(parent != NULL)
                    {
                        a->pushMatrix(parent->getToWorld());
                    }
                    
                    
                    a->overrideMaterial(_vDepthCmat[uiActiveLightCount], 
                                         a->getActNode());
                    _pStage->recurse(a, light);
                    a->overrideMaterial( NULL,       
                                         a->getActNode());
                    
                    if(parent != NULL)
                    {
                        a->popMatrix();
                    }
                }
                _pStage->popPartition(a);

                ++uiActiveLightCount;
            }
        }
    }

    //-------Restoring old states of Window and Viewport----------

    // enable all lights.
    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // restore old states.
        vLights[i].second->setOn(vLocalLightStates[i]);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
        {
            if(vExclActive[i])
            {
                exnode->setTravMask(TypeTraits<UInt32>::BitsSet);
            }
        }
    }
}
void VarianceShadowMapHandler::createShadowFactorMapFBO(
    RenderAction *a,
    DrawEnv      *pEnv,
    UInt32        num,
    UInt32        uiActiveLightCount)
{
    glClearColor(0.0, 0.0, 0.0, 1.0);

    //Finde alle aktiven Lichtquellen
    Real32  activeLights = 0;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();


    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i] != 0)
                activeLights++;
        }
    }
    else
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i]                              != 0 &&
               vLights     [i].second->getShadowIntensity() != 0.0)
            {
                activeLights++;
            }
        }
    }

    Real32  shadowIntensity;

    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        shadowIntensity = (_pStage->getGlobalShadowIntensity() /
                           activeLights);
    }
    else
    {
        shadowIntensity = 
            (vLights[num].second->getShadowIntensity() /
             activeLights);
    }

    if(vLights[num].second->getShadowIntensity() != 0.0 ||
       _pStage->getGlobalShadowIntensity() != 0.0)
    {

        Matrix  LVM, LPM, CVM;
        vLCams[num]->getViewing(LVM,
                                pEnv->getPixelWidth(),
                                pEnv->getPixelHeight());

        vLCams[num]->getProjection(LPM,
                                   pEnv->getPixelWidth(),
                                   pEnv->getPixelHeight());

        CVM = pEnv->getCameraViewing();

        Matrix  iCVM = CVM;
        iCVM.invert();

        Real32  texFactor;
        if(vLights[num].second->getType() == SpotLight ::getClassType() ||
           vLights[num].second->getType() == PointLight::getClassType())
        {
            texFactor = Real32(_width) / Real32(_height);
        }
        else
        {
            texFactor = 1.0;
        }

        Matrix  shadowMatrix = LPM;
        shadowMatrix.mult(LVM);
        shadowMatrix.mult(iCVM);

        Matrix  shadowMatrix2 = LVM;
        shadowMatrix2.mult(iCVM);


        Real32  xFactor = 1.0;
        Real32  yFactor = 1.0;

        Pnt3f   lPos;
        bool    isDirLight;
        Real32  sceneDiagLength;

        if(vLights[num].second->getType() == PointLight::getClassType())
        {
            PointLight *tmpPoint;

            tmpPoint = dynamic_cast<PointLight *>(
                vLights[num].second.get());

            lPos = tmpPoint->getPosition();

            if(tmpPoint->getBeacon() != NULL)
            {
                Matrix  m = tmpPoint->getBeacon()->getToWorld();
                m.mult(lPos, lPos);
            }

            isDirLight = false;
            Pnt3f           center;

            _pStageData->getLightRoot(num)->getVolume().getCenter(center);

            Vec3f           dir = lPos - center;
            Real32          dirLength = dir.length();

            Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
                                    ().getMax() - center);
            Real32          diffLength = diff.length();

            sceneDiagLength = dirLength + diffLength;
        }

        else if(vLights[num].second->getType() == SpotLight::getClassType())
        {
            SpotLight *tmpSpot;
            tmpSpot = dynamic_cast<SpotLight *>(
                vLights[num].second.get());

            lPos = tmpSpot->getPosition();

            if(tmpSpot->getBeacon() != NULL)
            {
                Matrix  m = tmpSpot->getBeacon()->getToWorld();
                m.mult(lPos, lPos);
            }

            isDirLight = false;
            Pnt3f           center;
            _pStageData->getLightRoot(num)->getVolume().getCenter(center);

            Vec3f           dir = lPos - center;
            Real32          dirLength = dir.length();

            Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
                                    ().getMax() - center);
            Real32          diffLength = diff.length();

            sceneDiagLength = dirLength + diffLength;
        }

        else
        {
            isDirLight = true;
            sceneDiagLength = 1.0;
        }


        Real32  lod;

        if(_pStage->getShadowSmoothness() <= 0.1999)
            lod = 0.5;
        else if(_pStage->getShadowSmoothness() <= 0.3999)
            lod = 1.5;
        else if(_pStage->getShadowSmoothness() <= 0.5999)
            lod = 2.5;
        else if(_pStage->getShadowSmoothness() <= 0.7999)
            lod = 3.5;
        else
            lod = 4.5;

        if(_vShadowCmat.size() == uiActiveLightCount)
        {
            _vShadowCmat.push_back(ChunkMaterial::createLocal());
        }
        
        OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());

        if(_vShadowSHLVar.size() == uiActiveLightCount)
        {
            _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());

#ifndef OSG_NEW_SHADER
            _vShadowSHLVar[uiActiveLightCount]->setSHLChunk(_shadowSHL);
#endif
        }
        
        OSG_ASSERT(uiActiveLightCount < _vShadowSHLVar.size());

        _shadowSHL->addUniformVariable("shadowMap",    0);
        _shadowSHL->addUniformVariable("oldFactorMap", 1);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "firstRun",
            (uiActiveLightCount == 0) ? Int32(1) : Int32(0));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "intensity", shadowIntensity);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "texFactor", texFactor);
        //_shadowSHL->addUniformVariable("shadowBias", 0.0075f);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM", shadowMatrix);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM2", shadowMatrix2);

        //_shadowSHL->addUniformVariable("shadowRange", Real32(shadowRange));
        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "xFactor", Real32(xFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "yFactor", Real32(yFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "sceneDiagLength", Real32(sceneDiagLength));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "Lod", Real32(lod));
        
        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "isDirLight", bool(isDirLight));


        ShadowStageData::ShadowMapStore &vShadowMaps = 
            _pStageData->getShadowMaps();

        _vShadowCmat[uiActiveLightCount]->clearChunks();

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowSHL);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _vShadowSHLVar[uiActiveLightCount]);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexO);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexE);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowFactorMapO);

        _pStage->pushPartition(a,
                               (RenderPartition::CopyWindow      |
                                RenderPartition::CopyViewing     |
                                RenderPartition::CopyProjection  |
                                RenderPartition::CopyFrustum     |
                                RenderPartition::CopyNearFar     |
                                RenderPartition::CopyViewportSize),
                               RenderPartition::StateSorting);
        {
            RenderPartition *pPart = a->getActivePartition();

            pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
            pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

            pPart->setRenderTarget(_pSceneFBO);
            pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT1_EXT);
            
            Node *light  = vLights[num].first;
            Node *parent = light->getParent();
            
            if(parent != NULL)
            {
                a->pushMatrix(parent->getToWorld());
            }

            if(uiActiveLightCount == 0)
            {
                pPart->setBackground(_pClearBackground);
            }
                             
            commitChanges();

            a->overrideMaterial(_vShadowCmat[uiActiveLightCount], 
                                 a->getActNode());
            _pStage->recurse(a, light);
            a->overrideMaterial( NULL,       
                                 a->getActNode());
            
            if(parent != NULL)
            {
                a->popMatrix();
            }
        }
        _pStage->popPartition(a);

        _firstRun = 0;
    }
}
예제 #4
0
void PCSSShadowMapHandler::createShadowMapsFBO(RenderAction *a,
                                               DrawEnv      *pEnv)
{
    // disable all lights more speed
    std::vector<bool> vLocalLightStates;

    const ShadowStageData::LightStore    &vLights      =
        _pStageData->getLights();

    const ShadowStageData::LStateStore   &vLightStates =
        _pStageData->getLightStates();

    const ShadowStageData::CamStore      &vLCams       =
        _pStageData->getLightCameras();

    const ShadowStageData::TravMaskStore &vExclTravMask =
        _pStageData->getExcludeNodeTravMask();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // store old states.
        vLocalLightStates.push_back(vLights[i].second->getOn());

        vLights[i].second->setOn(false);
    }

    // deactivate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
            exnode->setTravMask(0);
    }

    ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        if(vLightStates[i] != 0)
        {
            if(_pStage->getGlobalShadowIntensity() != 0.0 ||
               vLights[i].second->getShadowIntensity() != 0.0)
            {
                _pStage->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();

                    pPart->addPreRenderCallback(
                        &ShadowTreeHandler::setupAmbientModelAndMasks);
                    pPart->addPostRenderCallback(
                        &ShadowTreeHandler::endAmbientModelAndMasks);
                    
                    pPart->setRenderTarget(vShadowMaps[i].pFBO);
                    
                    pPart->setWindow  (a->getWindow());
                    
                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 _pStage->getMapSize()-1,
                                                 _pStage->getMapSize()-1,
                                                 
                                                 _pStage->getMapSize(),
                                                 _pStage->getMapSize() );
                    
                    
                    Matrix m, t;
                    
                    // set the projection
                    vLCams[i]->getProjection(
                        m, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    vLCams[i]->getProjectionTranslation(
                        t, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    vLCams[i]->getViewing(
                        m, 
                        pPart->getViewportWidth (),
                        pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (vLCams[i]->getNear());
                    pPart->setFar      (vLCams[i]->getFar ());
                    
                    pPart->calcFrustum();
                    
                    pPart->setBackground(_pClearSMapBack);
                    
                    Node *light  = vLights[i].first;
                    Node *parent = light->getParent();
                    
                    if(parent != NULL)
                    {
                        a->pushMatrix(parent->getToWorld());
                    }
                    
                    
                    a->overrideMaterial(_unlitMat, a->getActNode());
                    _pStage->recurse(a, light);
                    a->overrideMaterial( NULL,       a->getActNode());
                    
                    if(parent != NULL)
                    {
                        a->popMatrix();
                    }
                }
                _pStage->popPartition(a);
            }
        }
    }

    //-------Restoring old states of Window and Viewport----------
    // enable all lights.
    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // restore old states.
        vLights[i].second->setOn(vLocalLightStates[i]);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);
        if(exnode != NULL)
        {
            exnode->setTravMask(vExclTravMask[i]);
        }
    }
}
예제 #5
0
void PCSSShadowMapHandler::createShadowFactorMapFBO(
    RenderAction *a,
    DrawEnv      *pEnv,
    UInt32        num,
    UInt32        uiActiveLightCount)
{
    //Finde alle aktiven Lichtquellen

    Real32  activeLights = 0;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();


    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i] != 0)
                activeLights++;
        }
    }
    else
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i]                         != 0 &&
               vLights[i].second->getShadowIntensity() != 0.0)
            {
                activeLights++;
            }
        }
    }

    Real32  shadowIntensity;

    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        shadowIntensity = (_pStage->getGlobalShadowIntensity() /
                           activeLights);
    }
    else
    {
        shadowIntensity = 
            (vLights[num].second->getShadowIntensity() /
             activeLights);
    }

    if(vLights[num].second->getShadowIntensity() != 0.0 ||
       _pStage->getGlobalShadowIntensity()     != 0.0)
    {

        Matrix  LVM, LPM, CVM;

        vLCams[num]->getViewing(
            LVM,
            pEnv->getPixelWidth(),
            pEnv->getPixelHeight());

        vLCams[num]->getProjection(
            LPM,
            pEnv->getPixelWidth(),
            pEnv->getPixelHeight());

        CVM = pEnv->getCameraViewing();

        Matrix  iCVM = CVM;
        iCVM.invert();

        Real32  texFactor;

        if(vLights[num].second->getType() == SpotLight::getClassType () ||
           vLights[num].second->getType() == PointLight::getClassType()  )
        {
            texFactor = Real32(_width) / Real32(_height);
        }
        else
        {
            texFactor = 1.0;
        }

        Matrix  shadowMatrix = LPM;
        shadowMatrix.mult(LVM);
        shadowMatrix.mult(iCVM);

        Real32  xFactor = 1.0;
        Real32  yFactor = 1.0;

        Real32  lightSize;

        if(vLights[num].second->getType() != DirectionalLight::getClassType())
        {
            lightSize = _pStage->getShadowSmoothness() * 10.0;
        }
        else
        {
            lightSize = _pStage->getShadowSmoothness() / 25.0;
        }

        if(_vShadowCmat.size() == uiActiveLightCount)
        {
            _vShadowCmat.push_back(ChunkMaterial::createLocal());
        }
        
        OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());

        if(_vShadowSHLVar.size() == uiActiveLightCount)
        {
            _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());
        }

        _shadowSHL->addUniformVariable("shadowMap",    0);
        _shadowSHL->addUniformVariable("oldFactorMap", 1);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "firstRun", (uiActiveLightCount == 0) ? Int32(1) : Int32(0));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "intensity", shadowIntensity);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "texFactor", texFactor);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM", shadowMatrix);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "mapSize",
            Real32(_pStage->getMapSize()));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightSize", Real32(lightSize));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "xFactor", Real32(xFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "yFactor", Real32(yFactor));


        ShadowStageData::ShadowMapStore &vShadowMaps = 
            _pStageData->getShadowMaps();


        _vShadowCmat[uiActiveLightCount]->clearChunks();

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowSHL);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _vShadowSHLVar[uiActiveLightCount]);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexO);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexE);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowFactorMapO);

        _pStage->pushPartition(a,
                               (RenderPartition::CopyWindow      |
                                RenderPartition::CopyViewing     |
                                RenderPartition::CopyProjection  |
                                RenderPartition::CopyFrustum     |
                                RenderPartition::CopyNearFar     |
                                RenderPartition::CopyViewportSize),
                               RenderPartition::StateSorting);
        {
            RenderPartition *pPart = a->getActivePartition();

            pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
            pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

            pPart->setRenderTarget(_pShadowFactorFBO);
            pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT1_EXT);
            
            Node *light  = vLights[num].first;
            Node *parent = light->getParent();
            
            if(parent != NULL)
            {
                a->pushMatrix(parent->getToWorld());
            }

            if(uiActiveLightCount == 0)
            {
                pPart->setBackground(_pClearBackground);
            }
                           
            commitChanges();

            a->overrideMaterial(_vShadowCmat[uiActiveLightCount], 
                                 a->getActNode());
            _pStage->recurse(a, light);
            a->overrideMaterial( NULL,                    
                                 a->getActNode());
            
            if(parent != NULL)
            {
                a->popMatrix();
            }
        }
        _pStage->popPartition(a);

        _firstRun = 0;
    }
}
ActionBase::ResultE GroupingStage::renderEnter(Action *action)
{
    RenderAction *a = dynamic_cast<RenderAction *>(action);

    if(a == NULL)
        return ActionBase::Continue;

#if 0
    RenderPartition   *pParentPart = a   ->getActivePartition();
    FrameBufferObject *pTarget     = pParentPart->getRenderTarget();
#endif

    this->pushPartition(a, RenderPartition::CopyAll);

    RenderPartition   *pPart   = a->getActivePartition();

    Inherited::addCallbacks(pPart);

#if 0
    RenderPartition   *pParentPart = a   ->getActivePartition();
    FrameBufferObject *pTarget     = this->getRenderTarget();

    Background        *pBack   = this->getBackground();
    Viewport          *pPort   = a->getViewport();
    Window            *pWin    = a->getWindow  ();


    if(pTarget == NULL && this->getInheritedTarget() == true)
    {
        pTarget = pParentPart->getRenderTarget();
    }

    
    RenderPartition   *pPart   = a->getActivePartition();
    Camera            *pCam    = this->getCamera();
    
    pPart->setRenderTarget(pTarget);
    
//    pPart->setViewport(pPort);
    pPart->setWindow  (pWin );
    
    if(pTarget != NULL)
    {
        pPart->calcViewportDimension(this->getLeft  (),
                                     this->getBottom(),
                                     this->getRight (),
                                     this->getTop   (),
                                     
                                     pTarget->getWidth    (),
                                     pTarget->getHeight   ());
    }
    else if(pWin != NULL)
    {
        pPart->calcViewportDimension(this->getLeft  (),
                                     this->getBottom(),
                                     this->getRight (),
                                     this->getTop   (),
                                     
                                     pWin->getWidth   (),
                                     pWin->getHeight  ());
    }
    
    if(pCam != NULL)
    {
        Matrix m, t;
        
        // set the projection
        pCam->getProjection          (m, 
                                      pPart->getViewportWidth (), 
                                      pPart->getViewportHeight());
        
        pCam->getProjectionTranslation(t, 
                                       pPart->getViewportWidth (), 
                                       pPart->getViewportHeight());
        
        pPart->setupProjection(m, t);
        
        pCam->getViewing(m, 
                         pPart->getViewportWidth (),
                         pPart->getViewportHeight());
        
        
        pPart->setupViewing(m              );
        
        pPart->setNear     (pCam->getNear());
        pPart->setFar      (pCam->getFar ());
        
        pPart->calcFrustum (               );
        
    }
    
    this->fillPreRenderStore(vCallbackStore);

    GroupingStage::RenderFunctorStore::const_iterator cbIt  = 
        vCallbackStore.begin();

    GroupingStage::RenderFunctorStore::const_iterator cbEnd = 
        vCallbackStore.end  ();

    while(cbIt != cbEnd)
    {
        pPart->addPreRenderCallback(*cbIt);
        
        ++cbIt;
    }


    vCallbackStore.clear();

    this->fillPostRenderStore(vCallbackStore);

    cbIt  = vCallbackStore.begin();
    cbEnd = vCallbackStore.end  ();

    while(cbIt != cbEnd)
    {
        pPart->addPostRenderCallback(*cbIt);
        
        ++cbIt;
    }


    pPart->setBackground(pBack);
#endif

    return ActionBase::Continue;
}