Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

661 lines
28 KiB

//===== Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose: shader for drawing sprites as cards, with animation frame lerping
//
// $Header: $
// $NoKeywords: $
//===========================================================================//
#include "BaseVSShader.h"
#include "convar.h"
// STDSHADER_DX9_DLL_EXPORT
#include "spritecard_ps20.inc"
#include "spritecard_ps20b.inc"
#include "spritecard_vs20.inc"
#include "splinecard_vs20.inc"
#include "common_hlsl_cpp_consts.h"
#include "tier0/icommandline.h" //command line
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define DEFAULT_PARTICLE_FEATHERING_ENABLED 1
static ConVar mat_depthfeather_enable( "mat_depthfeather_enable", "1", FCVAR_DEVELOPMENTONLY );
#if defined( CSTRIKE15 ) && defined( _X360 )
static ConVar r_shader_srgbread( "r_shader_srgbread", "1", 0, "1 = use shader srgb texture reads, 0 = use HW" );
#else
static ConVar r_shader_srgbread( "r_shader_srgbread", "0", 0, "1 = use shader srgb texture reads, 0 = use HW" );
#endif
int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go against the default soft-particle value
{
static int iRetVal = -1;
if ( iRetVal == -1 )
{
#if ( DEFAULT_PARTICLE_FEATHERING_ENABLED == 1 )
{
if ( CommandLine()->CheckParm( "-softparticlesdefaultoff" ) )
iRetVal = 0;
else
iRetVal = 1;
}
#else
{
if ( CommandLine()->CheckParm( "-softparticlesdefaulton" ) )
iRetVal = 1;
else
iRetVal = 0;
}
#endif
}
// On low end parts on the Mac, we reduce particles and shut off depth blending here
static ConVarRef mat_reduceparticles( "mat_reduceparticles" );
if ( mat_reduceparticles.GetBool() )
{
iRetVal = 0;
}
return iRetVal;
}
BEGIN_VS_SHADER_FLAGS( Spritecard, "Help for Spritecard", SHADER_NOT_EDITABLE )
BEGIN_SHADER_PARAMS
SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" )
SHADER_PARAM( SCENEDEPTH, SHADER_PARAM_TYPE_TEXTURE, "", "" )
SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." )
SHADER_PARAM( INVERSEDEPTHBLEND, SHADER_PARAM_TYPE_BOOL, "0", "calculate 1-depthblendalpha so that sprites appear when they are near geometry" )
SHADER_PARAM( ORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "0 = always face camera, 1 = rotate around z, 2= parallel to ground 3=use normal 4=face camera POS" )
SHADER_PARAM( AIMATCAMERA, SHADER_PARAM_TYPE_BOOL, "0", "Aim at camera using orientation type 1" )
SHADER_PARAM( ADDBASETEXTURE2, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount to blend second texture into frame by" )
SHADER_PARAM( OVERBRIGHTFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "overbright factor for texture. For HDR effects.")
SHADER_PARAM( DUALSEQUENCE, SHADER_PARAM_TYPE_INTEGER, "0", "blend two separate animated sequences.")
SHADER_PARAM( SEQUENCE_BLEND_MODE, SHADER_PARAM_TYPE_INTEGER, "0", "defines the blend mode between the images un dual sequence particles. 0 = avg, 1=alpha from first, rgb from 2nd, 2= first over second" )
SHADER_PARAM( MAXLUMFRAMEBLEND1, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the first sequence, select pixels based upon max luminance" )
SHADER_PARAM( MAXLUMFRAMEBLEND2, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the 2nd sequence, select pixels based upon max luminance" )
SHADER_PARAM( RAMPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "if specified, then the red value of the image is used to index this ramp to produce the output color" )
SHADER_PARAM( ZOOMANIMATESEQ2, SHADER_PARAM_TYPE_FLOAT, "1.0", "amount to gradually zoom between frames on the second sequence. 2.0 will double the size of a frame over its lifetime.")
SHADER_PARAM( EXTRACTGREENALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "grayscale data sitting in green/alpha channels")
SHADER_PARAM( ADDOVERBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "use ONE:INVSRCALPHA blending")
SHADER_PARAM( ADDSELF, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount of base texture to additively blend in" )
SHADER_PARAM( BLENDFRAMES, SHADER_PARAM_TYPE_BOOL, "1", "whether or not to smoothly blend between animated frames" )
SHADER_PARAM( MINSIZE, SHADER_PARAM_TYPE_FLOAT, "0.0", "minimum screen fractional size of particle")
SHADER_PARAM( STARTFADESIZE, SHADER_PARAM_TYPE_FLOAT, "10.0", "screen fractional size to start fading particle out")
SHADER_PARAM( ENDFADESIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "screen fractional size to finish fading particle out")
SHADER_PARAM( MAXSIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "maximum screen fractional size of particle")
SHADER_PARAM( USEINSTANCING, SHADER_PARAM_TYPE_BOOL, "1", "whether to use GPU vertex instancing (submit 1 vert per particle quad)")
SHADER_PARAM( SPLINETYPE, SHADER_PARAM_TYPE_INTEGER, "0", "spline type 0 = none, 1=ctamull rom")
SHADER_PARAM( MAXDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100000.0", "maximum distance to draw particles at")
SHADER_PARAM( FARFADEINTERVAL, SHADER_PARAM_TYPE_FLOAT, "400.0", "interval over which to fade out far away particles")
SHADER_PARAM( SHADERSRGBREAD360, SHADER_PARAM_TYPE_BOOL, "0", "Simulate srgb read in shader code")
SHADER_PARAM( ORIENTATIONMATRIX, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "Matrix used to orient in orientation mode #2" )
SHADER_PARAM( MOD2X, SHADER_PARAM_TYPE_BOOL, "0", "whether or not to multiply the result of the pixel shader * 2 against the framebuffer" )
SHADER_PARAM( ALPHATRAILFADE, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to scale alpha by between start and end of trail/rope" )
SHADER_PARAM( RADIUSTRAILFADE, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to scale radis by between start and end of trail/rope" )
SHADER_PARAM( SHADOWDEPTH,SHADER_PARAM_TYPE_INTEGER, "0", "writing to a shadow depth buffer" )
SHADER_PARAM( OPAQUE, SHADER_PARAM_TYPE_BOOL, "0", "Are we opaque? (defaults to 0)" )
SHADER_PARAM( CROPFACTOR,SHADER_PARAM_TYPE_VEC2, "[1 1]", "writing to a shadow depth buffer" )
SHADER_PARAM( VERTEXCOLORLERP, SHADER_PARAM_TYPE_BOOL, "0", "Enable computing vertex color by interpolating two color based on vertex r color channel" )
SHADER_PARAM( LERPCOLOR1, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Lerp color 1" )
SHADER_PARAM( LERPCOLOR2, SHADER_PARAM_TYPE_VEC3, "[0 1 0]", "Lerp color 2" )
SHADER_PARAM( VERTEXFOGAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1", "Amount of vertex fog to apply" )
// distance outline control
SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.")
SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.")
SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha.");
SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha.");
SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.")
SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." )
SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline")
SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline")
SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline")
SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline")
SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline")
SHADER_PARAM( PERPARTICLEOUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Allow per particle outline control" )
SHADER_PARAM( MULOUTPUTBYALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Multiply output RGB by output alpha to avoid precision problems" );
SHADER_PARAM( INTENSITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Multiply output RGB by intensity factor" );
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
INIT_FLOAT_PARM( MAXDISTANCE, 100000.0 );
INIT_FLOAT_PARM( FARFADEINTERVAL, 400.0 );
INIT_FLOAT_PARM( MAXSIZE, 20.0 );
INIT_FLOAT_PARM( ENDFADESIZE, 20.0 );
INIT_FLOAT_PARM( STARTFADESIZE, 10.0 );
INIT_FLOAT_PARM( DEPTHBLENDSCALE, 50.0 );
INIT_FLOAT_PARM( OVERBRIGHTFACTOR, 1.0 );
INIT_FLOAT_PARM( ADDBASETEXTURE2, 0.0 );
INIT_FLOAT_PARM( ADDSELF, 0.0 );
INIT_FLOAT_PARM( ZOOMANIMATESEQ2, 0.0 );
INIT_FLOAT_PARM( ALPHATRAILFADE, 1. );
INIT_FLOAT_PARM( RADIUSTRAILFADE, 1. );
INIT_FLOAT_PARM( VERTEXFOGAMOUNT, 0.0f );
INIT_FLOAT_PARM( OUTLINEALPHA, 1.0 );
if ( !params[ORIENTATIONMATRIX]->IsDefined() )
{
VMatrix mat;
MatrixSetIdentity( mat );
params[ORIENTATIONMATRIX]->SetMatrixValue( mat );
}
if ( !params[CROPFACTOR]->IsDefined() )
{
params[CROPFACTOR]->SetVecValue( 1.0f, 1.0f );
}
if ( !params[DEPTHBLEND]->IsDefined() )
{
params[ DEPTHBLEND ]->SetIntValue( GetDefaultDepthFeatheringValue() );
}
if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
params[ DEPTHBLEND ]->SetIntValue( 0 );
}
InitIntParam( DUALSEQUENCE, params, 0 );
InitIntParam( MAXLUMFRAMEBLEND1, params, 0 );
InitIntParam( MAXLUMFRAMEBLEND2, params, 0 );
InitIntParam( EXTRACTGREENALPHA, params, 0 );
InitIntParam( ADDOVERBLEND, params, 0 );
InitIntParam( BLENDFRAMES, params, 1 );
InitIntParam( DISTANCEALPHA, params, 0 );
InitIntParam( OUTLINE, params, 0 );
InitIntParam( SOFTEDGES, params, 0 );
InitIntParam( PERPARTICLEOUTLINE, params, 0 );
InitIntParam( MULOUTPUTBYALPHA, params, 0 );
InitFloatParam( INTENSITY, params, 1.0f );
if ( !params[USEINSTANCING]->IsDefined() )
{
params[ USEINSTANCING ]->SetIntValue( IsX360() ? 1 : 0 );
}
// srgb read 360
InitIntParam( SHADERSRGBREAD360, params, 0 );
// default to being translucent since that's what we always were for historical reasons.
InitIntParam( OPAQUE, params, 0 );
InitIntParam( VERTEXCOLORLERP, params, 0 );
if ( !params[LERPCOLOR1]->IsDefined() )
{
params[LERPCOLOR1]->SetVecValue( 1.0f, 0.0f, 0.0f );
}
if ( !params[LERPCOLOR2]->IsDefined() )
{
params[LERPCOLOR2]->SetVecValue( 0.0f, 1.0f, 0.0f );
}
if ( params[OPAQUE]->GetIntValue() != 0 )
{
// none of these make sense if we have $opaque 1:
params[ADDBASETEXTURE2]->SetFloatValue( 0.0f );
params[DUALSEQUENCE]->SetIntValue( 0 );
params[SEQUENCE_BLEND_MODE]->SetIntValue( 0 );
params[MAXLUMFRAMEBLEND1]->SetIntValue( 0 );
params[MAXLUMFRAMEBLEND2]->SetIntValue( 0 );
params[EXTRACTGREENALPHA]->SetIntValue( 0 );
params[RAMPTEXTURE]->SetUndefined();
params[ZOOMANIMATESEQ2]->SetIntValue( 0 );
params[ADDOVERBLEND]->SetIntValue( 0 );
params[ADDSELF]->SetIntValue( 0 );
params[BLENDFRAMES]->SetIntValue( 0 );
params[DEPTHBLEND]->SetIntValue( 0 );
params[INVERSEDEPTHBLEND]->SetIntValue( 0 );
}
if ( IsPS3() && !params[SCENEDEPTH]->IsDefined() )
{
params[SCENEDEPTH]->SetStringValue( "^PS3^DEPTHBUFFER" );
}
if ( g_pHardwareConfig->HasFullResolutionDepthTexture() )
{
params[SCENEDEPTH]->SetStringValue( "_rt_FullFrameDepth" );
}
SET_FLAGS2( MATERIAL_VAR2_IS_SPRITECARD );
}
SHADER_FALLBACK
{
return 0;
}
SHADER_INIT
{
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
if ( params[BASETEXTURE]->IsDefined() )
{
bool bExtractGreenAlpha = false;
if ( params[EXTRACTGREENALPHA]->IsDefined() )
{
bExtractGreenAlpha = params[EXTRACTGREENALPHA]->GetIntValue() != 0;
}
LoadTexture( BASETEXTURE, bExtractGreenAlpha ? 0 : TEXTUREFLAGS_SRGB );
}
if ( params[RAMPTEXTURE]->IsDefined() )
{
LoadTexture( RAMPTEXTURE, TEXTUREFLAGS_SRGB );
}
if( IsPS3() && params[SCENEDEPTH]->IsDefined() )
{
LoadTexture( SCENEDEPTH, 0 );
}
if ( g_pHardwareConfig->HasFullResolutionDepthTexture() )
{
LoadTexture( SCENEDEPTH, 0 );
}
}
SHADER_DRAW
{
bool bUseRampTexture = ( params[RAMPTEXTURE]->IsDefined() );
bool bZoomSeq2 = ( ( params[ZOOMANIMATESEQ2]->GetFloatValue()) > 1.0 );
bool bDepthBlend = false;
if ( g_pHardwareConfig->HasFullResolutionDepthTexture() )
{
// If we didn't create the depth texture. We are looking at not using depth feathering to save memory.
static bool bNoDepthTexture = ( CommandLine()->FindParm( "-nodepthtexture" ) ) ? true : false;
if ( !bNoDepthTexture )
{
bDepthBlend = ( params[DEPTHBLEND]->GetIntValue() != 0 ) && mat_depthfeather_enable.GetBool();
}
}
bool bInverseDepthBlend = ( params[INVERSEDEPTHBLEND]->GetIntValue() != 0 );
bool bAdditive2ndTexture = params[ADDBASETEXTURE2]->GetFloatValue() != 0.0;
bool bExtractGreenAlpha = ( params[EXTRACTGREENALPHA]->GetIntValue() != 0 );
int nSplineType = params[SPLINETYPE]->GetIntValue();
bool bUseInstancing = IsX360() ? ( params[ USEINSTANCING ]->GetIntValue() != 0 ) : false;
#if defined( CSTRIKE15 )
bool bShaderSrgbRead = IsX360() && r_shader_srgbread.GetBool();
#else
bool bShaderSrgbRead = ( IsX360() && IS_PARAM_DEFINED( SHADERSRGBREAD360 ) && params[SHADERSRGBREAD360]->GetIntValue() );
#endif
bool bCrop = ( params[CROPFACTOR]->GetVecValue()[0] != 1.0f ) || ( params[CROPFACTOR]->GetVecValue()[1] != 1.0f );
bool bSecondSequence = params[DUALSEQUENCE]->GetIntValue() != 0;
bool bBlendFrames = ( params[BLENDFRAMES]->GetIntValue() != 0 );
bool bDistanceAlpha = ( params[DISTANCEALPHA]->GetIntValue() != 0 );
bool bOutLine = bDistanceAlpha && ( params[OUTLINE]->GetIntValue() != 0 );
bool bSoftEdges = bDistanceAlpha && ( params[OUTLINE]->GetIntValue() != 0 );
bool bPerParticleOutline = bDistanceAlpha && ( !bSecondSequence ) && ( params[PERPARTICLEOUTLINE]->GetIntValue() );
float flIntensity = params[INTENSITY]->GetFloatValue();
if ( nSplineType )
{
bDepthBlend = false; //splinecard_vsxx.fxc doesn't output all the data necessary for depth blending
bUseInstancing = false;
bBlendFrames = false;
}
bool bColorLerpPS = ( params[VERTEXCOLORLERP]->GetIntValue() != 0 );
bool bPackedInterpolator = bColorLerpPS && !( bExtractGreenAlpha || bSecondSequence || bBlendFrames || params[MAXLUMFRAMEBLEND1]->GetIntValue() );
bool bFog = params[VERTEXFOGAMOUNT]->GetFloatValue() != 0;
SHADOW_STATE
{
bool bAddOverBlend = params[ADDOVERBLEND]->GetIntValue() != 0;
bool bMod2X = params[MOD2X]->GetIntValue() != 0;
bool bShadowDepth = ( params[SHADOWDEPTH]->GetIntValue() != 0 );
bool bAddSelf = params[ADDSELF]->GetFloatValue() != 0.0;
if ( bFog )
{
pShaderShadow->FogMode( SHADER_FOGMODE_FOGCOLOR, true );
}
// draw back-facing because of yaw spin
pShaderShadow->EnableCulling( false );
// Don't write to dest alpha.
pShaderShadow->EnableAlphaWrites( false );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
if ( bUseRampTexture )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, !bShaderSrgbRead );
}
if ( bDepthBlend )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
}
if ( bAdditive2ndTexture || bAddSelf )
pShaderShadow->EnableAlphaTest( false );
else
pShaderShadow->EnableAlphaTest( true );
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 1 / 255 );
if ( bMod2X )
{
EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR );
}
else if ( bAdditive2ndTexture || bAddOverBlend || bAddSelf )
{
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
else
{
if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) )
{
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
}
else
{
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
}
}
bool bUseNormal = ( params[ORIENTATION]->GetIntValue() == 3 );
unsigned int flags = VERTEX_POSITION | VERTEX_COLOR;
static int s_TexCoordSize[8]={4, // 0 = sheet bounding uvs, frame0
4, // 1 = sheet bounding uvs, frame 1
4, // 2 = frame blend, rot, radius, ???
2, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 )
4, // 4 = texture 2 bounding uvs
4, // 5 = second sequence bounding uvs, frame0.. or glow tint, or normal
4, // 6 = second sequence bounding uvs, frame1
4, // 7 = second sequence frame blend, ?,?,?
};
static int s_TexCoordSizeSpline[]={4, // 0 = xyz rad pt0
4, // 1 = xyz rad pt1
4, // 2 = xyz rad pt2
4, // 3 = xyz rad pt3
4, // 4 = texture range u0,v0-u1,v1
4, // 5 = rgba pt1
3, // 6 = normal0
3, // 7 = normal1
};
int numTexCoords = 5;
if ( nSplineType )
{
numTexCoords += 1; // need second rope color
if ( bUseNormal )
numTexCoords += 2; // need normal vectors
}
else
{
if ( bPerParticleOutline || bUseNormal )
{
numTexCoords = 6;
}
else
{
if ( bSecondSequence )
{
// the whole shebang - 2 sequences, with a possible multi-image sequence first
numTexCoords = 8;
}
}
}
pShaderShadow->VertexShaderVertexFormat( flags,
numTexCoords,
nSplineType? s_TexCoordSizeSpline : s_TexCoordSize, 0 );
if ( nSplineType )
{
DECLARE_STATIC_VERTEX_SHADER( splinecard_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( ADDBASETEXTURE2, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( DEPTHBLEND, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( PACKED_INTERPOLATOR, 0 );
SET_STATIC_VERTEX_SHADER_COMBO( ANIMBLEND_OR_MAXLUMFRAMEBLEND1, bBlendFrames || ( params[MAXLUMFRAMEBLEND1]->GetIntValue() != 0 ) );
SET_STATIC_VERTEX_SHADER( splinecard_vs20 );
}
else
{
DECLARE_STATIC_VERTEX_SHADER( spritecard_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( SPRITECARDVERTEXFOG, bFog );
SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, bSecondSequence );
SET_STATIC_VERTEX_SHADER_COMBO( ZOOM_ANIMATE_SEQ2, bZoomSeq2 );
SET_STATIC_VERTEX_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture );
SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha );
SET_STATIC_VERTEX_SHADER_COMBO( DEPTHBLEND, bDepthBlend );
SET_STATIC_VERTEX_SHADER_COMBO( ANIMBLEND_OR_MAXLUMFRAMEBLEND1, bBlendFrames || ( params[MAXLUMFRAMEBLEND1]->GetIntValue() != 0 ) );
SET_STATIC_VERTEX_SHADER_COMBO( CROP, bCrop );
SET_STATIC_VERTEX_SHADER_COMBO( PACKED_INTERPOLATOR, bPackedInterpolator );
SET_STATIC_VERTEX_SHADER_COMBO( HARDWAREFOGBLEND, !IsX360() && bFog && ( g_pHardwareConfig->GetDXSupportLevel() <= 90 ) );
SET_STATIC_VERTEX_SHADER_COMBO( PERPARTICLEOUTLINE, bPerParticleOutline );
SET_STATIC_VERTEX_SHADER( spritecard_vs20 );
}
bool bMulOutputByAlpha = params[MULOUTPUTBYALPHA]->GetIntValue() != 0;
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture );
SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf );
SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames );
SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence );
SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 );
SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 );
SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture );
SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha );
SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDepthBlend );
SET_STATIC_PIXEL_SHADER_COMBO( INVERSEDEPTHBLEND, bInverseDepthBlend );
SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
SET_STATIC_PIXEL_SHADER_COMBO( MOD2X, bMod2X );
SET_STATIC_PIXEL_SHADER_COMBO( PACKED_INTERPOLATOR, bPackedInterpolator );
SET_STATIC_PIXEL_SHADER_COMBO( COLOR_LERP_PS, bColorLerpPS );
SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha );
SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutLine );
SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bSoftEdges );
SET_STATIC_PIXEL_SHADER_COMBO( MULOUTPUTBYALPHA, bMulOutputByAlpha );
SET_STATIC_PIXEL_SHADER( spritecard_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture );
SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence );
SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf );
SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames );
SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 );
SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() );
SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 );
SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture );
SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha );
SET_STATIC_PIXEL_SHADER_COMBO( INVERSEDEPTHBLEND, bInverseDepthBlend );
SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
SET_STATIC_PIXEL_SHADER_COMBO( MOD2X, bMod2X );
SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDepthBlend );
SET_STATIC_PIXEL_SHADER_COMBO( PACKED_INTERPOLATOR, bPackedInterpolator );
SET_STATIC_PIXEL_SHADER_COMBO( COLOR_LERP_PS, bColorLerpPS );
SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha );
SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutLine );
SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bSoftEdges );
SET_STATIC_PIXEL_SHADER_COMBO( MULOUTPUTBYALPHA, bMulOutputByAlpha );
SET_STATIC_PIXEL_SHADER( spritecard_ps20 );
}
if ( bShadowDepth )
{
pShaderShadow->EnableColorWrites( false );
pShaderShadow->EnableAlphaWrites( false );
pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_SHADOW_BIAS );
}
pShaderShadow->EnableSRGBWrite( true );
if( !bExtractGreenAlpha )
{
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, !bShaderSrgbRead );
}
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, SRGBReadMask( (! bExtractGreenAlpha ) && ( ! bShaderSrgbRead ) ), BASETEXTURE, FRAME );
if ( bUseRampTexture )
{
BindTexture( SHADER_SAMPLER1, SRGBReadMask( !bShaderSrgbRead ), RAMPTEXTURE, FRAME );
}
if ( bDepthBlend )
{
BindTexture( SHADER_SAMPLER2, TEXTURE_BINDFLAGS_NONE, SCENEDEPTH, -1 );
}
int nOrientation = params[ORIENTATION]->GetIntValue();
nOrientation = clamp( nOrientation, 0, 4 );
if ( nOrientation == 1 && params[AIMATCAMERA]->GetIntValue() > 0 )
nOrientation = 4;
switch ( nOrientation )
{
case 0:
// We need these only when screen-orienting
LoadModelViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 );
LoadProjectionMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 );
break;
case 2:
// We need this only when doing fixed orientation
SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, ORIENTATIONMATRIX );
break;
}
if ( bZoomSeq2 || bFog )
{
float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue());
float C0[4]={ 0.5*(1.0+flZScale), flZScale, params[VERTEXFOGAMOUNT]->GetFloatValue(), 0 };
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, C0, ARRAYSIZE(C0)/4 );
}
// set fade constants in vsconsts 8 and 9
float flMaxDistance = params[MAXDISTANCE]->GetFloatValue();
float flStartFade = MAX( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() );
float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(),
params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(),
flStartFade, 1.0/(flMaxDistance-flStartFade),
params[ALPHATRAILFADE]->GetFloatValue(),
params[RADIUSTRAILFADE]->GetFloatValue() };
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, VC0, ARRAYSIZE(VC0)/4 );
if ( bDepthBlend )
{
pShaderAPI->SetDepthFeatheringShaderConstants( 2, params[DEPTHBLENDSCALE]->GetFloatValue() );
}
// Get viewport and render target dimensions and set shader constant to do a 2D mad
int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
pShaderAPI->GetCurrentViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );
int nRtWidth, nRtHeight;
pShaderAPI->GetCurrentRenderTargetDimensions( nRtWidth, nRtHeight );
float vViewportMad[4];
// Compute viewport mad that takes projection space coords (post divide by W) into normalized screenspace, taking into account the currently set viewport.
vViewportMad[0] = .5f * ( ( float )nViewportWidth / ( float )nRtWidth );
vViewportMad[1] = -.5f * ( ( float )nViewportHeight / ( float )nRtHeight );
vViewportMad[2] = vViewportMad[0] + ( ( float )nViewportX / ( float )nRtWidth );
vViewportMad[3] = -vViewportMad[1] + ( ( float )nViewportY / ( float )nRtHeight );
pShaderAPI->SetPixelShaderConstant( DEPTH_FEATHER_VIEWPORT_MAD, vViewportMad, 1 );
if ( bCrop )
{
float vCropFactors[4];
params[CROPFACTOR]->GetVecValue( vCropFactors, 2 );
vCropFactors[2] = -0.5f * vCropFactors[0] + 0.5f;
vCropFactors[3] = -0.5f * vCropFactors[1] + 0.5f;
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, vCropFactors, 1 );
}
if ( bColorLerpPS )
{
float vLerpColors[8];
params[LERPCOLOR1]->GetVecValue( vLerpColors, 3 );
params[LERPCOLOR2]->GetVecValue( vLerpColors+4, 3 );
vLerpColors[3] = 1.0f;
vLerpColors[7] = 1.0f;
SetPixelShaderConstantGammaToLinear( 5, vLerpColors, 2 );
}
float C0[4]={ params[ADDBASETEXTURE2]->GetFloatValue(), params[OVERBRIGHTFACTOR]->GetFloatValue(), params[ADDSELF]->GetFloatValue(), flIntensity };
BOOL nBoolShaderConstant = bUseInstancing ? 1 : 0; // Convert to BOOL, which is int
pShaderAPI->SetBooleanVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0, &nBoolShaderConstant, 1 );
pShaderAPI->SetPixelShaderConstant( 0, C0, ARRAYSIZE(C0)/4 );
// Set Mod2xIdentity to be 0.5 if we blend in linear space, or 0.5 Gamma->Linear if we blend in gamma space
float vPsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
vPsConst1[0] = g_pHardwareConfig->UsesSRGBCorrectBlending() ? 0.5f : SrgbGammaToLinear( 0.5f );
pShaderAPI->SetPixelShaderConstant( 1, vPsConst1, 1 );
// set up distance-coding constants
if ( bDistanceAlpha )
{
float vDistanceConstants[4 * 3]; // c7, c8,c9
params[OUTLINECOLOR]->GetVecValue( vDistanceConstants, 3 );
vDistanceConstants[3] = params[OUTLINEALPHA]->GetFloatValue();
vDistanceConstants[4] = params[OUTLINESTART0]->GetFloatValue();
vDistanceConstants[5] = params[OUTLINESTART1]->GetFloatValue();
vDistanceConstants[6] = params[OUTLINEEND0]->GetFloatValue();
vDistanceConstants[7] = params[OUTLINEEND1]->GetFloatValue();
vDistanceConstants[8] = params[EDGESOFTNESSSTART]->GetFloatValue();
vDistanceConstants[9] = params[EDGESOFTNESSEND]->GetFloatValue();
vDistanceConstants[10] = 0;
vDistanceConstants[11] = 0;
pShaderAPI->SetPixelShaderConstant( 7, vDistanceConstants, ARRAYSIZE( vDistanceConstants ) / 4 );
}
if ( nSplineType )
{
DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation );
SET_DYNAMIC_VERTEX_SHADER( splinecard_vs20 );
}
else
{
DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation );
SET_DYNAMIC_VERTEX_SHADER( spritecard_vs20 );
}
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( spritecard_ps20b );
SET_DYNAMIC_PIXEL_SHADER( spritecard_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( spritecard_ps20 );
SET_DYNAMIC_PIXEL_SHADER( spritecard_ps20 );
}
}
Draw( );
}
END_SHADER