Пример #1
0
void App::UpdPSSMMaterials()	/// . . . . . . . . 
{
	if (pSet->shadow_type == 0)  return;
	if (!mPSSMSetup.get())  return;
	
	//--  pssm params
	PSSMShadowCameraSetup* pssmSetup = static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get());
	const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssmSetup->getSplitPoints();

	for (size_t i = 0; i < splitPointList.size(); ++i)
		splitPoints[i] = splitPointList[i];

	// mtr splits for all cars (only game)
	#ifndef ROAD_EDITOR
	//if (pSet->shadow_type == 3) 
	{
		recreateCarMtr();
	}
	#endif
	
	for (std::vector<std::string>::iterator it = materialFactory->splitMtrs.begin();
		it != materialFactory->splitMtrs.end(); ++it)
	{
		//LogO("Set splits: " + (*it) );
		setMtrSplits( (*it) );
	}
}
Пример #2
0
	void COgreManager::ApplyShadowParams()
	{
		EnableShadow(m_effectCfg.bShadow);
		m_pSceneMgr->setShadowFarDistance(Ogre::StringConverter::parseReal(m_shadowParams["FarDistance"]));
		m_pSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3);
		m_pSceneMgr->setShadowDirectionalLightExtrusionDistance(Ogre::StringConverter::parseReal(m_shadowParams["LightExtrusionDistance"]));
		m_pSceneMgr->setShadowTextureCount(3);
		FLOAT3 texSize = Ogre::StringConverter::parseVector3(m_shadowParams["ShadowMapSize"]);
		m_pSceneMgr->setShadowTextureConfig(0, texSize.x, texSize.x, PF_FLOAT32_R);
		m_pSceneMgr->setShadowTextureConfig(1, texSize.y, texSize.y, PF_FLOAT32_R);
		m_pSceneMgr->setShadowTextureConfig(2, texSize.z, texSize.z, PF_FLOAT32_R);
		m_pSceneMgr->setShadowTextureSelfShadow(Ogre::StringConverter::parseBool(m_shadowParams["SelfShadow"]));
		m_pSceneMgr->setShadowCasterRenderBackFaces(Ogre::StringConverter::parseBool(m_shadowParams["RenderBackFace"]));
		m_pSceneMgr->setShadowTextureCasterMaterial("Ogre/shadow/depth/caster");

		PSSMShadowCameraSetup* cam = GetShadowCameraSetup();

		cam->setSplitPadding(Ogre::StringConverter::parseBool(m_shadowParams["SplitPadding"]));
		cam->calculateSplitPoints(3, m_pMainCamera->getNearClipDistance(), m_pSceneMgr->getShadowFarDistance(), 
			Ogre::StringConverter::parseReal(m_shadowParams["PssmLambda"]));
		FLOAT3 adjust = Ogre::StringConverter::parseVector3(m_shadowParams["AdjustFactor"]);
		cam->setOptimalAdjustFactor(0, adjust.x);
		cam->setOptimalAdjustFactor(1, adjust.y);
		cam->setOptimalAdjustFactor(2, adjust.z);
		cam->setUseSimpleOptimalAdjust(Ogre::StringConverter::parseBool(m_shadowParams["UseSimpleAdjust"]));
		cam->setCameraLightDirectionThreshold(Degree(Ogre::StringConverter::parseReal(m_shadowParams["CameraLightDirectionThreshold"])));
	}
Пример #3
0
void App::UpdPSSMMaterials()	/// . . . . . . . . 
{
	if (pSet->shadow_type == 0)  return;
	if (!mPSSMSetup.get())  return;
	
	//--  pssm params
	PSSMShadowCameraSetup* pssmSetup = static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get());
	const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssmSetup->getSplitPoints();

	for (size_t i = 0; i < splitPointList.size(); ++i)
		splitPoints[i] = splitPointList[i];

	// mtr splits for all cars (only game)
	#ifndef ROAD_EDITOR
	//if (pSet->shadow_type == 3) 
	{
		recreateCarMtr();
	}
	#endif
}
  void configureShadows( bool enabled, bool depthShadows )
  {
    TerrainMaterialGeneratorA::SM2Profile* matProfile =
      static_cast<TerrainMaterialGeneratorA::SM2Profile*>(mTerrainGlobals->getDefaultMaterialGenerator()->getActiveProfile());
    matProfile->setReceiveDynamicShadowsEnabled( enabled );
#ifdef SHADOWS_IN_LOW_LOD_MATERIAL
    matProfile->setReceiveDynamicShadowsLowLod( true );
#else
    matProfile->setReceiveDynamicShadowsLowLod( false );
#endif
    // Default materials
    for( EntityList::iterator i = mHouseList.begin(); i != mHouseList.end(); ++i )
    {
      (*i)->setMaterialName( "Examples/TudorHouse" );
    }
    if( enabled )
    {// General scene setup
      mSceneMgr->setShadowTechnique( SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED );
      mSceneMgr->setShadowFarDistance( 3000 );

      // 3 textures per directional light (PSSM)
      mSceneMgr->setShadowTextureCountPerLightType( Ogre::Light::LT_DIRECTIONAL, 3 );
      if( mPSSMSetup.isNull() )
      {// shadow camera setup
        PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup();
        pssmSetup->setSplitPadding( mCamera->getNearClipDistance() );
        pssmSetup->calculateSplitPoints( 3, mCamera->getNearClipDistance(), mSceneMgr->getShadowFarDistance() );
        pssmSetup->setOptimalAdjustFactor( 0, 2 );
        pssmSetup->setOptimalAdjustFactor( 1, 1 );
        pssmSetup->setOptimalAdjustFactor( 2, 0.5 );

        mPSSMSetup.bind( pssmSetup );
      }
      mSceneMgr->setShadowCameraSetup( mPSSMSetup );
      if( depthShadows )
      {
        mSceneMgr->setShadowTextureCount( 3 );
        mSceneMgr->setShadowTextureConfig( 0, 2048, 2048, PF_FLOAT32_R );
        mSceneMgr->setShadowTextureConfig( 1, 1024, 1024, PF_FLOAT32_R );
        mSceneMgr->setShadowTextureConfig( 2, 1024, 1024, PF_FLOAT32_R );
        mSceneMgr->setShadowTextureSelfShadow( true );
        mSceneMgr->setShadowCasterRenderBackFaces( true );

        MaterialPtr houseMat = buildDepthShadowMaterial( "fw12b.jpg" );
        for( EntityList::iterator i = mHouseList.begin(); i != mHouseList.end(); ++i )
        {
          (*i)->setMaterial( houseMat );
        }
      }
      else
      {
        mSceneMgr->setShadowTextureCount( 3 );
        mSceneMgr->setShadowTextureConfig( 0, 2048, 2048, PF_X8B8G8R8 );
        mSceneMgr->setShadowTextureConfig( 1, 1024, 1024, PF_X8B8G8R8 );
        mSceneMgr->setShadowTextureConfig( 2, 1024, 1024, PF_X8B8G8R8 );
        mSceneMgr->setShadowTextureSelfShadow( false );
        mSceneMgr->setShadowCasterRenderBackFaces( false );
        mSceneMgr->setShadowTextureCasterMaterial( StringUtil::BLANK );
      }
      matProfile->setReceiveDynamicShadowsDepth( depthShadows );
      matProfile->setReceiveDynamicShadowsPSSM( static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get()) );
      //addTextureShadowDebugOverlay(TL_RIGHT, 3);
    }
    else
    {
      mSceneMgr->setShadowTechnique( SHADOWTYPE_NONE );
    }
  }
	//---------------------------------------------------------------------
	void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultFpParams(
		const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog)
	{
		GpuProgramParametersSharedPtr params = prog->getDefaultParameters();
		params->setIgnoreMissingParams(true);

		params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
		params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0);
		params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0);
		params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0);
		params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
		params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);

		if (prof->isShadowingEnabled(tt, terrain))
		{
			uint numTextures = 1;
			if (prof->getReceiveDynamicShadowsPSSM())
			{
				PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM();
				numTextures = (uint)pssm->getSplitCount();
				Vector4 splitPoints;
				const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints();
				// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
				for (uint i = 1; i < numTextures; ++i)
				{
					splitPoints[i-1] = splitPointList[i];
				}
				params->setNamedConstant("pssmSplitPoints", splitPoints);
			}

			if (prof->getReceiveDynamicShadowsDepth())
			{
				size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo;
				for (uint i = 0; i < numTextures; ++i)
				{
					params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i), 
						GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset);
				}
			}
		}

        // Explicitly bind samplers for GLSL
        if ((prof->_getShaderLanguage() == "glsl") || (prof->_getShaderLanguage() == "glsles"))
        {
            int numSamplers = 0;
            if (tt == LOW_LOD)
            {
                params->setNamedConstant("compositeMap", (int)numSamplers++);
            }
            else
            {
                params->setNamedConstant("globalNormal", (int)numSamplers++);

                if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled())
                {
                    params->setNamedConstant("globalColourMap", (int)numSamplers++);
                }
                if (prof->isLightmapEnabled())
                {
                    params->setNamedConstant("lightMap", (int)numSamplers++);
                }

                uint maxLayers = prof->getMaxLayers(terrain);
                uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
                uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
                // Blend textures - sampler definitions
                for (uint i = 0; i < numBlendTextures; ++i)
                {
                    params->setNamedConstant("blendTex" + StringConverter::toString(i), (int)numSamplers++);
                }

                // Layer textures - sampler definitions & UV multipliers
                for (uint i = 0; i < numLayers; ++i)
                {
                    params->setNamedConstant("difftex" + StringConverter::toString(i), (int)numSamplers++);
                    params->setNamedConstant("normtex" + StringConverter::toString(i), (int)numSamplers++);
                }

                uint numShadowTextures = 1;
                if (prof->getReceiveDynamicShadowsPSSM())
                    numShadowTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount();

                for (uint i = 0; i < numShadowTextures; ++i)
                {
                    if (prof->isShadowingEnabled(tt, terrain))
                        params->setNamedConstant("shadowMap" + StringConverter::toString(i), (int)numSamplers++);
                }
            }
        }
	}
Пример #6
0
///  Shadows config
//---------------------------------------------------------------------------------------------------
void App::changeShadows()
{	
	QTimer ti;  ti.update();  /// time
	
	//  get settings
	bool enabled = pSet->shadow_type != 0;
	bool bDepth = pSet->shadow_type >= 2;
	bool bSoft = pSet->shadow_type == 3;
	
	pSet->shadow_size = std::max(0,std::min(ciShadowNumSizes-1, pSet->shadow_size));
	int fTex = /*2048*/ ciShadowSizesA[pSet->shadow_size], fTex2 = fTex/2;
	int num = /*3*/ pSet->shadow_count;
		
	// disable 4 shadow textures (does not work because no texcoord's left in shader)
	if (num == 4) num = 3;

	TerrainMaterialGeneratorB::SM2Profile* matProfile = 0;
	
	if (mTerrainGlobals)
	{
		matProfile = (TerrainMaterialGeneratorB::SM2Profile*) mTerrainGlobals->getDefaultMaterialGenerator()->getActiveProfile();
		if (matProfile)
		{	matProfile->setReceiveDynamicShadowsEnabled(enabled);
			matProfile->setReceiveDynamicShadowsLowLod(true);
			matProfile->setGlobalColourMapEnabled(false);

			matProfile->setLayerSpecularMappingEnabled(pSet->ter_mtr >= 1);  // ter mtr
			matProfile->setLayerNormalMappingEnabled(  pSet->ter_mtr >= 2);
			matProfile->setLayerParallaxMappingEnabled(pSet->ter_mtr >= 3);
	}	}
	

	if (!enabled)  {
		mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);  /*return;*/ }

	else
	{
		// General scene setup
		//mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
		mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
		mSceneMgr->setShadowFarDistance(pSet->shadow_dist);  // 3000
		mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, num);

		if (mPSSMSetup.isNull())
		{
			// shadow camera setup
			PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup();
			#ifndef ROAD_EDITOR
			pssmSetup->setSplitPadding(mSplitMgr->mCameras.front()->getNearClipDistance());
			//pssmSetup->setSplitPadding(10);
			pssmSetup->calculateSplitPoints(num, mSplitMgr->mCameras.front()->getNearClipDistance(), mSceneMgr->getShadowFarDistance());
			#else
			pssmSetup->setSplitPadding(mCamera->getNearClipDistance());
			//pssmSetup->setSplitPadding(10);
			pssmSetup->calculateSplitPoints(num, mCamera->getNearClipDistance(), mSceneMgr->getShadowFarDistance());
			#endif
			for (int i=0; i < num; ++i)
			{	//int size = i==0 ? fTex : fTex2;
				const Real cAdjfA[5] = {2, 1, 0.5, 0.25, 0.125};
				pssmSetup->setOptimalAdjustFactor(i, cAdjfA[std::min(i, 4)]);
			}
			materialFactory->setPSSMCameraSetup(pssmSetup);
			mPSSMSetup.bind(pssmSetup);
		}
		mSceneMgr->setShadowCameraSetup(mPSSMSetup);

		mSceneMgr->setShadowTextureCount(num);
		for (int i=0; i < num; ++i)
		{	int size = i==0 ? fTex : fTex2;
		
			PixelFormat pf;
			if (bDepth && !bSoft) pf = PF_FLOAT32_R;
			else if (bSoft) pf = PF_FLOAT16_RGB;
			else pf = PF_X8B8G8R8;
			
			mSceneMgr->setShadowTextureConfig(i, size, size, pf);
		}
		
		mSceneMgr->setShadowTextureSelfShadow(bDepth ? true : false);  //-?
		mSceneMgr->setShadowCasterRenderBackFaces((bDepth && !bSoft) ? true : false);
		
		String shadowCasterMat;
		if (bDepth && !bSoft) shadowCasterMat = "PSSM/shadow_caster";
		else if (bSoft) shadowCasterMat = "PSVSM/shadow_caster";
		else shadowCasterMat = StringUtil::BLANK;
		
		mSceneMgr->setShadowTextureCasterMaterial(shadowCasterMat);

		if (matProfile && terrain)  {
			matProfile->setReceiveDynamicShadowsDepth(bDepth);
			matProfile->setReceiveDynamicShadowsPSSM(static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get()));
			MaterialPtr mtr = matProfile->generateForCompositeMap(terrain);
			//LogO(mtr->getBestTechnique()->getPass(0)->getTextureUnitState(0)->getName());
			//LogO(String("Ter mtr: ") + mtr->getName());

		}
	}
	
	materialFactory->setTerrain(terrain);
	materialFactory->setNumShadowTex(num);
	materialFactory->setShadows(pSet->shadow_type != 0);
	materialFactory->setShadowsDepth(bDepth);
	materialFactory->setShadowsSoft(bSoft);
	materialFactory->generate();
	
	#if 0	// shadow tex overlay
	// add the overlay elements to show the shadow maps:
	// init overlay elements
	OverlayManager& mgr = OverlayManager::getSingleton();
	Overlay* overlay;
	
	// destroy if already exists
	if (overlay = mgr.getByName("DebugOverlay"))
		mgr.destroy(overlay);
		
	overlay = mgr.create("DebugOverlay");
	
	TexturePtr tex;
	for (size_t i = 0; i < 2; ++i) {
		//TexturePtr tex = mSceneMgr->getShadowTexture(i);
		if (i == 0) tex = TextureManager::getSingleton().getByName("PlaneReflection"); 
		else tex = TextureManager::getSingleton().getByName("PlaneRefraction"); 
		
		// Set up a debug panel to display the shadow
		
		if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i)))
			MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i));
		MaterialPtr debugMat = MaterialManager::getSingleton().create(
			"Ogre/DebugTexture" + toStr(i), 
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
			
		debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
		TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
		t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

		OverlayContainer* debugPanel;
		
		// destroy container if exists
		try
		{
			if (debugPanel = 
				static_cast<OverlayContainer*>(
					mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i)
				)))
				mgr.destroyOverlayElement(debugPanel);
		}
		catch (Ogre::Exception&) {}
		
		debugPanel = (OverlayContainer*)
			(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
		debugPanel->_setPosition(0.8, i*0.25);
		debugPanel->_setDimensions(0.2, 0.24);
		debugPanel->setMaterialName(debugMat->getName());
		debugPanel->show();
		overlay->add2D(debugPanel);
		overlay->show();
	}
	#endif
	
	// -------------------   update the paged-geom materials
	
	// grass is not cloned, just need to set new shader parameters
	if (grass)
	{
		GrassLoader *grassLoader = static_cast<GrassLoader*>(grass->getPageLoader());
		for (std::list<GrassLayer*>::iterator it= grassLoader->getLayerList().begin();
			it != grassLoader->getLayerList().end(); ++it)
		{
			GrassLayer* layer = (*it);
			layer->applyShader();
		}
	}
	
	// trees are more complicated since they are cloned
	//!todo this doesn't work (tree material does not update immediately)
	if(trees)
	{
		trees->reloadGeometry();
		std::vector<ResourcePtr> reosurceToDelete;
		ResourceManager::ResourceMapIterator it = MaterialManager::getSingleton().getResourceIterator();
		while (it.hasMoreElements())
		{
			ResourcePtr material = it.getNext();
			String materialName = material->getName();
			std::string::size_type pos =materialName.find("BatchMat|");
			if( pos != std::string::npos ) {
				reosurceToDelete.push_back(material);
			}
		}
		for(int i=0;i<reosurceToDelete.size();i++)
		{
			MaterialManager::getSingleton().remove(reosurceToDelete[i]);
		}
	}
	UpdPSSMMaterials();

	ti.update();	/// time
	float dt = ti.dt * 1000.f;
	LogO(String("::: Time Shadows: ") + toStr(dt) + " ms");
}
Пример #7
0
///  Shadows config
//---------------------------------------------------------------------------------------------------
void CScene::changeShadows()
{	
	Ogre::Timer ti;
	
	//  get settings
	SETTINGS* pSet = app->pSet;
	bool enabled = pSet->shadow_type != Sh_None;
	bool bDepth = pSet->shadow_type >= Sh_Depth;
	bool bSoft = pSet->shadow_type == Sh_Soft;
	
	pSet->shadow_size = std::max(0,std::min(ciShadowSizesNum-1, pSet->shadow_size));
	int fTex = ciShadowSizesA[pSet->shadow_size], fTex2 = fTex/2;
	int num = pSet->shadow_count;

	sh::Vector4* fade = new sh::Vector4(
		pSet->shadow_dist,
		pSet->shadow_dist * 0.6, // fade start
		0, 0);

	sh::Factory* mFactory = app->mFactory;
	SceneManager* mSceneMgr = app->mSceneMgr;

	if (terrain)
		mFactory->setTextureAlias("TerrainLightMap", terrain->getLightmap()->getName());

		
	// disable 4 shadow textures (does not work because no texcoord's left in shader)
	if (num == 4)  num = 3;


	if (!enabled)
		mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
	else
	{
		// General scene setup
		//mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
		mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
		mSceneMgr->setShadowFarDistance(pSet->shadow_dist);  // 3000
		mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, num);

		if (num == 1)  // 1 tex, fast
		{
			ShadowCameraSetupPtr mShadowCameraSetup = ShadowCameraSetupPtr(new LiSPSMShadowCameraSetup());
			mSceneMgr->setShadowCameraSetup(mShadowCameraSetup);
		}else
		{	if (mPSSMSetup.isNull())  // pssm
			{
				PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup();
				#ifndef SR_EDITOR
				pssmSetup->setSplitPadding(app->mSplitMgr->mCameras.front()->getNearClipDistance());
				pssmSetup->calculateSplitPoints(num, app->mSplitMgr->mCameras.front()->getNearClipDistance(), mSceneMgr->getShadowFarDistance());
				#else
				pssmSetup->setSplitPadding(app->mCamera->getNearClipDistance());
				pssmSetup->calculateSplitPoints(num, app->mCamera->getNearClipDistance(), app->mSceneMgr->getShadowFarDistance());
				#endif
				for (int i=0; i < num; ++i)
				{	//int size = i==0 ? fTex : fTex2;
					const Real cAdjfA[5] = {2, 1, 0.5, 0.25, 0.125};
					pssmSetup->setOptimalAdjustFactor(i, cAdjfA[std::min(i, 4)]);
				}
				mPSSMSetup.bind(pssmSetup);
			}
			mSceneMgr->setShadowCameraSetup(mPSSMSetup);
		}

		mSceneMgr->setShadowTextureCount(num);
		for (int i=0; i < num; ++i)
		{	int size = i==0 ? fTex : fTex2;
		
			PixelFormat pf;
			if (bDepth && !bSoft) pf = PF_FLOAT32_R;
			else if (bSoft) pf = PF_FLOAT16_RGB;
			else pf = PF_X8B8G8R8;
			
			mSceneMgr->setShadowTextureConfig(i, size, size, pf);
		}
		
		mSceneMgr->setShadowTextureSelfShadow(bDepth ? true : false);  //-?
		mSceneMgr->setShadowCasterRenderBackFaces((bDepth && !bSoft) ? true : false);

		mSceneMgr->setShadowTextureCasterMaterial(bDepth ? "shadowcaster_default" : "");
	}

	mSceneMgr->setShadowColour(Ogre::ColourValue(0,0,0,1));


#if 0  /// TEST overlays
	//  add overlay elements to show shadow or terrain maps
	OverlayManager& mgr = OverlayManager::getSingleton();
	Overlay* overlay = mgr.getByName("DebugOverlay");
	if (overlay)
		mgr.destroy(overlay);
	overlay = mgr.create("DebugOverlay");
	TexturePtr tex;

	#if 0  /// shadow
	for (int i = 0; i < pSet->shadow_count; ++i)
	{	
		TexturePtr tex = mSceneMgr->getShadowTexture(i);
	#else  /// terrain
	for (int i = 0; i < 2/*pSet->shadow_count*/; ++i)
	{	
		TexturePtr tex = !terrain ? mSceneMgr->getShadowTexture(i) :
			i==0 ? terrain->getCompositeMap() : terrain->getLightmap();
	#endif
		// Set up a debug panel to display the shadow
		if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i)))
			MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i));
		MaterialPtr debugMat = MaterialManager::getSingleton().create(
			"Ogre/DebugTexture" + toStr(i), rgDef);
			
		debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
		TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
		t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

		OverlayContainer* debugPanel;
		
		// destroy container if exists
		try
		{
			if (debugPanel = static_cast<OverlayContainer*>(mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i))))
				mgr.destroyOverlayElement(debugPanel);
		}
		catch (Ogre::Exception&) {}
		
		debugPanel = (OverlayContainer*)
			(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
		debugPanel->_setPosition(0.8, i*0.31);  //aspect.. 0.25 0.24
		debugPanel->_setDimensions(0.2, 0.3);
		debugPanel->setMaterialName(debugMat->getName());
		debugPanel->show();
		overlay->add2D(debugPanel);
		overlay->show();
	}
#endif
	
	UpdPSSMMaterials();


	//  rebuild static geom after materials change
	if (vdrTrack)
	{
		vdrTrack->destroy();
		vdrTrack->build();
	}

	LogO(String("::: Time Shadows: ") + fToStr(ti.getMilliseconds(),0,3) + " ms");
}


/// . . . . . . . . 
void CScene::UpdPSSMMaterials()
{
	if (app->pSet->shadow_type == Sh_None)  return;
	
	if (app->pSet->shadow_count == 1)  // 1 tex
	{
		float dist = app->pSet->shadow_dist;
		sh::Vector3* splits = new sh::Vector3(dist, 0,0);  //dist*2, dist*3);
		sh::Factory::getInstance().setSharedParameter("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splits));
		return;
	}
	
	if (!mPSSMSetup.get())  return;
	
	//--  pssm params
	PSSMShadowCameraSetup* pssmSetup = static_cast<PSSMShadowCameraSetup*>(mPSSMSetup.get());
	const PSSMShadowCameraSetup::SplitPointList& sp = pssmSetup->getSplitPoints();
	const int last = sp.size()-1;

	sh::Vector3* splits = new sh::Vector3(
		sp[std::min(1,last)], sp[std::min(2,last)], sp[std::min(3,last)] );

	sh::Factory::getInstance().setSharedParameter("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splits));
}