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.
535 lines
19 KiB
535 lines
19 KiB
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
|
|
|
|
// STATIC: "PHONG" "0..1"
|
|
// STATIC: "PHONGEXPONENTTEXTURE" "0..1"
|
|
// STATIC: "CUBEMAP" "0..1"
|
|
// STATIC: "DECALSTYLE" "0..5"
|
|
// STATIC: "THIRDPERSON" "0..1"
|
|
// STATIC: "CASCADED_SHADOW_MAPPING" "0..1" [ps30]
|
|
// STATIC: "ALPHAMASK" "0..1" [ps30]
|
|
// STATIC: "DESATBASETINT" "0..1"
|
|
|
|
// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20]
|
|
// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] [ps30]
|
|
// DYNAMIC: "DYN_CSM_ENABLED" "0..1"
|
|
// DYNAMIC: "HIGHLIGHT" "0..1" [ps20] [ps20b]
|
|
// DYNAMIC: "HIGHLIGHT" "0..2" [ps30]
|
|
// DYNAMIC: "PEEL" "0..1"
|
|
|
|
// SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $DYN_CSM_ENABLED == 1 )
|
|
// SKIP: ( $HIGHLIGHT == 1 ) [ps30]
|
|
// SKIP: ( $HIGHLIGHT > 0 ) && ( $THIRDPERSON == 1 )
|
|
// SKIP: ( $HIGHLIGHT > 0 ) && ( $PEEL == 1 )
|
|
// SKIP: ( $PEEL == 1 ) && ( $THIRDPERSON == 1 )
|
|
// SKIP: ( $ALPHAMASK == 1 ) && ( $THIRDPERSON == 1 )
|
|
// SKIP: ( $ALPHAMASK == 1 ) && ( $HIGHLIGHT == 1 )
|
|
// SKIP: ( $ALPHAMASK == 1 ) && ( $PEEL == 1 )
|
|
|
|
#include "common_ps_fxc.h"
|
|
//#include "common_vertexlitgeneric_dx9.h"
|
|
#include "shader_constant_register_map.h"
|
|
|
|
|
|
// SAMPLERS
|
|
sampler BaseSampler : register( s0 );
|
|
#if (THIRDPERSON == 0)
|
|
sampler AOSampler : register( s1 );
|
|
#endif
|
|
|
|
#if (PHONGEXPONENTTEXTURE == 1)
|
|
sampler ExpSampler : register( s2 );
|
|
#endif
|
|
|
|
#if (CUBEMAP == 1)
|
|
samplerCUBE EnvmapSampler : register( s3 );
|
|
#endif
|
|
|
|
#if (THIRDPERSON == 0)
|
|
sampler ScratchesSampler : register( s4 );
|
|
sampler GrungeSampler : register( s9 );
|
|
#endif
|
|
|
|
#if (DECALSTYLE == 3)
|
|
sampler HoloSpectrumSampler : register( s6 );
|
|
sampler HoloMaskSampler : register( s7 );
|
|
#endif
|
|
|
|
#if ( (DECALSTYLE == 4) || ( DECALSTYLE==5 ) )
|
|
sampler NormalMapSampler : register( s6 );
|
|
#endif
|
|
|
|
#if ( DECALSTYLE == 5 )
|
|
sampler AnisoDirSampler : register( s8 );
|
|
#endif
|
|
|
|
sampler NormalizeSampler : register( s5 );
|
|
|
|
#if ( CASCADED_SHADOW_MAPPING == 1 )
|
|
sampler CSMDepthAtlasSampler : register( s15 );
|
|
#define CASCADE_SIZE 3
|
|
#define CSM_ENABLED 1
|
|
#include "csm_common_fxc.h"
|
|
#endif
|
|
|
|
// REGISTERS
|
|
const float4 g_fvConstRegister0 : register( c0 );
|
|
#define g_flWearAmt g_fvConstRegister0.x
|
|
#define g_flWearWidth g_fvConstRegister0.y
|
|
#define g_flWearRemapped g_fvConstRegister0.z
|
|
#define g_flUnWearStrength g_fvConstRegister0.w
|
|
|
|
const float4 g_fvConstRegister1 : register( c1 );
|
|
#define g_flPhongExponent g_fvConstRegister1.x
|
|
#define g_flPhongBoost g_fvConstRegister1.y
|
|
#define g_flPhongAlbedoBoost g_fvConstRegister1.z
|
|
#define g_flGrungeScale g_fvConstRegister1.w
|
|
|
|
const float4 g_fvConstRegister2 : register( c2 );
|
|
#define g_fvPhongFresnelRanges g_fvConstRegister2.xyz
|
|
#define g_bPhongAlbedoTint g_fvConstRegister2.w
|
|
|
|
const float4 g_fvConstRegister3 : register( c3 );
|
|
#define g_fvEnvmapTint g_fvConstRegister3.xyz
|
|
|
|
const float4 g_fvConstRegister10 : register( c10 );
|
|
#define g_fvColorTint g_fvConstRegister10.xyz
|
|
|
|
const float4 g_fvConstRegister13 : register( c13 );
|
|
|
|
#if (DECALSTYLE == 2)
|
|
const float4 g_fvConstRegister11 : register( c11 );
|
|
#define g_fvColorTint2 g_fvConstRegister11.xyz
|
|
#define g_fvColorTint3 float3( g_fvConstRegister3.w, g_fvConstRegister10.w, g_fvConstRegister11.w )
|
|
#define g_fvColorTint4 g_fvConstRegister13.xyz
|
|
#endif
|
|
|
|
#define g_flTintLerpBase g_fvConstRegister13.w
|
|
|
|
#if (HIGHLIGHT > 0)
|
|
#define TAU 6.28318
|
|
#define ONE_OVER_SIXTEEN 0.0625
|
|
#define CSTRIKE_BLUE float3( 0.204, 0.266, 0.343 )
|
|
#endif
|
|
|
|
#if (HIGHLIGHT > 0) || (PEEL == 1)
|
|
const float4 g_fvConstRegister14 : register( c14 );
|
|
#define g_flHighlightAmount g_fvConstRegister14.x
|
|
#define g_flHighlightCycle g_fvConstRegister14.y
|
|
#endif
|
|
|
|
const float4 g_EyePos_unused : register( c12 );
|
|
#define g_EyePos g_EyePos_unused.xyz
|
|
|
|
const float3 g_cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); // 4 through 9
|
|
PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 20 through 25
|
|
|
|
#define g_flScratchwidth 0.02f
|
|
|
|
struct PS_INPUT
|
|
{
|
|
float4 vBaseUV_PatternUV : TEXCOORD0;
|
|
//float4 vWearUV_GrungeUV : TEXCOORD1;
|
|
float4 lightAtten : TEXCOORD2;
|
|
float3 worldPos : TEXCOORD3;
|
|
#if ( ( DECALSTYLE == 4 ) || ( DECALSTYLE == 5) )
|
|
float3x3 tangentSpaceTranspose : TEXCOORD4;
|
|
// second row : TEXCOORD5;
|
|
// third row : TEXCOORD6;
|
|
#else
|
|
float3 vWorldNormal : TEXCOORD4;
|
|
#endif
|
|
};
|
|
|
|
void PixelShaderDoAnisotropicSpecularLight( const float3 vWorldNormal, const float3 vWorldTangentS, const float3 vWorldTangentT,
|
|
const float fSpecularExponent, const float3 vEyeDir,
|
|
const float fAtten, const float3 vLightColor, const float3 vLightDir,
|
|
const float2 vAnisoDir,
|
|
|
|
// Outputs
|
|
out float3 specularLighting )
|
|
{
|
|
float3 vTangent = vAnisoDir.x * vWorldTangentS + vAnisoDir.y * vWorldTangentT;
|
|
|
|
float cs = -dot( vEyeDir, vTangent );
|
|
float sn = sqrt( 1 - cs * cs );
|
|
float cl = -dot( vLightDir, vTangent );
|
|
float sl = sqrt( 1 - cl * cl );
|
|
specularLighting = pow( saturate(cs * cl + sn * sl), fSpecularExponent );
|
|
|
|
specularLighting *= pow( saturate( dot( vWorldNormal, vLightDir ) ), 0.5 ); // Mask with N.L raised to a power
|
|
specularLighting *= vLightColor * fAtten; // Modulate with light color
|
|
}
|
|
|
|
void PixelShaderDoAnisotropicSpecularLighting( const float3 worldPos, const float3 worldNormal, const float3 worldTangentS, const float3 worldTangentT,
|
|
const float fSpecularExponent, const float3 vEyeDir,
|
|
const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], float fFresnel,
|
|
const float2 anisoDir, const float flDirectShadow,
|
|
|
|
// Outputs
|
|
out float3 specularLighting )
|
|
{
|
|
specularLighting = float3( 0.0f, 0.0f, 0.0f );
|
|
float3 localSpecularTerm;
|
|
|
|
if( nNumLights > 0 )
|
|
{
|
|
// First local light will always be forced to a directional light in CS:GO (see CanonicalizeMaterialLightingState() in shaderapidx8.cpp) - it may be completely black.
|
|
PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
|
|
PixelShaderGetLightColor( cLightInfo, 0 ),
|
|
PixelShaderGetLightVector( worldPos, cLightInfo, 0 ),
|
|
anisoDir, localSpecularTerm );
|
|
|
|
specularLighting += localSpecularTerm * flDirectShadow; // Accumulate specular and rim terms
|
|
}
|
|
|
|
if( nNumLights > 1 )
|
|
{
|
|
PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
|
|
PixelShaderGetLightColor( cLightInfo, 1 ),
|
|
PixelShaderGetLightVector( worldPos, cLightInfo, 1 ),
|
|
anisoDir, localSpecularTerm );
|
|
|
|
specularLighting += localSpecularTerm; // Accumulate specular and rim terms
|
|
}
|
|
|
|
|
|
if( nNumLights > 2 )
|
|
{
|
|
PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
|
|
PixelShaderGetLightColor( cLightInfo, 2 ),
|
|
PixelShaderGetLightVector( worldPos, cLightInfo, 2 ),
|
|
anisoDir, localSpecularTerm );
|
|
|
|
specularLighting += localSpecularTerm; // Accumulate specular and rim terms
|
|
}
|
|
|
|
if( nNumLights > 3 )
|
|
{
|
|
PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
|
|
PixelShaderGetLightColor( cLightInfo, 3 ),
|
|
PixelShaderGetLightVector( worldPos, cLightInfo, 3 ),
|
|
anisoDir, localSpecularTerm );
|
|
|
|
specularLighting += localSpecularTerm; // Accumulate specular and rim terms
|
|
}
|
|
|
|
specularLighting *= fFresnel;
|
|
|
|
}
|
|
|
|
#if ( DESATBASETINT == 1 )
|
|
static const float3 g_desat = { 0.299, 0.587, 0.114 };
|
|
#endif
|
|
|
|
float4_color_return_type main( PS_INPUT i ) : COLOR
|
|
{
|
|
|
|
#if defined( _X360 ) || defined( _PS3 )
|
|
float4 cOut = float4( 0.0f, 0.0f, 0.0f, 1.0f );
|
|
#else
|
|
|
|
float4 cOut = tex2D( BaseSampler, i.vBaseUV_PatternUV.zw );
|
|
|
|
#if ( DESATBASETINT == 1 )
|
|
cOut.rgb = lerp( dot(g_desat.rgb, cOut.rgb).xxx, cOut.rgb, g_flTintLerpBase );
|
|
#endif
|
|
|
|
#if ( ALPHAMASK == 1 )
|
|
cOut.a = step( 0.1f, cOut.a );
|
|
cOut.rgb = cOut.a;
|
|
cOut.a = 1;
|
|
return cOut;
|
|
#endif
|
|
|
|
#if ( THIRDPERSON == 1 )
|
|
//clip off any pixels outside 0-1 UV space to prevent smearing edge pixels on lower mips
|
|
clip( (saturate( i.vBaseUV_PatternUV.z ) != i.vBaseUV_PatternUV.z) ? -1 : 1 );
|
|
clip( (saturate( i.vBaseUV_PatternUV.w ) != i.vBaseUV_PatternUV.w) ? -1 : 1 );
|
|
#endif
|
|
|
|
//alpha values above 0.1 locally decrease wear to retain important areas of the sticker
|
|
float flUnWearImportance = g_flUnWearStrength * ( 1.0f - cOut.a );
|
|
|
|
//semi-on/off alpha
|
|
cOut.a = step( 0.1f, cOut.a );
|
|
#if (HIGHLIGHT == 0) && (PEEL == 0)
|
|
clip( cOut.a - 0.001f );
|
|
#endif
|
|
|
|
#if (DECALSTYLE != 2) // non-color-replace logos can still be color tinted by the first color tint value
|
|
|
|
#if (DESATBASETINT == 1)
|
|
cOut.rgb = lerp( cOut.rgb * g_fvColorTint, cOut.rgb, cOut.g * g_flTintLerpBase );
|
|
#else
|
|
cOut.rgb *= g_fvColorTint;
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if (PHONG == 1)
|
|
// default to numerically defined specular values
|
|
float4 fvSpecularExponent = float4( g_flPhongExponent, g_bPhongAlbedoTint, 0.0f, 1.0f );
|
|
#if (PHONGEXPONENTTEXTURE == 1)
|
|
// override the existing specular exponent values with values from the exponent map
|
|
fvSpecularExponent.xy = tex2D( ExpSampler, i.vBaseUV_PatternUV.xy ).xy;
|
|
#endif
|
|
#endif
|
|
|
|
float3 vWorldPos = i.worldPos;
|
|
float3 vEyeDir = normalize( g_EyePos - vWorldPos );
|
|
|
|
#if ( (DECALSTYLE == 4) || ( DECALSTYLE == 5 ) )// foil emboss uses normal map
|
|
float4 vNormalTexel = tex2D( NormalMapSampler, i.vBaseUV_PatternUV.zw );
|
|
float3 vTangentSpaceNormal = 2.0f * vNormalTexel.xyz - 1.0f;
|
|
float3 vWorldNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentSpaceNormal ) );
|
|
#if ( DECALSTYLE == 5)
|
|
// flatten the normal for anisotropic spec to reduce aliasing
|
|
float3 vSpecNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, lerp( vTangentSpaceNormal, float3( 0.0f, 0.0f, 1.0f ), 0.95f ) ) );
|
|
#endif
|
|
#else
|
|
float3 vWorldNormal = normalize ( i.vWorldNormal.xyz );
|
|
#endif
|
|
|
|
#if (DECALSTYLE == 2) // color-replace logo
|
|
cOut.rgb = lerp( lerp( lerp( g_fvColorTint, g_fvColorTint2, cOut.r ), g_fvColorTint3, cOut.g ), g_fvColorTint4, cOut.b );
|
|
#endif
|
|
|
|
#if (DECALSTYLE == 3) // hologram
|
|
float3 fvHoloMask = tex2D( HoloMaskSampler, i.vBaseUV_PatternUV.zw ).rgb;
|
|
|
|
#if (NUM_LIGHTS > 0)
|
|
float2 fvSpectrumUV = float2( fvHoloMask.g + dot( vEyeDir, vWorldNormal ), fvHoloMask.b );
|
|
float3 fvlightdir0 = normalize(cLightInfo[0].pos.xyz - vWorldPos);
|
|
fvSpectrumUV.x += dot( vEyeDir, fvlightdir0 );
|
|
#else
|
|
float2 fvSpectrumUV = float2( fvHoloMask.g + dot( vEyeDir + vWorldNormal, float3( 0, 1, 0 ) ), fvHoloMask.b );
|
|
#endif
|
|
|
|
float3 fvHoloSpectrumSrc = tex2D( HoloSpectrumSampler, fvSpectrumUV ).rgb;
|
|
cOut.rgb = lerp( cOut.rgb, fvHoloSpectrumSrc, fvHoloMask.r );
|
|
#endif
|
|
|
|
// lighting
|
|
#if ( (CASCADED_SHADOW_MAPPING == 1) && (DYN_CSM_ENABLED == 1) )
|
|
float flCSMShadow = CSMComputeShadowing( vWorldPos );
|
|
#else
|
|
float flCSMShadow = 1.0f;
|
|
#endif
|
|
|
|
float3 linearColor = PixelShaderDoLighting( vWorldPos, vWorldNormal, float3( 0.1f, 0.1f, 0.1f), false, true, i.lightAtten, g_cAmbientCube, NormalizeSampler, NUM_LIGHTS, cLightInfo, false, false, NULL, flCSMShadow );
|
|
|
|
#if (CUBEMAP == 1)
|
|
float3 vReflect = CalcReflectionVectorUnnormalized( vWorldNormal, vEyeDir );
|
|
float3 envMapColor = ENV_MAP_SCALE * texCUBE( EnvmapSampler, vReflect ).rgb * g_fvEnvmapTint;
|
|
// TODO: envmap fresnel
|
|
#if (DECALSTYLE == 4)
|
|
envMapColor *= cOut.rgb * linearColor.rgb;
|
|
#endif
|
|
#endif
|
|
|
|
#if (PHONG == 1)
|
|
float3 specularLighting, rimLighting;
|
|
float fFresnelRanges = Fresnel( vWorldNormal, vEyeDir, g_fvPhongFresnelRanges );
|
|
#if ( DECALSTYLE == 5)
|
|
float3 vTangentS = float3( i.tangentSpaceTranspose[0][0], i.tangentSpaceTranspose[1][0], i.tangentSpaceTranspose[2][0] );
|
|
vTangentS = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentS ) );
|
|
float3 vTangentT = float3( i.tangentSpaceTranspose[0][1], i.tangentSpaceTranspose[1][1], i.tangentSpaceTranspose[2][1] );
|
|
vTangentT = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentT ) );
|
|
|
|
vTangentS = normalize( cross( vSpecNormal, vTangentT ) );
|
|
vTangentT = normalize( cross( vSpecNormal, vTangentS ) );
|
|
|
|
float4 vAnisoDirSample = tex2D( AnisoDirSampler, i.vBaseUV_PatternUV.zw );
|
|
float2 vAnisoDir = vAnisoDirSample.yx * 2.0f - 1.0f;
|
|
|
|
PixelShaderDoAnisotropicSpecularLighting( vWorldPos, vWorldNormal, vTangentS, vTangentT, fvSpecularExponent.r * 255.0f, vEyeDir, i.lightAtten, NUM_LIGHTS, cLightInfo, fFresnelRanges, vAnisoDir, 1.0f, specularLighting );
|
|
|
|
rimLighting = 0.0f;
|
|
|
|
specularLighting *= vAnisoDirSample.a;
|
|
#else
|
|
PixelShaderDoSpecularLighting( vWorldPos, vWorldNormal, fvSpecularExponent.r * 255.0f, vEyeDir, i.lightAtten, NUM_LIGHTS, cLightInfo, false, NULL, fFresnelRanges, false, 1.0f, 1.0f, specularLighting, rimLighting );
|
|
#endif
|
|
|
|
specularLighting *= max( g_flPhongBoost.xxx, fvSpecularExponent.g * g_flPhongAlbedoBoost ) * cOut.rgb ;
|
|
//specularLighting *= lerp( g_flPhongBoost.xxx, g_flPhongAlbedoBoost * cOut.rgb, fvSpecularExponent.g );
|
|
//specularLighting *= g_flPhongBoost;
|
|
|
|
#if ( DECALSTYLE != 5 )
|
|
specularLighting *= cOut.a * fFresnelRanges; // specular mask
|
|
#endif
|
|
#endif
|
|
|
|
#if ( THIRDPERSON == 0 )
|
|
|
|
//sample ao
|
|
float4 fvAOSrc = tex2D( AOSampler, i.vBaseUV_PatternUV.xy );
|
|
|
|
//apply scratches and grunge
|
|
|
|
//sample cavity and ao
|
|
float4 fvScratchesSrc = tex2D( ScratchesSampler, i.vBaseUV_PatternUV.xy * 0.5 );
|
|
float4 fvGrungeSrc = tex2D( GrungeSampler, i.vBaseUV_PatternUV.zw * g_flGrungeScale );
|
|
float cavity = 1 - fvAOSrc.r * fvAOSrc.g * fvScratchesSrc.g;
|
|
|
|
//apply uniform grunge
|
|
cOut.rgb = lerp( cOut.rgb, cOut.rgb * fvGrungeSrc.rgb, g_flWearAmt * 0.7 );
|
|
|
|
float flLocalRemappedWear = g_flWearRemapped - flUnWearImportance;
|
|
|
|
float alphaWearPoint = saturate( flLocalRemappedWear - g_flWearWidth );
|
|
|
|
//fast wear vertical threshold
|
|
//float flFastWearThresholdValue = step( g_flFastWearThreshold, i.vBaseUV_PatternUV.w ) * g_flWearAmt * 2.0f;
|
|
//alphaWearPoint += flFastWearThresholdValue;
|
|
//flLocalRemappedWear += flFastWearThresholdValue;
|
|
|
|
#if (DECALSTYLE == 4)
|
|
//foil embossed labels have hard wear edges
|
|
cOut.a *= step( alphaWearPoint + g_flScratchwidth, cavity );
|
|
#else
|
|
cOut.a *= smoothstep( alphaWearPoint - g_flScratchwidth, alphaWearPoint + g_flScratchwidth, cavity );
|
|
#endif
|
|
|
|
#if ( DECALSTYLE == 1 || DECALSTYLE == 3 ) //paper-backed or holographic (which is also paper-backed)
|
|
// wear down color to white paper backing
|
|
float colorWear = smoothstep( flLocalRemappedWear - g_flScratchwidth, flLocalRemappedWear + g_flScratchwidth, cavity );
|
|
cOut.rgb = lerp( fvGrungeSrc.rgb, cOut.rgb, colorWear );
|
|
#endif
|
|
|
|
#if ( ( DECALSTYLE != 4 ) && ( DECALSTYLE != 5 ) ) //foil stickers don't lose their shine
|
|
// wear down spec and envmap
|
|
#if (PHONG == 1 || CUBEMAP == 1)
|
|
float specWearPoint = saturate( flLocalRemappedWear + g_flWearWidth );
|
|
float specWear = smoothstep( specWearPoint - g_flScratchwidth, specWearPoint + g_flScratchwidth, cavity );
|
|
#if (PHONG == 1)
|
|
specularLighting *= specWear;
|
|
#endif
|
|
#if (CUBEMAP == 1)
|
|
envMapColor *= specWear;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#endif //THIRDPERSON == 0
|
|
|
|
#if ( DECALSTYLE == 5 ) // color burn lighting for extra saturation
|
|
cOut.rgb = lerp( cOut.rgb * cOut.rgb * cOut.rgb, cOut.rgb, linearColor );
|
|
#endif
|
|
|
|
#if (PHONG == 1)
|
|
cOut.rgb += specularLighting;
|
|
#endif
|
|
|
|
// apply lighting
|
|
cOut.rgb *= linearColor;
|
|
|
|
#if (CUBEMAP == 1)
|
|
cOut.rgb += envMapColor;
|
|
#endif
|
|
|
|
#if ( THIRDPERSON == 0 )
|
|
//secondary blurred ao
|
|
cOut.rgb *= lerp( 1.0, fvAOSrc.b, g_flWearAmt * 0.35 );
|
|
|
|
//apply AO
|
|
cOut.rgb *= fvAOSrc.g;
|
|
#endif //THIRDPERSON == 0
|
|
|
|
#if ( HIGHLIGHT > 0 )
|
|
// cheap highlighting base pass
|
|
float flModdedCycle = fmod( 0.5f * i.vBaseUV_PatternUV.x + i.vBaseUV_PatternUV.y + g_flHighlightCycle, 1.5f );
|
|
flModdedCycle = smoothstep( 0.2f, 0.6f, abs( flModdedCycle - 0.5f ) );
|
|
|
|
#if (CUBEMAP == 1)
|
|
vReflect.r += flModdedCycle;
|
|
float3 envMapColorSelect = texCUBE( EnvmapSampler, vReflect ).rgb * HDR_INPUT_MAP_SCALE;
|
|
float3 selectionColor = max( 4*envMapColorSelect, CSTRIKE_BLUE );
|
|
#else
|
|
float3 selectionColor = max( 4*cOut, CSTRIKE_BLUE );
|
|
#endif
|
|
|
|
cOut.rgb = lerp( cOut.rgb, selectionColor, flModdedCycle * g_flHighlightAmount );
|
|
|
|
#endif
|
|
|
|
#if ( HIGHLIGHT == 2)
|
|
|
|
//also do expensive edge detection
|
|
float flEdgeAlphaDetect = 0.0f;
|
|
|
|
float2 offsets[16] = {
|
|
float2( 1.0f, 0.0f ),
|
|
float2( 0.9211f, 0.3894f ),
|
|
float2( 0.6967f, 0.7174f ),
|
|
float2( 0.3624f, 0.932f ),
|
|
float2( -0.0292f, 0.9996f ),
|
|
float2( -0.4161f, 0.9093f ),
|
|
float2( -0.7374f, 0.6755f ),
|
|
float2( -0.9422f, 0.335f ),
|
|
float2( -0.9983f, -0.0584f ),
|
|
float2( -0.8968f, -0.4425f ),
|
|
float2( -0.6536f, -0.7568f ),
|
|
float2( -0.3073f, -0.9516f ),
|
|
float2( 0.0875f, -0.9962f ),
|
|
float2( 0.4685f, -0.8835f ),
|
|
float2( 0.7756f, -0.6313f ),
|
|
float2( 0.9602f, -0.2794f ),
|
|
};
|
|
|
|
for ( int k = 0; k < 16; k++ )
|
|
{
|
|
float flAlphaTap = tex2D( BaseSampler, i.vBaseUV_PatternUV.zw + offsets[k] * 0.015f ).a;
|
|
flEdgeAlphaDetect += step( 0.1f, flAlphaTap );
|
|
}
|
|
|
|
flEdgeAlphaDetect = step( abs( (flEdgeAlphaDetect * ONE_OVER_SIXTEEN) - 0.5f ), 0.499f );
|
|
|
|
cOut = lerp( cOut, float4(selectionColor, 1), flEdgeAlphaDetect * g_flHighlightAmount );
|
|
|
|
#endif
|
|
|
|
#if ( PEEL == 1 )
|
|
//sticker peeling application effect in 2D
|
|
float invHighlight = 1.0f - g_flHighlightAmount;
|
|
float distort = pow( (invHighlight - i.vBaseUV_PatternUV.x), 0.3f ) * 0.3f;
|
|
|
|
float2 backingUV = float2(invHighlight + (invHighlight - i.vBaseUV_PatternUV.x), i.vBaseUV_PatternUV.y );
|
|
|
|
//fake vertical parallax
|
|
float flParallaxY = dot( float3(0,0,1), vWorldNormal );
|
|
backingUV.y += (flParallaxY * distort );
|
|
|
|
float4 flBackingSample = tex2D( BaseSampler, backingUV );
|
|
|
|
//desaturate backing sample
|
|
flBackingSample.rgb = dot( flBackingSample.rgb, float3(0.299,0.587,0.114) );
|
|
|
|
distort = smoothstep( 0.01f, 0.2f, distort);
|
|
flBackingSample.rgb = lerp( flBackingSample.rgb, 0.5f, 0.2f ) * distort;
|
|
flBackingSample.a = step( 0.1f, flBackingSample.a );
|
|
|
|
//if ( flBackingSample.a > 0 && i.vBaseUV_PatternUV.x < invHighlight )
|
|
//{
|
|
// cOut.rgb = flBackingSample.rgb;
|
|
// float edgeFade = smoothstep( 0.0f, 0.2f, min( i.vBaseUV_PatternUV.x, i.vBaseUV_PatternUV.y ) );
|
|
// cOut.a = max( cOut.a, edgeFade );
|
|
//}
|
|
//becomes:
|
|
cOut = lerp( cOut,
|
|
float4( flBackingSample.rgb, max( cOut.a, smoothstep( 0.0f, 0.2f, min( i.vBaseUV_PatternUV.x, i.vBaseUV_PatternUV.y ) ) ) ),
|
|
step( i.vBaseUV_PatternUV.x, invHighlight ) * flBackingSample.a );
|
|
|
|
//if ( i.vBaseUV_PatternUV.x > invHighlight )
|
|
//{
|
|
// cOut.rgb = 0;
|
|
// cOut.a *= (1.0f - distort) * 0.8f;
|
|
//}
|
|
//becomes:
|
|
cOut = lerp( cOut, float4( 0, 0, 0, cOut.a * (1.0f - distort) * 0.8f ), step( invHighlight, i.vBaseUV_PatternUV.x ) );
|
|
|
|
#endif
|
|
|
|
#endif
|
|
return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR );
|
|
}
|