From 15673810c6f65b7ecff8cc85b54fb7e56312fe5b Mon Sep 17 00:00:00 2001 From: DavidWyand-GG Date: Thu, 24 Oct 2013 13:40:44 -0400 Subject: [PATCH] Expand PostFX Viewport Options - Added an option for a postFX to get its viewport from a named texture in slot 0, if there is one. This allows the postFX to operate when the named input texture's viewport is different than the current viewport. - Modified the SSAO postFX to use the new PFXTargetViewport_NamedInTexture0 option to more closely link SSAO with the prepass buffer. - Modifed the GFX method setActiveRenderTarget() with a new parameter that indicates if the current viewport should be modified with the new rendering target. This defaults to true to maintain its previous behaviour. The postFX rendering pipeline sets this to false as it now handles its own viewport setup, and removes an unnecessary GFX->setViewport() call. --- Engine/source/gfx/gfxDevice.cpp | 7 ++- Engine/source/gfx/gfxDevice.h | 2 +- Engine/source/postFx/postEffect.cpp | 51 ++++++++++++++++--- Engine/source/postFx/postEffectCommon.h | 4 ++ .../game/core/scripts/client/postFx/ssao.cs | 2 +- .../game/core/scripts/client/postFx/ssao.cs | 2 +- 6 files changed, 56 insertions(+), 12 deletions(-) diff --git a/Engine/source/gfx/gfxDevice.cpp b/Engine/source/gfx/gfxDevice.cpp index 9e57bcc81..f4ac1902b 100644 --- a/Engine/source/gfx/gfxDevice.cpp +++ b/Engine/source/gfx/gfxDevice.cpp @@ -849,7 +849,7 @@ void GFXDevice::popActiveRenderTarget() mRTStack.pop_back(); } -void GFXDevice::setActiveRenderTarget( GFXTarget *target ) +void GFXDevice::setActiveRenderTarget( GFXTarget *target, bool updateViewport ) { AssertFatal( target, "GFXDevice::setActiveRenderTarget - must specify a render target!" ); @@ -878,7 +878,10 @@ void GFXDevice::setActiveRenderTarget( GFXTarget *target ) // We should consider removing this and making it the // responsibility of the caller to set a proper viewport // when the target is changed. - setViewport( RectI( Point2I::Zero, mCurrentRT->getSize() ) ); + if ( updateViewport ) + { + setViewport( RectI( Point2I::Zero, mCurrentRT->getSize() ) ); + } } /// Helper class for GFXDevice::describeResources. diff --git a/Engine/source/gfx/gfxDevice.h b/Engine/source/gfx/gfxDevice.h index e153d02c5..874466665 100644 --- a/Engine/source/gfx/gfxDevice.h +++ b/Engine/source/gfx/gfxDevice.h @@ -695,7 +695,7 @@ public: void popActiveRenderTarget(); /// Assign a new active render target. - void setActiveRenderTarget( GFXTarget *target ); + void setActiveRenderTarget( GFXTarget *target, bool updateViewport=true ); /// Returns the current active render target. inline GFXTarget* getActiveRenderTarget() { return mCurrentRT; } diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index ff83997eb..04089338e 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -118,6 +118,7 @@ ImplementEnumType( PFXTargetViewport, "@ingroup Rendering\n\n") { PFXTargetViewport_TargetSize, "PFXTargetViewport_TargetSize", "Set viewport to match target size (default).\n" }, { PFXTargetViewport_GFXViewport, "PFXTargetViewport_GFXViewport", "Use the current GFX viewport (scaled to match target size).\n" }, + { PFXTargetViewport_NamedInTexture0, "PFXTargetViewport_NamedInTexture0", "Use the input texture 0 if it is named (scaled to match target size), otherwise revert to PFXTargetViewport_TargetSize if there is none.\n" }, EndImplementEnumType; @@ -947,7 +948,17 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg const Point2I &oldTargetSize = oldTarget->getSize(); Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); - const RectI viewport = GFX->getViewport(); + const RectI &viewport = GFX->getViewport(); + + mNamedTarget.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); + } + else if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture()) + { + // Scale the named input texture's viewport to match our target + const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize(); + Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y)); + + const RectI &viewport = mActiveNamedTarget[0]->getViewport(); mNamedTarget.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); } @@ -1009,7 +1020,17 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg const Point2I &oldTargetSize = oldTarget->getSize(); Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); - const RectI viewport = GFX->getViewport(); + const RectI &viewport = GFX->getViewport(); + + mNamedTargetDepthStencil.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); + } + else if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture()) + { + // Scale the named input texture's viewport to match our target + const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize(); + Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y)); + + const RectI &viewport = mActiveNamedTarget[0]->getViewport(); mNamedTargetDepthStencil.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); } @@ -1093,8 +1114,6 @@ void PostEffect::process( const SceneRenderState *state, bool clearTarget = false; _setupTarget( state, &clearTarget ); - RectI oldViewport = GFX->getViewport(); - if ( mTargetTex || mTargetDepthStencil ) { @@ -1110,6 +1129,7 @@ void PostEffect::process( const SceneRenderState *state, GFX->getActiveRenderTarget()->preserve(); #endif + const RectI &oldViewport = GFX->getViewport(); GFXTarget *oldTarget = GFX->getActiveRenderTarget(); GFX->pushActiveRenderTarget(); @@ -1121,21 +1141,38 @@ void PostEffect::process( const SceneRenderState *state, else mTarget->attachTexture( GFXTextureTarget::DepthStencil, mTargetDepthStencil ); - GFX->setActiveRenderTarget( mTarget ); + // Set the render target but not its viewport. We'll do that below. + GFX->setActiveRenderTarget( mTarget, false ); - // The setActiveRenderTarget() called above will change the viewport to cover the - // entire target area. Restore the viewport as necessary. if(mNamedTarget.isRegistered()) { + // Always use the name target's viewport, if available. It was set up in _setupTarget(). GFX->setViewport(mNamedTarget.getViewport()); } else if(mTargetViewport == PFXTargetViewport_GFXViewport) { + // Go with the current viewport as scaled against our render target. const Point2I &oldTargetSize = oldTarget->getSize(); const Point2I &targetSize = mTarget->getSize(); Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); GFX->setViewport( RectI( oldViewport.point.x*scale.x, oldViewport.point.y*scale.y, oldViewport.extent.x*scale.x, oldViewport.extent.y*scale.y ) ); } + else if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture()) + { + // Go with the first input texture, if it is named. Scale the named input texture's viewport to match our target + const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize(); + const Point2I &targetSize = mTarget->getSize(); + Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y)); + + const RectI &viewport = mActiveNamedTarget[0]->getViewport(); + + GFX->setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); + } + else + { + // Default to using the whole target as the viewport + GFX->setViewport( RectI( Point2I::Zero, mTarget->getSize() ) ); + } } if ( clearTarget ) diff --git a/Engine/source/postFx/postEffectCommon.h b/Engine/source/postFx/postEffectCommon.h index fecef5a52..00bd2d4d4 100644 --- a/Engine/source/postFx/postEffectCommon.h +++ b/Engine/source/postFx/postEffectCommon.h @@ -77,6 +77,10 @@ enum PFXTargetViewport /// Use the current GFX viewport PFXTargetViewport_GFXViewport, + + /// Use the input texture 0 if it is named, otherwise + /// revert to PFXTargetViewport_TargetSize if there is none + PFXTargetViewport_NamedInTexture0, }; DefineEnumType( PFXTargetViewport ); diff --git a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs index 8b54ce870..cd5bfc598 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs @@ -190,7 +190,7 @@ singleton PostEffect( SSAOPostFx ) target = "$outTex"; targetScale = "0.5 0.5"; - targetViewport = "PFXTargetViewport_GFXViewport"; + targetViewport = "PFXTargetViewport_NamedInTexture0"; singleton PostEffect() { diff --git a/Templates/Full/game/core/scripts/client/postFx/ssao.cs b/Templates/Full/game/core/scripts/client/postFx/ssao.cs index 8b54ce870..cd5bfc598 100644 --- a/Templates/Full/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Full/game/core/scripts/client/postFx/ssao.cs @@ -190,7 +190,7 @@ singleton PostEffect( SSAOPostFx ) target = "$outTex"; targetScale = "0.5 0.5"; - targetViewport = "PFXTargetViewport_GFXViewport"; + targetViewport = "PFXTargetViewport_NamedInTexture0"; singleton PostEffect() {