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)); }