Bläddra i källkod

Turbulence respects side-by-side rendering

- PostEffect class now offers the current projection offset and target
viewport as shader constants.
- Turbulence postFX now takes the current projection offset into
account.
- Turbulence postFX now clamps itself to the current viewport.
- Turbulence postFX now renders after the glow bin, specifically after
the glow postFX renders.  This ensures that it can take advantage of
knowing the current viewport rather than affecting the entire render
target.
DavidWyand-GG 12 år sedan
förälder
incheckning
2077632a92

+ 28 - 0
Engine/source/postFx/postEffect.cpp

@@ -256,6 +256,7 @@ PostEffect::PostEffect()
       mRTSizeSC( NULL ),
       mOneOverRTSizeSC( NULL ),
       mViewportOffsetSC( NULL ),
+      mTargetViewportSC( NULL ),
       mFogDataSC( NULL ),
       mFogColorSC( NULL ),
       mEyePosSC( NULL ),
@@ -265,6 +266,7 @@ PostEffect::PostEffect()
       mNearFarSC( NULL ),
       mInvNearFarSC( NULL ),
       mWorldToScreenScaleSC( NULL ),
+      mProjectionOffsetSC( NULL ),
       mWaterColorSC( NULL ),
       mWaterFogDataSC( NULL ),
       mAmbientColorSC( NULL ),
@@ -541,6 +543,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
 
       //mViewportSC = shader->getShaderConstHandle( "$viewport" );
 
+      mTargetViewportSC = mShader->getShaderConstHandle( "$targetViewport" );
+
       mFogDataSC = mShader->getShaderConstHandle( ShaderGenVars::fogData );
       mFogColorSC = mShader->getShaderConstHandle( ShaderGenVars::fogColor );
 
@@ -554,6 +558,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mMatScreenToWorldSC = mShader->getShaderConstHandle( "$matScreenToWorld" );
       mMatPrevScreenToWorldSC = mShader->getShaderConstHandle( "$matPrevScreenToWorld" );
 
+      mProjectionOffsetSC = mShader->getShaderConstHandle( "$projectionOffset" );
+
       mWaterColorSC = mShader->getShaderConstHandle( "$waterColor" );
       mAmbientColorSC = mShader->getShaderConstHandle( "$ambientColor" );
       mWaterFogDataSC = mShader->getShaderConstHandle( "$waterFogData" );
@@ -621,6 +627,27 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mShaderConsts->set( mRenderTargetParamsSC[i], rtParams );
    }
 
+   // Target viewport (in target space)
+   if ( mTargetViewportSC->isValid() )
+   {
+      const Point2I& targetSize = GFX->getActiveRenderTarget()->getSize();
+      Point3I size(targetSize.x, targetSize.y, 0);
+      const RectI& viewport = GFX->getViewport();
+
+      Point2F offset((F32)viewport.point.x / (F32)targetSize.x, (F32)viewport.point.y / (F32)targetSize.y );
+      Point2F scale((F32)viewport.extent.x / (F32)targetSize.x, (F32)viewport.extent.y / (F32)targetSize.y );
+
+      const Point2F halfPixel( 0.5f / targetSize.x, 0.5f / targetSize.y );
+
+      Point4F targetParams;
+      targetParams.x = offset.x + halfPixel.x;
+      targetParams.y = offset.y + halfPixel.y;
+      targetParams.z = offset.x + scale.x - halfPixel.x;
+      targetParams.w = offset.y + scale.y - halfPixel.y;
+
+      mShaderConsts->set( mTargetViewportSC, targetParams );
+   }
+
    // Set the fog data.
    if ( mFogDataSC->isValid() )
    {
@@ -692,6 +719,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mShaderConsts->setSafe( mNearFarSC, Point2F( state->getNearPlane(), state->getFarPlane() ) );
       mShaderConsts->setSafe( mInvNearFarSC, Point2F( 1.0f / state->getNearPlane(), 1.0f / state->getFarPlane() ) );
       mShaderConsts->setSafe( mWorldToScreenScaleSC, state->getWorldToScreenScale() );
+      mShaderConsts->setSafe( mProjectionOffsetSC, state->getFrustum().getProjectionOffset() );
       mShaderConsts->setSafe( mFogColorSC, state->getSceneManager()->getFogData().color );
 
       if ( mWaterColorSC->isValid() )

+ 3 - 0
Engine/source/postFx/postEffect.h

@@ -118,6 +118,8 @@ protected:
 
    GFXShaderConstHandle *mViewportOffsetSC;
 
+   GFXShaderConstHandle *mTargetViewportSC;
+
    GFXShaderConstHandle *mFogDataSC;
    GFXShaderConstHandle *mFogColorSC;
    GFXShaderConstHandle *mEyePosSC;
@@ -127,6 +129,7 @@ protected:
    GFXShaderConstHandle *mNearFarSC;
    GFXShaderConstHandle *mInvNearFarSC;   
    GFXShaderConstHandle *mWorldToScreenScaleSC;
+   GFXShaderConstHandle *mProjectionOffsetSC;
    GFXShaderConstHandle *mWaterColorSC;
    GFXShaderConstHandle *mWaterFogDataSC;     
    GFXShaderConstHandle *mAmbientColorSC;

+ 3 - 3
Templates/Empty/game/core/scripts/client/postFx/turbulence.cs

@@ -35,7 +35,6 @@ singleton ShaderData( PFX_TurbulenceShader )
    DXVertexShaderFile 	= "shaders/common/postFx/postFxV.hlsl";
    DXPixelShaderFile 	= "shaders/common/postFx/turbulenceP.hlsl";
            
-   samplerNames[0] = "$inputTex";            
    pixVersion = 3.0;
 };
 
@@ -45,8 +44,9 @@ singleton PostEffect( TurbulenceFx )
    isEnabled = false;    
    allowReflectPass = true;  
          
-   renderTime = "PFXAfterDiffuse";  
-   renderBin = "ObjTranslucentBin";     
+   renderTime = "PFXAfterBin";
+   renderBin = "GlowBin";
+   renderPriority = 10; // Render after the glows themselves
      
    shader = PFX_TurbulenceShader;  
    stateBlock=PFX_TurbulenceStateBlock;

+ 9 - 2
Templates/Empty/game/shaders/common/postFx/turbulenceP.hlsl

@@ -23,13 +23,20 @@
 #include "./postFx.hlsl"
 
 uniform float  accumTime;
+uniform float2 projectionOffset;
+uniform float4 targetViewport;
 
 float4 main( PFXVertToPix IN, uniform sampler2D inputTex : register(S0) ) : COLOR
 {
 	float speed = 2.0;
 	float distortion = 6.0;
 	
-	float y = IN.uv0.y + (cos(IN.uv0.y * distortion + accumTime * speed) * 0.01);
-    float x = IN.uv0.x + (sin(IN.uv0.x * distortion + accumTime * speed) * 0.01);
+	float y = IN.uv0.y + (cos((IN.uv0.y+projectionOffset.y) * distortion + accumTime * speed) * 0.01);
+   float x = IN.uv0.x + (sin((IN.uv0.x+projectionOffset.x) * distortion + accumTime * speed) * 0.01);
+
+   // Clamp the calculated uv values to be within the target's viewport
+	y = clamp(y, targetViewport.y, targetViewport.w);
+	x = clamp(x, targetViewport.x, targetViewport.z);
+	
     return tex2D (inputTex, float2(x, y));
 }

+ 3 - 3
Templates/Full/game/core/scripts/client/postFx/turbulence.cs

@@ -35,7 +35,6 @@ singleton ShaderData( PFX_TurbulenceShader )
    DXVertexShaderFile 	= "shaders/common/postFx/postFxV.hlsl";
    DXPixelShaderFile 	= "shaders/common/postFx/turbulenceP.hlsl";
            
-   samplerNames[0] = "$inputTex";   
    pixVersion = 3.0;
 };
 
@@ -45,8 +44,9 @@ singleton PostEffect( TurbulenceFx )
    isEnabled = false;    
    allowReflectPass = true;  
          
-   renderTime = "PFXAfterDiffuse";  
-   renderBin = "ObjTranslucentBin";     
+   renderTime = "PFXAfterBin";
+   renderBin = "GlowBin";
+   renderPriority = 10; // Render after the glows themselves
      
    shader = PFX_TurbulenceShader;  
    stateBlock=PFX_TurbulenceStateBlock;

+ 9 - 2
Templates/Full/game/shaders/common/postFx/turbulenceP.hlsl

@@ -23,13 +23,20 @@
 #include "./postFx.hlsl"
 
 uniform float  accumTime;
+uniform float2 projectionOffset;
+uniform float4 targetViewport;
 
 float4 main( PFXVertToPix IN, uniform sampler2D inputTex : register(S0) ) : COLOR
 {
 	float speed = 2.0;
 	float distortion = 6.0;
 	
-	float y = IN.uv0.y + (cos(IN.uv0.y * distortion + accumTime * speed) * 0.01);
-    float x = IN.uv0.x + (sin(IN.uv0.x * distortion + accumTime * speed) * 0.01);
+	float y = IN.uv0.y + (cos((IN.uv0.y+projectionOffset.y) * distortion + accumTime * speed) * 0.01);
+   float x = IN.uv0.x + (sin((IN.uv0.x+projectionOffset.x) * distortion + accumTime * speed) * 0.01);
+
+   // Clamp the calculated uv values to be within the target's viewport
+	y = clamp(y, targetViewport.y, targetViewport.w);
+	x = clamp(x, targetViewport.x, targetViewport.z);
+	
     return tex2D (inputTex, float2(x, y));
 }