summaryrefslogtreecommitdiff
path: root/materialsystem/stdshaders/Engine_Post_dx9.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'materialsystem/stdshaders/Engine_Post_dx9.cpp')
-rw-r--r--materialsystem/stdshaders/Engine_Post_dx9.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/materialsystem/stdshaders/Engine_Post_dx9.cpp b/materialsystem/stdshaders/Engine_Post_dx9.cpp
new file mode 100644
index 0000000..66a290f
--- /dev/null
+++ b/materialsystem/stdshaders/Engine_Post_dx9.cpp
@@ -0,0 +1,227 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "BaseVSShader.h"
+
+#include "screenspaceeffect_vs20.inc"
+#include "engine_post_ps20.inc"
+#include "engine_post_ps20b.inc"
+
+#include "../materialsystem_global.h"
+
+
+DEFINE_FALLBACK_SHADER( Engine_Post, Engine_Post_dx9 )
+BEGIN_VS_SHADER_FLAGS( Engine_Post_dx9, "Engine post-processing effects (software anti-aliasing, bloom, color-correction", SHADER_NOT_EDITABLE )
+ BEGIN_SHADER_PARAMS
+ SHADER_PARAM( FBTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB", "Full framebuffer texture" )
+ SHADER_PARAM( AAENABLE, SHADER_PARAM_TYPE_BOOL, "0", "Enable software anti-aliasing" )
+ SHADER_PARAM( AAINTERNAL1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
+ SHADER_PARAM( AAINTERNAL2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
+ SHADER_PARAM( AAINTERNAL3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0]", "Internal anti-aliasing values set via material proxy" )
+ SHADER_PARAM( BLOOMENABLE, SHADER_PARAM_TYPE_BOOL, "1", "Enable bloom" )
+ END_SHADER_PARAMS
+
+ SHADER_INIT_PARAMS()
+ {
+ if( !params[ AAENABLE ]->IsDefined() )
+ {
+ params[ AAENABLE ]->SetIntValue( 0 );
+ }
+ if( !params[ AAINTERNAL1 ]->IsDefined() )
+ {
+ params[ AAINTERNAL1 ]->SetVecValue( 0, 0, 0, 0 );
+ }
+ if( !params[ AAINTERNAL2 ]->IsDefined() )
+ {
+ params[ AAINTERNAL2 ]->SetVecValue( 0, 0, 0, 0 );
+ }
+ if( !params[ AAINTERNAL3 ]->IsDefined() )
+ {
+ params[ AAINTERNAL3 ]->SetVecValue( 0, 0, 0, 0 );
+ }
+ if( !params[ BLOOMENABLE ]->IsDefined() )
+ {
+ params[ BLOOMENABLE ]->SetIntValue( 1 );
+ }
+ SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
+ }
+
+ SHADER_FALLBACK
+ {
+ // This shader should not be *used* unless we're >= DX9 (bloomadd.vmt/screenspace_general_dx8 should be used for DX8)
+ return 0;
+ }
+
+ SHADER_INIT
+ {
+ if ( params[BASETEXTURE]->IsDefined() )
+ {
+ LoadTexture( BASETEXTURE );
+ }
+ if ( params[FBTEXTURE]->IsDefined() )
+ {
+ LoadTexture( FBTEXTURE );
+ }
+ }
+
+ SHADER_DRAW
+ {
+ SHADOW_STATE
+ {
+ // This shader uses opaque blending, but needs to match the behaviour of bloom_add/screen_spacegeneral,
+ // which uses additive blending (and is used when bloom is enabled but col-correction and AA are not).
+ // BUT!
+ // Hardware sRGB blending is incorrect (on pre-DX10 cards, sRGB values are added directly).
+ // SO...
+ // When doing the bloom addition in the pixel shader, we need to emulate that incorrect
+ // behaviour - by turning sRGB read OFF for the FB texture and by turning sRGB write OFF
+ // (which is fine, since the AA process works better on an sRGB framebuffer than a linear
+ // one; gamma colours more closely match luminance perception. The color-correction process
+ // has always taken gamma-space values as input anyway).
+
+ // On OpenGL OSX, we MUST do sRGB reads from the bloom and full framebuffer textures AND sRGB
+ // writes on the way out to the framebuffer. Hence, our colors are linear in the shader.
+ // Given this, we use the LINEAR_INPUTS combo to convert to sRGB for the purposes of color
+ // correction, since that is how the color correction textures are authored.
+ bool bLinearInput = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs();
+ bool bLinearOutput = IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() && g_pHardwareConfig->CanDoSRGBReadFromRTs();
+
+ bool bForceSRGBReadsAndWrites = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs();
+
+ pShaderShadow->EnableBlending( false );
+
+ // The (sRGB) bloom texture is bound to sampler 0
+ pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadsAndWrites );
+ pShaderShadow->EnableSRGBWrite( bForceSRGBReadsAndWrites );
+
+ // The (sRGB) full framebuffer texture is bound to sampler 1:
+ pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, bForceSRGBReadsAndWrites );
+
+ // Up to 4 (sRGB) color-correction lookup textures are bound to samplers 2-5:
+ pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false );
+
+ int format = VERTEX_POSITION;
+ int numTexCoords = 1;
+ int * pTexCoordDimensions = NULL;
+ int userDataSize = 0;
+ pShaderShadow->VertexShaderVertexFormat( format, numTexCoords, pTexCoordDimensions, userDataSize );
+
+ DECLARE_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
+ SET_STATIC_VERTEX_SHADER( screenspaceeffect_vs20 );
+
+ if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // GL always goes the ps2b way for this shader, even on "ps20" parts
+ {
+ DECLARE_STATIC_PIXEL_SHADER( engine_post_ps20b );
+ SET_STATIC_PIXEL_SHADER_COMBO( LINEAR_INPUT, bLinearInput );
+ SET_STATIC_PIXEL_SHADER_COMBO( LINEAR_OUTPUT, bLinearOutput );
+ SET_STATIC_PIXEL_SHADER( engine_post_ps20b );
+ }
+ else
+ {
+ DECLARE_STATIC_PIXEL_SHADER( engine_post_ps20 );
+ SET_STATIC_PIXEL_SHADER( engine_post_ps20 );
+ }
+ }
+ DYNAMIC_STATE
+ {
+ BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 );
+ // FIXME: need to set FBTEXTURE to be point-sampled (will speed up this shader significantly on 360)
+ // and assert that it's set to SHADER_TEXWRAPMODE_CLAMP (since the shader will sample offscreen)
+ BindTexture( SHADER_SAMPLER1, FBTEXTURE, -1 );
+
+ ShaderColorCorrectionInfo_t ccInfo;
+ pShaderAPI->GetCurrentColorCorrection( &ccInfo );
+ int colCorrectNumLookups = ccInfo.m_nLookupCount;
+ for( int i = 0; i < colCorrectNumLookups; i++ )
+ {
+ pShaderAPI->BindStandardTexture( (Sampler_t)(SHADER_SAMPLER2 + i), (StandardTextureId_t)(TEXTURE_COLOR_CORRECTION_VOLUME_0 + i) );
+ }
+
+ // Upload 1-pixel X&Y offsets [ (+dX,0,+dY,-dX) is chosen to work with the allowed ps20 swizzles ]
+ // The shader will sample in a cross (up/down/left/right from the current sample), for 5-tap
+ // (quality 0) mode and add another 4 samples in a diagonal cross, for 9-tap (quality 1) mode
+ ITexture * pTarget = params[FBTEXTURE]->GetTextureValue();
+ int width = pTarget->GetActualWidth();
+ int height = pTarget->GetActualHeight();
+ float dX = 1.0f / width;
+ float dY = 1.0f / height;
+ float offsets[4] = { +dX, 0, +dY, -dX };
+ pShaderAPI->SetPixelShaderConstant( 0, &offsets[0], 1 );
+ // Upload AA tweakables:
+ // x - strength (this can be used to toggle the AA off, or to weaken it where pathological cases are showing)
+ // y - reduction of 1-pixel-line blurring (blurring of 1-pixel lines causes issues, so it's tunable)
+ // z - edge threshold multiplier (default 1.0, < 1.0 => more edges softened, > 1.0 => fewer edges softened)
+ // w - tap offset multiplier (default 1.0, < 1.0 => sharper image, > 1.0 => blurrier image)
+ float tweakables[4] = { params[ AAINTERNAL1 ]->GetVecValue()[0],
+ params[ AAINTERNAL1 ]->GetVecValue()[1],
+ params[ AAINTERNAL3 ]->GetVecValue()[0],
+ params[ AAINTERNAL3 ]->GetVecValue()[1] };
+ pShaderAPI->SetPixelShaderConstant( 1, &tweakables[0], 1 );
+ // Upload AA UV transform (converts bloom texture UVs to framebuffer texture UVs)
+ // NOTE: we swap the order of the z and w components since 'wz' is an allowed ps20 swizzle, but 'zw' is not:
+ float uvTrans[4] = { params[ AAINTERNAL2 ]->GetVecValue()[0],
+ params[ AAINTERNAL2 ]->GetVecValue()[1],
+ params[ AAINTERNAL2 ]->GetVecValue()[3],
+ params[ AAINTERNAL2 ]->GetVecValue()[2] };
+ pShaderAPI->SetPixelShaderConstant( 2, &uvTrans[0], 1 );
+
+ // Upload color-correction weights:
+ pShaderAPI->SetPixelShaderConstant( 3, &ccInfo.m_flDefaultWeight );
+ pShaderAPI->SetPixelShaderConstant( 4, ccInfo.m_pLookupWeights );
+
+ int aaEnabled = ( params[ AAINTERNAL1 ]->GetVecValue()[0] == 0.0f ) ? 0 : 1;
+ int aaReduceOnePixelLineBlur = ( params[ AAINTERNAL1 ]->GetVecValue()[1] == 0.0f ) ? 0 : 1;
+ int aaQualityMode = (int)params[ AAINTERNAL1 ]->GetVecValue()[2];
+// int aaDebugMode = (int)params[ AAINTERNAL1 ]->GetVecValue()[3];
+ int bloomEnabled = ( params[ BLOOMENABLE ]->GetIntValue() == 0 ) ? 0 : 1;
+ int colCorrectEnabled = ccInfo.m_bIsEnabled;
+
+ float flBloomFactor = bloomEnabled ? 1.0f : 0.0f;
+ float bloomConstant[4] = { flBloomFactor, flBloomFactor, flBloomFactor, flBloomFactor };
+ pShaderAPI->SetPixelShaderConstant( 5, bloomConstant );
+
+ if ( !colCorrectEnabled )
+ {
+ colCorrectNumLookups = 0;
+ }
+
+ if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // GL always goes the ps2b way for this shader, even on "ps20" parts
+ {
+ DECLARE_DYNAMIC_PIXEL_SHADER( engine_post_ps20b );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_QUALITY_MODE, aaQualityMode );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_REDUCE_ONE_PIXEL_LINE_BLUR, aaReduceOnePixelLineBlur );
+// SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_DEBUG_MODE, aaDebugMode );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups );
+ SET_DYNAMIC_PIXEL_SHADER( engine_post_ps20b );
+ }
+ else
+ {
+ DECLARE_DYNAMIC_PIXEL_SHADER( engine_post_ps20 );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_ENABLE, aaEnabled );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_QUALITY_MODE, 0 ); // Only enough instruction slots in ps2b
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_REDUCE_ONE_PIXEL_LINE_BLUR, 0 );
+// SET_DYNAMIC_PIXEL_SHADER_COMBO( AA_DEBUG_MODE, aaDebugMode );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( COL_CORRECT_NUM_LOOKUPS, colCorrectNumLookups );
+ SET_DYNAMIC_PIXEL_SHADER( engine_post_ps20 );
+ }
+
+ DECLARE_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
+ SET_DYNAMIC_VERTEX_SHADER( screenspaceeffect_vs20 );
+ }
+ Draw();
+ }
+END_SHADER