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.
 
 
 
 
 
 

368 lines
10 KiB

//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
// STATIC: "DUALSEQUENCE" "0..1"
// STATIC: "SEQUENCE_BLEND_MODE" "0..2"
// STATIC: "ADDBASETEXTURE2" "0..1"
// STATIC: "MAXLUMFRAMEBLEND1" "0..1"
// STATIC: "MAXLUMFRAMEBLEND2" "0..1"
// STATIC: "EXTRACTGREENALPHA" "0..1"
// STATIC: "COLORRAMP" "0..1"
// STATIC: "ANIMBLEND" "0..1"
// STATIC: "ADDSELF" "0..1"
// STATIC: "MOD2X" "0..1"
// STATIC: "DEPTHBLEND" "0..1" [CONSOLE]
// STATIC: "DEPTHBLEND" "0..1" [PC]
// STATIC: "INVERSEDEPTHBLEND" "0..1" [CONSOLE]
// STATIC: "INVERSEDEPTHBLEND" "0..0" [PC]
// STATIC: "SHADER_SRGB_READ" "0..1" [XBOX]
// STATIC: "SHADER_SRGB_READ" "0..0" [PC]
// STATIC: "SHADER_SRGB_READ" "0..0" [SONYPS3]
// STATIC: "COLOR_LERP_PS" "0..1"
// STATIC: "PACKED_INTERPOLATOR" "0..1"
// STATIC: "DISTANCEALPHA" "0..1"
// STATIC: "SOFTEDGES" "0..1"
// STATIC: "OUTLINE" "0..1"
// STATIC: "MULOUTPUTBYALPHA" "0..1"
// SKIP: ( $DISTANCEALPHA == 0 ) && ( $SOFTEDGES || $OUTLINE )
// SKIP: $DISTANCEALPHA && $DUALSEQUENCE
// SKIP: $DISTANCEALPHA && ( $MAXLUMFRAMEBLEND2 || $MAXLUMFRAMEBLEND1 )
// SKIP: ( $DUALSEQUENCE == 0 ) && ( $SEQUENCE_BLEND_MODE != 0 )
// SKIP: $INVERSEDEPTHBLEND && !$DEPTHBLEND [CONSOLE]
// These are mutually exclusive because PACKED_INTERPOLATOR only fetches a single texture tile
// SKIP: $PACKED_INTERPOLATOR && ( $ANIMBLEND || $MAXLUMFRAMEBLEND1 || $EXTRACTGREENALPHA || $DUALSEQUENCE )
#define COMBINE_MODE_AVERAGE 0
#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1
#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2
#define HDRTYPE HDR_TYPE_NONE
#include "common_ps_fxc.h"
HALF4 g_Parameters : register( c0 );
#define fAdditiveBlendWeight g_Parameters.x
#define fOverbrightFactor g_Parameters.y
#define fAdditiveSelfBlendWeight g_Parameters.z
#define fIntensity g_Parameters.w
float g_flMod2xIdentity : register( c1 );
float4 g_DepthFeatheringConstants : register( c2 );
float4 g_FogParams : register( c3 );
float3 g_EyePos : register( c4 );
HALF3 g_vColor0 : register( c5 );
HALF3 g_vColor1 : register( c6 );
// VS_OUTPUT in a common file.
#define PIXELSHADER
#include "common_spritecard_fxc.h"
sampler BaseTextureSampler : register( s0 );
sampler ColorRampSampler : register( s1 );
sampler DepthSampler : register( s2 );
#if DISTANCEALPHA == 0
#define EDGESOFTNESS_START 0.5h
#define EDGESOFTNESS_END 0.425h
#define OUTLINECOLOR HALF4( 0, 1, 0, 1 )
#define OUTLINESTART0 0.2h
#define OUTLINESTART1 0.3h
#define OUTLINEEND0 0.49h
#define OUTLINEEND1 0.6h
#else
HALF4 g_vecOutlineColor : register( c7 );
#define OUTLINECOLOR (HALF4)( g_vecOutlineColor * i.vecOutlineTint )
HALF4 g_vecOutlineControl : register( c8 );
#define OUTLINESTART0 ( g_vecOutlineControl.x )
#define OUTLINESTART1 ( g_vecOutlineControl.y )
#define OUTLINEEND0 ( g_vecOutlineControl.z )
#define OUTLINEEND1 ( g_vecOutlineControl.w )
HALF4 g_vecEdgeControl : register( c9 );
#define EDGESOFTNESS_START ( g_vecEdgeControl.x )
#define EDGESOFTNESS_END ( g_vecEdgeControl.y )
#endif
HALF DepthFeatheringFullDepth( sampler DepthSampler, const float4 vProjPos, float4 vDepthBlendConstants )
{
# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b
{
float2 vProjPosDivW = vProjPos.xy / vProjPos.w;
float2 vScreenPos = vProjPosDivW * g_vDepthFeatherViewportMad.xy + g_vDepthFeatherViewportMad.zw;
float flFeatheredAlpha;
// Sample the scene's depth at the current fragment.
float flSceneProjZ = tex2D( DepthSampler, vScreenPos ).r;
float4 vSceneProjPos = float4( vProjPosDivW.x, vProjPosDivW.y, flSceneProjZ, 1.0f );
float flSceneViewZ = dot( vSceneProjPos, g_vDepthFeatherProjToViewZW[0] );
float flSceneViewW = dot( vSceneProjPos, g_vDepthFeatherProjToViewZW[1] );
flSceneViewZ /= flSceneViewW;
// fragment's viewspace Z from its projection space coord. computed in VS
float flSurfViewZ = vProjPos.z;
flFeatheredAlpha = flSurfViewZ - flSceneViewZ;
flFeatheredAlpha = saturate( saturate( vDepthBlendConstants.z * flFeatheredAlpha ) + vDepthBlendConstants.w );
return flFeatheredAlpha;
}
# else
{
return 1.0;
}
# endif
}
float4_color_return_type main( PS_INPUT i ) : COLOR
{
// Sample frames from textures
HALF4 baseTex0 = h4tex2Dsrgb( BaseTextureSampler, i.texCoord0_1.xy );
HALF4 baseTex1;
HALF4 result = baseTex0;
HALF4 vVertexColor;
#if ( PACKED_INTERPOLATOR )
{
vVertexColor.rgba = i.texCoord0_1.zzzw;
}
#else
{
vVertexColor.rgba = i.argbcolor.rgba;
baseTex1 = h4tex2Dsrgb( BaseTextureSampler, i.texCoord0_1.wz );
}
#endif
#if ( COLOR_LERP_PS )
{
vVertexColor.rgb = lerp( g_vColor0.rgb, g_vColor1.rgb, saturate( vVertexColor.r ) );
}
#endif
// Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha)
#if ( ANIMBLEND )
result = lerp( result, baseTex1, (HALF)i.blendfactor0.x );
#endif
#if ( MAXLUMFRAMEBLEND1 )
{
// Blend between animation frames based upon max luminance
HALF lum0 = dot( HALF3(.3, .59, .11), baseTex0.rgb * (1.0h-(HALF)i.blendfactor0.x));
HALF lum1 = dot( HALF3(.3, .59, .11), baseTex1.rgb * (HALF)i.blendfactor0.x);
if ( lum0 > lum1 )
result = baseTex0;
else
result = baseTex1;
}
#elif( EXTRACTGREENALPHA )
{
// Weight Green/Alphas from the two frames for a scalar result
result = dot( baseTex0, (HALF4)i.blendfactor0 ) + dot( baseTex1, (HALF4)i.blendfactor1 );
}
#endif
if ( DISTANCEALPHA )
{
HALF flOrigAlpha = result.a;
if ( SOFTEDGES )
{
result.a = smoothstep( EDGESOFTNESS_END, EDGESOFTNESS_START, result.a );
}
else
{
if ( result.a < 0.5h )
result = 0;
}
if ( OUTLINE )
{
result.rgb *= vVertexColor.rgb; // multiply by vertex color before glow.
if ( ( flOrigAlpha >= OUTLINESTART0 ) && ( flOrigAlpha <= OUTLINEEND1 ) )
{
float oFactor = 1.0f;
if ( flOrigAlpha <= OUTLINESTART1 )
{
oFactor = smoothstep( OUTLINESTART0, OUTLINESTART1, flOrigAlpha );
}
else
{
oFactor = smoothstep( OUTLINEEND1, OUTLINEEND0, flOrigAlpha );
}
result = lerp( result, OUTLINECOLOR, oFactor );
}
}
}
#if ( DUALSEQUENCE )
{
baseTex0 = h4tex2Dsrgb( BaseTextureSampler, i.vSeq2TexCoord0_1.xy );
baseTex1 = h4tex2Dsrgb( BaseTextureSampler, i.vSeq2TexCoord0_1.wz );
// Blend by default (may override with bMaxLumFrameBlend2)
HALF4 rgb2 = lerp( baseTex0, baseTex1, (HALF)i.blendfactor0.z );
#if ( MAXLUMFRAMEBLEND2 )
{
// blend between animation frames based upon max luminance
HALF tlum0 = dot( HALF3(.3, .59, .11), baseTex0.rgb * (1.0h-(HALF)i.blendfactor0.x));
HALF tlum1 = dot( HALF3(.3, .59, .11), baseTex1.rgb * (HALF)i.blendfactor0.x);
if ( tlum0 > tlum1 )
rgb2 = baseTex0;
else
rgb2 = baseTex1;
}
#endif
#if ( SEQUENCE_BLEND_MODE == COMBINE_MODE_AVERAGE )
{
result = 0.5h * ( result + rgb2 );
}
#elif ( SEQUENCE_BLEND_MODE == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND )
{
result.rgb = rgb2.rgb;
}
#elif ( SEQUENCE_BLEND_MODE == COMBINE_MODE_USE_FIRST_OVER_SECOND )
{
result.rgb = lerp( result.rgb, rgb2.rgb, rgb2.a );
}
#endif
}
#endif
// Optional color ramp
#if ( COLORRAMP )
{
result.rgb = h3tex2Dsrgb( ColorRampSampler, float2( result.r, result.g ) ).rgb;
}
#endif
// Overbright
result.rgb *= fOverbrightFactor;
//Soft Particles FTW
#if (DEPTHBLEND == 1)
HALF fDepthBlend = DepthFeatheringFullDepth( DepthSampler, i.vProjPos, g_DepthFeatheringConstants );
#if (INVERSEDEPTHBLEND == 1)
fDepthBlend = 1.0h - fDepthBlend;
#endif
vVertexColor.a *= fDepthBlend;
#endif
// Premultiply the alpha for a ONE:INVALPHA blend
#if ( ADDBASETEXTURE2 )
{
result.a *= vVertexColor.a;
// In this case, we don't really want to pre-multiply by alpha
#if ( !COLORRAMP )
{
result.rgb *= result.a;
}
#endif
#if ( EXTRACTGREENALPHA )
{
result.rgb += fAdditiveBlendWeight * vVertexColor.a * result.rgb;
}
#else
{
result.rgb += fOverbrightFactor * fAdditiveBlendWeight * vVertexColor.a * h3tex2Dsrgb( BaseTextureSampler, i.texCoord2 ).rgb;
}
#endif
result.rgb *= vVertexColor.rgb;
}
#else
{
#if ADDSELF
{
result.a *= vVertexColor.a;
result.rgb *= result.a;
result.rgb += fAdditiveSelfBlendWeight * result.rgb;
result.rgb *= vVertexColor.rgb;
}
#else
{
#if ( MOD2X )
{
result.rgb = lerp( (HALF3)g_flMod2xIdentity, result.rgb, vVertexColor.rgb );
result.a *= vVertexColor.a;
}
#else
{
if ( ! OUTLINE )
{
result *= vVertexColor; // if outlined, we've already done this. don't want to mul glow by particle color.
}
else
{
result.a *= vVertexColor.a;
}
}
#endif
}
#endif
}
#endif
float4_color_return_type vOutput;
#if ( MOD2X )
{
// Blend towards a unity multiply as alpha gets closer to zero
result.rgb = lerp( ( HALF3 )g_flMod2xIdentity, result.rgb, result.a );
// Don't tonemap scale since we are multiplying by what is already in the framebuffer.
vOutput = FinalOutputHalf( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
}
#else
{
vOutput = FinalOutputHalf( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR );
#if defined( _X360 ) && defined( CSTRIKE15 )
// TEMPORARY - fix up properly after PAX
// undo the linear to gamma that would have been done in FinalOutput as we have other colour ops to perform
vOutput.rgb = GammaToLinear( vOutput.rgb );
#endif
}
#endif
vOutput = saturate( vOutput );
// Purposely multiplying after saturating.
vOutput.rgb *= fIntensity;
#if ( MULOUTPUTBYALPHA )
{
// Do the final alpha multiply in the shader to avoid alpha blender unit precision problems. (This should only be enabled when we would normally
// do SRC_RGB*SRC_ALPHA+DST_RGB blending.)
vOutput.rgb *= vOutput.a;
vOutput.a = 1.0h;
}
#endif
#if ( MOD2X )
{
}
#else
{
#if defined( _X360 ) && defined( CSTRIKE15 )
// [mariod] - srgb write required in this shader - after FinalOutput due to other ops - Final output will skip since TONEMAP_SCALE is NONE
vOutput.rgb = LinearToGamma( vOutput.rgb );
//vOutput.rgb = SrgbLinearToGamma( vOutput.rgb );
#endif
}
#endif
return vOutput;
}