Browse Source

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.
DavidWyand-GG 11 years ago
parent
commit
15673810c6

+ 5 - 2
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.

+ 1 - 1
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; }

+ 44 - 7
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 )

+ 4 - 0
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 );

+ 1 - 1
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()
    {

+ 1 - 1
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()
    {