I've been trying to get PSSM shadows work correctly sice few weeks ago and I can't manage to get any good results.
Code: Select all
void ShadowManager::processPSSM()
{
gEnv->sceneManager->setShadowFarDistance(2048);
gEnv->sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
gEnv->sceneManager->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, PSSM_Shadows.ShadowsTextureNum);
if (PSSM_Shadows.mPSSMSetup.isNull())
{
// shadow camera setup
Ogre::PSSMShadowCameraSetup* pssmSetup = new Ogre::PSSMShadowCameraSetup();
pssmSetup->setSplitPadding(5);
pssmSetup->setCameraLightDirectionThreshold(Ogre::Degree(5));
pssmSetup->setUseAggressiveFocusRegion(true);
pssmSetup->setUseSimpleOptimalAdjust(false);
//pssmSetup->calculateSplitPoints(3, gEnv->mainCamera->getNearClipDistance(), gEnv->mainCamera->getFarClipDistance());
pssmSetup->setOptimalAdjustFactor(0, 2);
pssmSetup->setOptimalAdjustFactor(1, 1);
pssmSetup->setOptimalAdjustFactor(2, 0.5);
PSSM_Shadows.mPSSMSetup.bind(pssmSetup);
}
gEnv->sceneManager->setShadowCameraSetup(PSSM_Shadows.mPSSMSetup);
gEnv->sceneManager->setShadowTextureCount(PSSM_Shadows.ShadowsTextureNum);
gEnv->sceneManager->setShadowTextureConfig(0, 2048, 2048, PF_FLOAT16_RGB);
gEnv->sceneManager->setShadowTextureConfig(1, 1024, 1024, PF_FLOAT16_RGB);
gEnv->sceneManager->setShadowTextureConfig(2, 512, 512, PF_FLOAT16_RGB);
gEnv->sceneManager->setShadowTextureSelfShadow(true);
gEnv->sceneManager->setShadowCasterRenderBackFaces(true);
gEnv->sceneManager->setShadowTextureCasterMaterial(PSSM_Shadows.mDepthShadows ? "PSSM/shadow_caster" : Ogre::StringUtil::BLANK);
updatePSSM();
}
void ShadowManager::updatePSSM(Ogre::Terrain* terrain)
{
if (!PSSM_Shadows.mPSSMSetup.get()) return;
Ogre::TerrainMaterialGeneratorA::SM2Profile *matProfile = 0;
if (Ogre::TerrainGlobalOptions::getSingletonPtr())
{
matProfile = static_cast<Ogre::TerrainMaterialGeneratorA::SM2Profile*>(Ogre::TerrainGlobalOptions::getSingleton().getDefaultMaterialGenerator()->getActiveProfile());
matProfile->setReceiveDynamicShadowsEnabled(true);
matProfile->setReceiveDynamicShadowsLowLod(true);
matProfile->setGlobalColourMapEnabled(true);
}
Ogre::PSSMShadowCameraSetup* pssmSetup = static_cast<Ogre::PSSMShadowCameraSetup*>(PSSM_Shadows.mPSSMSetup.get());
Ogre::PSSMShadowCameraSetup::SplitPointList splitPointList = pssmSetup->getSplitPoints();
splitPointList[0] = 1.0;
splitPointList[1] = 94.0;
splitPointList[2] = 250.0;
splitPointList[3] = 512.0;
pssmSetup->setSplitPoints(splitPointList);
Ogre::Vector4 splitPoints;
for (int i = 0; i < PSSM_Shadows.ShadowsTextureNum; ++i)
splitPoints[i] = splitPointList[i];
MaterialPtr mat = MaterialManager::getSingleton().getByName("RoR/Managed_Mats/Base");
mat->getTechnique("ShadowTechnique")->getPass(0)->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints);
// TODO: fix this
/* setMaterialSplitPoints("road", splitPoints);
setMaterialSplitPoints("road2", splitPoints);
*/
if (matProfile && terrain)
{
matProfile->generateForCompositeMap(terrain);
matProfile->setReceiveDynamicShadowsDepth(PSSM_Shadows.mDepthShadows);
matProfile->setReceiveDynamicShadowsPSSM(static_cast<Ogre::PSSMShadowCameraSetup*>(PSSM_Shadows.mPSSMSetup.get()));
}
}
Also, it seems like there is a problem with the.. uhm bias? Shadows are rendered over the side where the light is hitting?
Thanks for your help.