ok, i've finally made it working. can someone review my changes and tell me if what i'm doing is correct or not ?
first modification is in OgreSceneManager.cpp, deriveShadowReceiverPass, i've changed the last lines to copy startlight and textureunitstate to the best technique pass found. i did it because without it next stage need those parameters and they are not updated otherwise, i guess there is a better place for this or a better way to do it:
Code: Select all
// handle the case where there is no fixed pipeline support
retPass->getParent()->getParent()->compile();
Technique* btech = retPass->getParent()->getParent()->getBestTechnique();
if( btech )
{
Pass* newPass = btech->getPass(0);
if (newPass != retPass) {
newPass->setStartLight(retPass->getStartLight());
newPass->removeAllTextureUnitStates();
Pass::TextureUnitStateIterator it = retPass->getTextureUnitStateIterator();
while (it.hasMoreElements()) {
TextureUnitState* tus = it.getNext();
TextureUnitState* newTus = newPass->createTextureUnitState( tus->getName() );
*newTus = *tus;
}
retPass = newPass;
}
}
next modification is in OgreSceneManager.cpp, renderModulativeTextureShadowedQueueGroupObjects, while iterating trough lights i set startlight, contenttype and texture unit texture name to the current light/shadowmap. i need to do that because later this will be used to set texture projection effect later regarding current light camera frustum and texture name:
Code: Select all
Pass* targetPass = mShadowTextureCustomReceiverPass ?
mShadowTextureCustomReceiverPass : mShadowReceiverPass;
targetPass->setStartLight( l->_getIndexInFrame() );
targetPass->getTextureUnitState(0)->setTextureName(
mCurrentShadowTexture->getName());
// Hook up projection frustum if fixed-function, but also need to
// disable it explicitly for program pipeline.
TextureUnitState* texUnit = targetPass->getTextureUnitState(0);
texUnit->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam);
// clamp to border colour in case this is a custom material
texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
texUnit->setTextureBorderColour(ColourValue::White);
texUnit->setContentType(TextureUnitState::CONTENT_SHADOW);
targetPass->getTextureUnitState(0)->setTextureName(
mCurrentShadowTexture->getName());
i set the texture name after setting the contenttype because using content_shadow remove the texture unit and the shadowmap is needed later.
then in OgreSceneManager.cpp, _setPass, i've changed how texture projection is set because it was checking if the pass has vertex program and the pass was not set correctly:
Code: Select all
- pTex->setProjectiveTexturing(!pass->hasVertexProgram(), cam);
+ pTex->setProjectiveTexturing(pTex->getEffects().end() != pTex->getEffects().find(TextureUnitState::ET_PROJECTIVE_TEXTURE), cam);
finally in OgreShaderFFPTexturing.cpp, updateGpuProgramsParams, i've changed the way mTextureViewProjImageMatrix is set because it was always using the same parameter instead of the one coming from AutoParamDataSource source:
Code: Select all
void FFPTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source,
const LightList* pLightList)
{
for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i)
{
TextureUnitParams* curParams = &mTextureUnitParamsList[i];
if (curParams->mTextureViewProjImageMatrix.get() != NULL)
{
Matrix4 matTexViewProjImage;
matTexViewProjImage = source->getTextureViewProjMatrix(0);
curParams->mTextureViewProjImageMatrix->setGpuParameter(matTexViewProjImage);
}
}
}
i think that this patch is very dirty because i don't really understand what's going on. i works, now i can see shadowmap for each light, but i think it's not a good solution, if someone who know how RTSS and texture shadows work, it could be very nice if he can spend time to evaluate my changes.