00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include "OSGPCSSShadowMapHandler.h"
00043 #include "OSGRenderAction.h"
00044 #include "OSGShadowStage.h"
00045 #include "OSGShadowStageData.h"
00046 #include "OSGSpotLight.h"
00047 #include "OSGDirectionalLight.h"
00048
00049 OSG_BEGIN_NAMESPACE
00050
00051 #include "ShaderCode/OSGPCSSShadowMapShaderCode.cinl"
00052
00053 PCSSShadowMapHandler::PCSSShadowMapHandler(ShadowStage *pSource,
00054 ShadowStageData *pData ) :
00055 Inherited (pSource,
00056 pData ),
00057 _pClearSMapBack(NULL ),
00058 _pPoly (NULL ),
00059 _shadowSHL (NULL ),
00060 _firstRun (1 )
00061 {
00062 _uiMode = ShadowStage::PCSS_SHADOW_MAP;
00063
00064
00065
00066
00067 _shadowSHL = SimpleSHLChunk::createLocal();
00068 _shadowSHL->setVertexProgram (_pcss_shadow_vp);
00069 _shadowSHL->setFragmentProgram(_pcss_shadow_fp);
00070
00071
00072 _pPoly = PolygonChunk::createLocal();
00073
00074 _unlitMat->addChunk(_pPoly);
00075
00076 _pClearSMapBack = SolidBackground::createLocal();
00077
00078 _pClearSMapBack->setColor(Color3f(1.f, 1.f, 1.f));
00079 }
00080
00081 PCSSShadowMapHandler::~PCSSShadowMapHandler(void)
00082 {
00083 _pClearSMapBack = NULL;
00084 _pPoly = NULL;
00085 _shadowSHL = NULL;
00086
00087 _vShadowCmat .clear();
00088 _vShadowSHLVar.clear();
00089
00090 }
00091
00092
00093 void PCSSShadowMapHandler::createShadowMapsFBO(RenderAction *a,
00094 DrawEnv *pEnv)
00095 {
00096
00097 std::vector<bool> vLocalLightStates;
00098
00099 const ShadowStageData::LightStore &vLights =
00100 _pStageData->getLights();
00101
00102 const ShadowStageData::LStateStore &vLightStates =
00103 _pStageData->getLightStates();
00104
00105 const ShadowStageData::CamStore &vLCams =
00106 _pStageData->getLightCameras();
00107
00108 const ShadowStageData::StatusStore &vExclActive =
00109 _pStageData->getExcludeNodeActive();
00110
00111 for(UInt32 i = 0;i < vLights.size();++i)
00112 {
00113
00114 vLocalLightStates.push_back(vLights[i].second->getOn());
00115
00116 vLights[i].second->setOn(false);
00117 }
00118
00119
00120 for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
00121 {
00122 Node *exnode = _pStage->getExcludeNodes(i);
00123
00124 if(exnode != NULL)
00125 exnode->setTravMask(0);
00126 }
00127
00128 ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00129
00130 for(UInt32 i = 0;i < vLights.size();++i)
00131 {
00132 if(vLightStates[i] != 0)
00133 {
00134 if(_pStage->getGlobalShadowIntensity() != 0.0 ||
00135 vLights[i].second->getShadowIntensity() != 0.0)
00136 {
00137 a->pushPartition();
00138 {
00139 RenderPartition *pPart = a->getActivePartition();
00140
00141 pPart->addPreRenderCallback(
00142 &ShadowTreeHandler::setupAmbientModelAndMasks);
00143 pPart->addPostRenderCallback(
00144 &ShadowTreeHandler::endAmbientModelAndMasks);
00145
00146 pPart->setRenderTarget(vShadowMaps[i].pFBO);
00147
00148 pPart->setWindow (a->getWindow());
00149
00150 pPart->calcViewportDimension(0.f,
00151 0.f,
00152 _pStage->getMapSize()-1,
00153 _pStage->getMapSize()-1,
00154
00155 _pStage->getMapSize(),
00156 _pStage->getMapSize() );
00157
00158
00159 Matrix m, t;
00160
00161
00162 vLCams[i]->getProjection(
00163 m,
00164 pPart->getViewportWidth (),
00165 pPart->getViewportHeight());
00166
00167 vLCams[i]->getProjectionTranslation(
00168 t,
00169 pPart->getViewportWidth (),
00170 pPart->getViewportHeight());
00171
00172 pPart->setupProjection(m, t);
00173
00174 vLCams[i]->getViewing(
00175 m,
00176 pPart->getViewportWidth (),
00177 pPart->getViewportHeight());
00178
00179
00180 pPart->setupViewing(m);
00181
00182 pPart->setNear (vLCams[i]->getNear());
00183 pPart->setFar (vLCams[i]->getFar ());
00184
00185 pPart->calcFrustum();
00186
00187 pPart->setBackground(_pClearSMapBack);
00188
00189 Node *light = vLights[i].first;
00190 Node *parent = light->getParent();
00191
00192 if(parent != NULL)
00193 {
00194 a->pushMatrix(parent->getToWorld());
00195 }
00196
00197
00198 a->overrideMaterial(_unlitMat, a->getActNode());
00199 _pStage->recurse(a, light);
00200 a->overrideMaterial( NULL, a->getActNode());
00201
00202 if(parent != NULL)
00203 {
00204 a->popMatrix();
00205 }
00206 }
00207 a->popPartition();
00208 }
00209 }
00210 }
00211
00212
00213
00214 for(UInt32 i = 0;i < vLights.size();++i)
00215 {
00216
00217 vLights[i].second->setOn(vLocalLightStates[i]);
00218 }
00219
00220
00221 for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
00222 {
00223 Node *exnode = _pStage->getExcludeNodes(i);
00224 if(exnode != NULL)
00225 {
00226 if(vExclActive[i])
00227 {
00228 exnode->setTravMask(TypeTraits<UInt32>::BitsSet);
00229 }
00230 }
00231 }
00232 }
00233
00234
00235 void PCSSShadowMapHandler::createColorMapFBO(RenderAction *a,
00236 DrawEnv *pEnv)
00237 {
00238 a->pushPartition((RenderPartition::CopyWindow |
00239 RenderPartition::CopyViewing |
00240 RenderPartition::CopyProjection |
00241 RenderPartition::CopyFrustum |
00242 RenderPartition::CopyNearFar |
00243 RenderPartition::CopyViewportSize),
00244 RenderPartition::StateSorting);
00245 {
00246 RenderPartition *pPart = a->getActivePartition();
00247
00248 pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
00249 pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel );
00250
00251 pPart->setRenderTarget(_pSceneFBO);
00252 pPart->setDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
00253
00254 Node *parent = a->getActNode()->getParent();
00255
00256 if(parent != NULL)
00257 {
00258 a->pushMatrix(parent->getToWorld());
00259 }
00260
00261 pPart->setBackground(a->getBackground());
00262
00263 _pStage->recurseFromThis(a);
00264
00265 if(parent != NULL)
00266 {
00267 a->popMatrix();
00268 }
00269 }
00270 a->popPartition();
00271
00272
00273 }
00274
00275 void PCSSShadowMapHandler::createShadowFactorMapFBO(
00276 RenderAction *a,
00277 DrawEnv *pEnv,
00278 UInt32 num,
00279 UInt32 uiActiveLightCount)
00280 {
00281
00282
00283 Real32 activeLights = 0;
00284
00285 const ShadowStageData::LightStore &vLights =
00286 _pStageData->getLights();
00287
00288 const ShadowStageData::LStateStore &vLightStates =
00289 _pStageData->getLightStates();
00290
00291 const ShadowStageData::CamStore &vLCams =
00292 _pStageData->getLightCameras();
00293
00294
00295 if(_pStage->getGlobalShadowIntensity() != 0.0)
00296 {
00297 for(UInt32 i = 0;i < vLights.size();i++)
00298 {
00299 if(vLightStates[i] != 0)
00300 activeLights++;
00301 }
00302 }
00303 else
00304 {
00305 for(UInt32 i = 0;i < vLights.size();i++)
00306 {
00307 if(vLightStates[i] != 0 &&
00308 vLights[i].second->getShadowIntensity() != 0.0)
00309 {
00310 activeLights++;
00311 }
00312 }
00313 }
00314
00315 Real32 shadowIntensity;
00316
00317 if(_pStage->getGlobalShadowIntensity() != 0.0)
00318 {
00319 shadowIntensity = (_pStage->getGlobalShadowIntensity() /
00320 activeLights);
00321 }
00322 else
00323 {
00324 shadowIntensity =
00325 (vLights[num].second->getShadowIntensity() /
00326 activeLights);
00327 }
00328
00329 if(vLights[num].second->getShadowIntensity() != 0.0 ||
00330 _pStage->getGlobalShadowIntensity() != 0.0)
00331 {
00332
00333 Matrix LVM, LPM, CVM;
00334
00335 vLCams[num]->getViewing(
00336 LVM,
00337 pEnv->getPixelWidth(),
00338 pEnv->getPixelHeight());
00339
00340 vLCams[num]->getProjection(
00341 LPM,
00342 pEnv->getPixelWidth(),
00343 pEnv->getPixelHeight());
00344
00345 CVM = pEnv->getCameraViewing();
00346
00347 Matrix iCVM = CVM;
00348 iCVM.invert();
00349
00350 Real32 texFactor;
00351
00352 if(vLights[num].second->getType() == SpotLight::getClassType () ||
00353 vLights[num].second->getType() == PointLight::getClassType() )
00354 {
00355 texFactor = Real32(_width) / Real32(_height);
00356 }
00357 else
00358 {
00359 texFactor = 1.0;
00360 }
00361
00362 Matrix shadowMatrix = LPM;
00363 shadowMatrix.mult(LVM);
00364 shadowMatrix.mult(iCVM);
00365
00366 Real32 xFactor = 1.0;
00367 Real32 yFactor = 1.0;
00368
00369 Real32 lightSize;
00370
00371 if(vLights[num].second->getType() != DirectionalLight::getClassType())
00372 {
00373 lightSize = _pStage->getShadowSmoothness() * 10.0;
00374 }
00375 else
00376 {
00377 lightSize = _pStage->getShadowSmoothness() / 25.0;
00378 }
00379
00380 if(_vShadowCmat.size() == uiActiveLightCount)
00381 {
00382 _vShadowCmat.push_back(ChunkMaterial::createLocal());
00383 }
00384
00385 OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());
00386
00387 if(_vShadowSHLVar.size() == uiActiveLightCount)
00388 {
00389 _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());
00390
00391 #ifndef OSG_NEW_SHADER
00392 _vShadowSHLVar[uiActiveLightCount]->setSHLChunk(_shadowSHL);
00393 #endif
00394 }
00395
00396 _shadowSHL->addUniformVariable("shadowMap", 0);
00397 _shadowSHL->addUniformVariable("oldFactorMap", 1);
00398
00399 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00400 "firstRun", (uiActiveLightCount == 0) ? Int32(1) : Int32(0));
00401
00402 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00403 "intensity", shadowIntensity);
00404
00405 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00406 "texFactor", texFactor);
00407
00408 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00409 "lightPM", shadowMatrix);
00410
00411 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00412 "mapSize",
00413 Real32(_pStage->getMapSize()));
00414
00415 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00416 "lightSize", Real32(lightSize));
00417
00418 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00419 "xFactor", Real32(xFactor));
00420
00421 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00422 "yFactor", Real32(yFactor));
00423
00424
00425 ShadowStageData::ShadowMapStore &vShadowMaps =
00426 _pStageData->getShadowMaps();
00427
00428
00429 _vShadowCmat[uiActiveLightCount]->clearChunks();
00430
00431 _vShadowCmat[uiActiveLightCount]->addChunk(
00432 _shadowSHL);
00433
00434 _vShadowCmat[uiActiveLightCount]->addChunk(
00435 _vShadowSHLVar[uiActiveLightCount]);
00436
00437 _vShadowCmat[uiActiveLightCount]->addChunk(
00438 vShadowMaps[num].pTexO);
00439
00440 _vShadowCmat[uiActiveLightCount]->addChunk(
00441 vShadowMaps[num].pTexE);
00442
00443 _vShadowCmat[uiActiveLightCount]->addChunk(
00444 _shadowFactorMapO);
00445
00446 a->pushPartition((RenderPartition::CopyWindow |
00447 RenderPartition::CopyViewing |
00448 RenderPartition::CopyProjection |
00449 RenderPartition::CopyFrustum |
00450 RenderPartition::CopyNearFar |
00451 RenderPartition::CopyViewportSize),
00452 RenderPartition::StateSorting);
00453 {
00454 RenderPartition *pPart = a->getActivePartition();
00455
00456 pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
00457 pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel );
00458
00459 pPart->setRenderTarget(_pSceneFBO);
00460 pPart->setDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
00461
00462 Node *light = vLights[num].first;
00463 Node *parent = light->getParent();
00464
00465 if(parent != NULL)
00466 {
00467 a->pushMatrix(parent->getToWorld());
00468 }
00469
00470 if(uiActiveLightCount == 0)
00471 {
00472 pPart->setBackground(_pClearBackground);
00473 }
00474
00475 commitChanges();
00476
00477 a->overrideMaterial(_vShadowCmat[uiActiveLightCount],
00478 a->getActNode());
00479 _pStage->recurse(a, light);
00480 a->overrideMaterial( NULL,
00481 a->getActNode());
00482
00483 if(parent != NULL)
00484 {
00485 a->popMatrix();
00486 }
00487 }
00488 a->popPartition();
00489
00490 _firstRun = 0;
00491 }
00492 }
00493
00494 void PCSSShadowMapHandler::configureShadowMaps(void)
00495 {
00496 ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00497
00498 const ShadowStageData::LightStore &vLights = _pStageData->getLights();
00499
00500
00501 UInt32 uiSHMSize = vShadowMaps.size();
00502 UInt32 uiMapSize = _pStage-> getMapSize ();
00503
00504 for(UInt32 i = 0; i < uiSHMSize; ++i)
00505 {
00506 vShadowMaps[i].pTexO->setCompareMode(GL_NONE );
00507 vShadowMaps[i].pTexO->setCompareFunc(GL_LEQUAL );
00508 vShadowMaps[i].pTexO->setDepthMode (GL_LUMINANCE);
00509
00510 vShadowMaps[i].pTexO->setMinFilter (GL_NEAREST );
00511 vShadowMaps[i].pTexO->setMagFilter (GL_NEAREST );
00512
00513 if(vShadowMaps[i].uiType ==
00514 ShadowStageData::ShadowMapElem::ColorShadowMap)
00515 {
00516 vShadowMaps[i].pTexO->setInternalFormat(GL_DEPTH_COMPONENT);
00517 vShadowMaps[i].pTexO->setExternalFormat(GL_DEPTH_COMPONENT);
00518
00519 if(vLights[i].second->getType() != PointLight::getClassType())
00520 {
00521 vShadowMaps[i].pTexO->setWrapS(GL_CLAMP_TO_EDGE);
00522 vShadowMaps[i].pTexO->setWrapT(GL_CLAMP_TO_EDGE);
00523 }
00524 else
00525 {
00526 vShadowMaps[i].pTexO->setWrapS(GL_CLAMP_TO_BORDER);
00527 vShadowMaps[i].pTexO->setWrapT(GL_CLAMP_TO_BORDER);
00528 }
00529
00530 vShadowMaps[i].pTexO->setAnisotropy(1.0);
00531
00532 vShadowMaps[i].pImage->set(Image::OSG_L_PF,
00533 uiMapSize, uiMapSize, 1,
00534 1, 1, 0.f,
00535 NULL,
00536 Image::OSG_UINT8_IMAGEDATA,
00537 false);
00538
00539 vShadowMaps[i].pFBO->setDepthAttachment(
00540 vShadowMaps[i].pFBO->getColorAttachments(0));
00541
00542 vShadowMaps[i].pFBO->setColorAttachment(NULL, 0);
00543
00544 vShadowMaps[i].uiType =
00545 ShadowStageData::ShadowMapElem::DepthShadowMap;
00546 }
00547 }
00548
00549 _bShadowMapsConfigured = true;
00550 }
00551
00552 void PCSSShadowMapHandler::render(RenderAction *a,
00553 DrawEnv *pEnv)
00554 {
00555 const ShadowStageData::LightStore &vLights =
00556 _pStageData->getLights();
00557
00558 const ShadowStageData::NodeStore &vTransparents =
00559 _pStageData->getTransparents();
00560
00561 const ShadowStageData::LStateStore &vLightStates =
00562 _pStageData->getLightStates();
00563
00564 #ifndef SHADOW_CHECK
00565 if(_bShadowMapsConfigured == false)
00566 _pStageData->getShadowMaps().clear();
00567 #endif
00568
00569 if(_pStageData->getShadowMaps().size() != vLights.size())
00570 {
00571 initShadowMaps();
00572 }
00573
00574 if(_bShadowMapsConfigured == false)
00575 {
00576 configureShadowMaps();
00577 }
00578
00579 if(_uiMapSize != _pStage->getMapSize())
00580 {
00581 updateShadowMapSize();
00582 }
00583
00584 if(_pSceneFBO == NULL)
00585 initSceneFBO(pEnv, false);
00586
00587 if(_width != pEnv->getPixelWidth () ||
00588 _height != pEnv->getPixelHeight() )
00589 {
00590 updateSceneFBOSize(pEnv, false);
00591 }
00592
00593 commitChanges();
00594
00595 _firstRun = 1;
00596
00597 if(_pStage->getMapAutoUpdate() == true ||
00598 _pStage->_trigger_update == true )
00599 {
00600 _pPoly->setOffsetFill (true );
00601 _pPoly->setOffsetFactor(_pStage->getOffFactor());
00602 _pPoly->setOffsetBias (_pStage->getOffBias ());
00603
00604 createColorMapFBO(a, pEnv);
00605
00606
00607
00608 for(UInt32 t = 0;t < vTransparents.size();++t)
00609 {
00610 vTransparents[t]->setTravMask(0);
00611 }
00612
00613
00614 createShadowMapsFBO(a, pEnv);
00615
00616
00617
00618 for(UInt32 t = 0;t < vTransparents.size();++t)
00619 {
00620 vTransparents[t]->setTravMask(TypeTraits<UInt32>::BitsSet);
00621 }
00622
00623
00624 UInt32 uiActiveLightCount = 0;
00625
00626 for(UInt32 i = 0;i < vLights.size();i++)
00627 {
00628 if(vLightStates[i] != 0)
00629 {
00630 if(_pStage->getGlobalShadowIntensity() != 0.0 ||
00631 vLights[i].second->getShadowIntensity() != 0.0)
00632 {
00633 createShadowFactorMapFBO(a,
00634 pEnv,
00635 i,
00636 uiActiveLightCount);
00637
00638 ++uiActiveLightCount;
00639 }
00640 }
00641 }
00642
00643 _pStage->_trigger_update = false;
00644 }
00645
00646 setupDrawCombineMap1(a);
00647 }
00648
00649 OSG_END_NAMESPACE