pass on the multiple target results

The changes to pass on the results for each target to the children of that posteffect
This commit is contained in:
marauder2k7 2026-04-19 17:36:54 +01:00
parent 60e659aedc
commit d33edb051c
5 changed files with 43 additions and 35 deletions

View file

@ -551,7 +551,7 @@ void ProjectedShadow::_renderToTexture( F32 camDist, const TSRenderState &rdata
} }
if ( smShadowFilter ) if ( smShadowFilter )
smShadowFilter->process( NULL, mShadowTexture ); smShadowFilter->process( NULL, &mShadowTexture );
} }
// Restore frustum // Restore frustum

View file

@ -1169,7 +1169,10 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
} }
} }
void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI *inTexViewport ) void PostEffect::_setupTexture(U32 stage,
GFXTexHandle* inputTex,
U32 inputTexCount,
const RectI* inTexViewport)
{ {
const String &texFilename = mTextureAsset[stage].notNull() ? mTextureAsset[stage]->getImageFile() : ""; const String &texFilename = mTextureAsset[stage].notNull() ? mTextureAsset[stage]->getImageFile() : "";
@ -1178,17 +1181,17 @@ void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI *
RectI viewport = GFX->getViewport(); RectI viewport = GFX->getViewport();
if ( _inTexSlotFromName(texFilename) >= 0 ) S32 inSlot = _inTexSlotFromName(texFilename);
if (inSlot >= 0)
{ {
theTex = inputTex; if ((U32)inSlot < inputTexCount)
{
theTex = inputTex[inSlot];
if ( inTexViewport ) if (inSlot == 0 && inTexViewport)
{ viewport = *inTexViewport;
viewport = *inTexViewport; else if (theTex)
} viewport.set(0, 0, theTex->getWidth(), theTex->getHeight());
else if ( theTex )
{
viewport.set( 0, 0, theTex->getWidth(), theTex->getHeight() );
} }
} }
else if ( texFilename.compare( "$backBuffer", 0, String::NoCase ) == 0 ) else if ( texFilename.compare( "$backBuffer", 0, String::NoCase ) == 0 )
@ -1432,9 +1435,10 @@ void PostEffect::_cleanTargets( bool recurse )
} }
} }
void PostEffect::process( const SceneRenderState *state, void PostEffect::process( const SceneRenderState* state,
GFXTexHandle& inOutTex, GFXTexHandle* inOutTex,
const RectI *inTexViewport ) U32 inOutTexCount,
const RectI* inTexViewport)
{ {
// If the shader is forced to be skipped... then skip. // If the shader is forced to be skipped... then skip.
if ( mSkip ) if ( mSkip )
@ -1470,11 +1474,16 @@ void PostEffect::process( const SceneRenderState *state,
} }
GFXTransformSaver saver; GFXTransformSaver saver;
GFXTexHandle chain[NumMRTTargets];
U32 texCount = getMin(inOutTexCount, (U32)NumMRTTargets);
for (U32 c = 0; c < texCount; c++)
chain[c] = inOutTex[c];
// Set the textures. // Set the textures.
for (U32 i = 0; i < NumTextures; i++) for (U32 i = 0; i < NumTextures; i++)
{ {
if (mTextureType[i] == NormalTextureType) if (mTextureType[i] == NormalTextureType)
_setupTexture(i, inOutTex, inTexViewport); _setupTexture(i, chain, texCount, inTexViewport);
else if (mTextureType[i] == CubemapType) else if (mTextureType[i] == CubemapType)
_setupCubemapTexture(i, mCubemapTextures[i]); _setupCubemapTexture(i, mCubemapTextures[i]);
else if (mTextureType[i] == CubemapArrayType) else if (mTextureType[i] == CubemapArrayType)
@ -1490,12 +1499,13 @@ void PostEffect::process( const SceneRenderState *state,
const bool hasDepth = mTargetDepthStencil.isValid(); const bool hasDepth = mTargetDepthStencil.isValid();
bool hasColorTarget = false; bool hasColorTarget = false;
U32 curTargetCount = 0;
for (U32 c = 0; c < NumMRTTargets; c++) for (U32 c = 0; c < NumMRTTargets; c++)
{ {
if (mTargetTex[c].isValid()) if (mTargetTex[c].isValid())
{ {
hasColorTarget = true; hasColorTarget = true;
break; curTargetCount++;
} }
} }
@ -1621,9 +1631,11 @@ void PostEffect::process( const SceneRenderState *state,
PFXMGR->releaseBackBufferTex(); PFXMGR->releaseBackBufferTex();
} }
inOutTex = mTargetTex[0];
for (U32 c = 0; c < NumMRTTargets; c++) for (U32 c = 0; c < NumMRTTargets; c++)
{ {
if (c < texCount)
chain[c] = mTargetTex[c];
if (!mNamedTarget[c].isRegistered()) if (!mNamedTarget[c].isRegistered())
mTargetTex[c] = NULL; mTargetTex[c] = NULL;
} }
@ -1632,12 +1644,13 @@ void PostEffect::process( const SceneRenderState *state,
// are processed as it screws up the viewport. // are processed as it screws up the viewport.
saver.restore(); saver.restore();
const U32 nextTexCount = getMax(getMax(texCount, curTargetCount), 1u);
// Now process my children. // Now process my children.
iterator i = begin(); iterator i = begin();
for ( ; i != end(); i++ ) for ( ; i != end(); i++ )
{ {
PostEffect *effect = static_cast<PostEffect*>(*i); PostEffect *effect = static_cast<PostEffect*>(*i);
effect->process( state, inOutTex ); effect->process( state, chain, nextTexCount);
} }
if ( mOneFrameOnly ) if ( mOneFrameOnly )
@ -2048,19 +2061,13 @@ void PostEffect::clearShaderMacros()
mUpdateShader = true; mUpdateShader = true;
} }
GFXTextureObject* PostEffect::_getTargetTexture( U32 index) GFXTextureObject* PostEffect::_getTargetTexture(U32 index)
{ {
// A TexGen PostEffect will generate its texture now if it if (mRenderTime == PFXTexGenOnDemand
// has not already. && (!mTargetTex[index] || mUpdateShader))
if ( mRenderTime == PFXTexGenOnDemand &&
( !mTargetTex[index] || mUpdateShader ) )
{ {
GFXTexHandle chainTex; GFXTexHandle chainTex[NumMRTTargets]; // zero-initialised by GFXTexHandle ctor
process( NULL, chainTex ); process(NULL, chainTex, NumMRTTargets);
// TODO: We should add a conditional copy
// to a non-RT texture here to reduce the
// amount of non-swappable RTs in use.
} }
return mTargetTex[index].getPointer(); return mTargetTex[index].getPointer();

View file

@ -280,7 +280,7 @@ protected:
virtual void _setupConstants(const SceneRenderState* state); virtual void _setupConstants(const SceneRenderState* state);
virtual void _setupTransforms(); virtual void _setupTransforms();
virtual void _setupTarget(const SceneRenderState* state, bool* outClearTarget); virtual void _setupTarget(const SceneRenderState* state, bool* outClearTarget);
virtual void _setupTexture(U32 slot, GFXTexHandle& inputTex, const RectI* inTexViewport); virtual void _setupTexture(U32 stage, GFXTexHandle* inputTex, U32 inputTexCount, const RectI* inTexViewport);
virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle& inputTex); virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle& inputTex);
virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle& inputTex); virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle& inputTex);
@ -345,7 +345,8 @@ public:
DECLARE_CALLBACK(void, onDisabled, ()); DECLARE_CALLBACK(void, onDisabled, ());
virtual void process(const SceneRenderState* state, virtual void process(const SceneRenderState* state,
GFXTexHandle& inOutTex, GFXTexHandle* inOutTex,
U32 inOutTexCount = 1,
const RectI* inTexViewport = NULL); const RectI* inTexViewport = NULL);
void reload(); void reload();

View file

@ -284,14 +284,14 @@ void PostEffectManager::renderEffects( const SceneRenderState *state,
// This is used to pass the output texture // This is used to pass the output texture
// of one effect into the next effect. // of one effect into the next effect.
GFXTexHandle chainTex; GFXTexHandle chainTex[PostEffect::NumMRTTargets];
// Process the effects. // Process the effects.
for ( U32 i = 0; i < effects->size(); i++ ) for ( U32 i = 0; i < effects->size(); i++ )
{ {
PostEffect *effect = (*effects)[i]; PostEffect *effect = (*effects)[i];
AssertFatal( effect != NULL, "Somehow this happened" ); AssertFatal( effect != NULL, "Somehow this happened" );
effect->process( state, chainTex ); effect->process(state, chainTex, PostEffect::NumMRTTargets);
} }
} }

View file

@ -144,7 +144,7 @@ void RenderFormatToken::process(SceneRenderState *state, RenderPassStateBin *cal
// Run the PostEffect which copies data into the new target. // Run the PostEffect which copies data into the new target.
if ( mCopyPostEffect.isValid() ) if ( mCopyPostEffect.isValid() )
mCopyPostEffect->process( state, curBackBuffer, &mTarget.getViewport() ); mCopyPostEffect->process( state, &curBackBuffer,1, &mTarget.getViewport() );
} }
break; break;
@ -174,7 +174,7 @@ void RenderFormatToken::process(SceneRenderState *state, RenderPassStateBin *cal
{ {
// Need to create a texhandle here, since inOutTex gets assigned during process() // Need to create a texhandle here, since inOutTex gets assigned during process()
GFXTexHandle inOutTex = mTargetColorTexture[mTargetChainIdx]; GFXTexHandle inOutTex = mTargetColorTexture[mTargetChainIdx];
mResolvePostEffect->process( state, inOutTex, &mTarget.getViewport() ); mResolvePostEffect->process( state, &inOutTex, 1, &mTarget.getViewport() );
} }
} }
break; break;