From 2077632a9273fea56cfc759a6bef8761407b2bc6 Mon Sep 17 00:00:00 2001 From: DavidWyand-GG Date: Fri, 1 Nov 2013 16:18:48 -0400 Subject: [PATCH] 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. --- Engine/source/postFx/postEffect.cpp | 28 +++++++++++++++++++ Engine/source/postFx/postEffect.h | 3 ++ .../core/scripts/client/postFx/turbulence.cs | 6 ++-- .../shaders/common/postFx/turbulenceP.hlsl | 11 ++++++-- .../core/scripts/client/postFx/turbulence.cs | 6 ++-- .../shaders/common/postFx/turbulenceP.hlsl | 11 ++++++-- 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 04089338e..9a0e9e4e4 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/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() ) diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 8208a8e88..4ea75595f 100644 --- a/Engine/source/postFx/postEffect.h +++ b/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; diff --git a/Templates/Empty/game/core/scripts/client/postFx/turbulence.cs b/Templates/Empty/game/core/scripts/client/postFx/turbulence.cs index 6e897621c..bf63ced07 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/turbulence.cs +++ b/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; diff --git a/Templates/Empty/game/shaders/common/postFx/turbulenceP.hlsl b/Templates/Empty/game/shaders/common/postFx/turbulenceP.hlsl index 631338814..0fb38ea07 100644 --- a/Templates/Empty/game/shaders/common/postFx/turbulenceP.hlsl +++ b/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)); } diff --git a/Templates/Full/game/core/scripts/client/postFx/turbulence.cs b/Templates/Full/game/core/scripts/client/postFx/turbulence.cs index 82f05f00e..bf63ced07 100644 --- a/Templates/Full/game/core/scripts/client/postFx/turbulence.cs +++ b/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; diff --git a/Templates/Full/game/shaders/common/postFx/turbulenceP.hlsl b/Templates/Full/game/shaders/common/postFx/turbulenceP.hlsl index 631338814..0fb38ea07 100644 --- a/Templates/Full/game/shaders/common/postFx/turbulenceP.hlsl +++ b/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)); }