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.

535 lines
19 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "PHONG" "0..1"
  3. // STATIC: "PHONGEXPONENTTEXTURE" "0..1"
  4. // STATIC: "CUBEMAP" "0..1"
  5. // STATIC: "DECALSTYLE" "0..5"
  6. // STATIC: "THIRDPERSON" "0..1"
  7. // STATIC: "CASCADED_SHADOW_MAPPING" "0..1" [ps30]
  8. // STATIC: "ALPHAMASK" "0..1" [ps30]
  9. // STATIC: "DESATBASETINT" "0..1"
  10. // DYNAMIC: "NUM_LIGHTS" "0..2" [ps20]
  11. // DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] [ps30]
  12. // DYNAMIC: "DYN_CSM_ENABLED" "0..1"
  13. // DYNAMIC: "HIGHLIGHT" "0..1" [ps20] [ps20b]
  14. // DYNAMIC: "HIGHLIGHT" "0..2" [ps30]
  15. // DYNAMIC: "PEEL" "0..1"
  16. // SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $DYN_CSM_ENABLED == 1 )
  17. // SKIP: ( $HIGHLIGHT == 1 ) [ps30]
  18. // SKIP: ( $HIGHLIGHT > 0 ) && ( $THIRDPERSON == 1 )
  19. // SKIP: ( $HIGHLIGHT > 0 ) && ( $PEEL == 1 )
  20. // SKIP: ( $PEEL == 1 ) && ( $THIRDPERSON == 1 )
  21. // SKIP: ( $ALPHAMASK == 1 ) && ( $THIRDPERSON == 1 )
  22. // SKIP: ( $ALPHAMASK == 1 ) && ( $HIGHLIGHT == 1 )
  23. // SKIP: ( $ALPHAMASK == 1 ) && ( $PEEL == 1 )
  24. #include "common_ps_fxc.h"
  25. //#include "common_vertexlitgeneric_dx9.h"
  26. #include "shader_constant_register_map.h"
  27. // SAMPLERS
  28. sampler BaseSampler : register( s0 );
  29. #if (THIRDPERSON == 0)
  30. sampler AOSampler : register( s1 );
  31. #endif
  32. #if (PHONGEXPONENTTEXTURE == 1)
  33. sampler ExpSampler : register( s2 );
  34. #endif
  35. #if (CUBEMAP == 1)
  36. samplerCUBE EnvmapSampler : register( s3 );
  37. #endif
  38. #if (THIRDPERSON == 0)
  39. sampler ScratchesSampler : register( s4 );
  40. sampler GrungeSampler : register( s9 );
  41. #endif
  42. #if (DECALSTYLE == 3)
  43. sampler HoloSpectrumSampler : register( s6 );
  44. sampler HoloMaskSampler : register( s7 );
  45. #endif
  46. #if ( (DECALSTYLE == 4) || ( DECALSTYLE==5 ) )
  47. sampler NormalMapSampler : register( s6 );
  48. #endif
  49. #if ( DECALSTYLE == 5 )
  50. sampler AnisoDirSampler : register( s8 );
  51. #endif
  52. sampler NormalizeSampler : register( s5 );
  53. #if ( CASCADED_SHADOW_MAPPING == 1 )
  54. sampler CSMDepthAtlasSampler : register( s15 );
  55. #define CASCADE_SIZE 3
  56. #define CSM_ENABLED 1
  57. #include "csm_common_fxc.h"
  58. #endif
  59. // REGISTERS
  60. const float4 g_fvConstRegister0 : register( c0 );
  61. #define g_flWearAmt g_fvConstRegister0.x
  62. #define g_flWearWidth g_fvConstRegister0.y
  63. #define g_flWearRemapped g_fvConstRegister0.z
  64. #define g_flUnWearStrength g_fvConstRegister0.w
  65. const float4 g_fvConstRegister1 : register( c1 );
  66. #define g_flPhongExponent g_fvConstRegister1.x
  67. #define g_flPhongBoost g_fvConstRegister1.y
  68. #define g_flPhongAlbedoBoost g_fvConstRegister1.z
  69. #define g_flGrungeScale g_fvConstRegister1.w
  70. const float4 g_fvConstRegister2 : register( c2 );
  71. #define g_fvPhongFresnelRanges g_fvConstRegister2.xyz
  72. #define g_bPhongAlbedoTint g_fvConstRegister2.w
  73. const float4 g_fvConstRegister3 : register( c3 );
  74. #define g_fvEnvmapTint g_fvConstRegister3.xyz
  75. const float4 g_fvConstRegister10 : register( c10 );
  76. #define g_fvColorTint g_fvConstRegister10.xyz
  77. const float4 g_fvConstRegister13 : register( c13 );
  78. #if (DECALSTYLE == 2)
  79. const float4 g_fvConstRegister11 : register( c11 );
  80. #define g_fvColorTint2 g_fvConstRegister11.xyz
  81. #define g_fvColorTint3 float3( g_fvConstRegister3.w, g_fvConstRegister10.w, g_fvConstRegister11.w )
  82. #define g_fvColorTint4 g_fvConstRegister13.xyz
  83. #endif
  84. #define g_flTintLerpBase g_fvConstRegister13.w
  85. #if (HIGHLIGHT > 0)
  86. #define TAU 6.28318
  87. #define ONE_OVER_SIXTEEN 0.0625
  88. #define CSTRIKE_BLUE float3( 0.204, 0.266, 0.343 )
  89. #endif
  90. #if (HIGHLIGHT > 0) || (PEEL == 1)
  91. const float4 g_fvConstRegister14 : register( c14 );
  92. #define g_flHighlightAmount g_fvConstRegister14.x
  93. #define g_flHighlightCycle g_fvConstRegister14.y
  94. #endif
  95. const float4 g_EyePos_unused : register( c12 );
  96. #define g_EyePos g_EyePos_unused.xyz
  97. const float3 g_cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); // 4 through 9
  98. PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 20 through 25
  99. #define g_flScratchwidth 0.02f
  100. struct PS_INPUT
  101. {
  102. float4 vBaseUV_PatternUV : TEXCOORD0;
  103. //float4 vWearUV_GrungeUV : TEXCOORD1;
  104. float4 lightAtten : TEXCOORD2;
  105. float3 worldPos : TEXCOORD3;
  106. #if ( ( DECALSTYLE == 4 ) || ( DECALSTYLE == 5) )
  107. float3x3 tangentSpaceTranspose : TEXCOORD4;
  108. // second row : TEXCOORD5;
  109. // third row : TEXCOORD6;
  110. #else
  111. float3 vWorldNormal : TEXCOORD4;
  112. #endif
  113. };
  114. void PixelShaderDoAnisotropicSpecularLight( const float3 vWorldNormal, const float3 vWorldTangentS, const float3 vWorldTangentT,
  115. const float fSpecularExponent, const float3 vEyeDir,
  116. const float fAtten, const float3 vLightColor, const float3 vLightDir,
  117. const float2 vAnisoDir,
  118. // Outputs
  119. out float3 specularLighting )
  120. {
  121. float3 vTangent = vAnisoDir.x * vWorldTangentS + vAnisoDir.y * vWorldTangentT;
  122. float cs = -dot( vEyeDir, vTangent );
  123. float sn = sqrt( 1 - cs * cs );
  124. float cl = -dot( vLightDir, vTangent );
  125. float sl = sqrt( 1 - cl * cl );
  126. specularLighting = pow( saturate(cs * cl + sn * sl), fSpecularExponent );
  127. specularLighting *= pow( saturate( dot( vWorldNormal, vLightDir ) ), 0.5 ); // Mask with N.L raised to a power
  128. specularLighting *= vLightColor * fAtten; // Modulate with light color
  129. }
  130. void PixelShaderDoAnisotropicSpecularLighting( const float3 worldPos, const float3 worldNormal, const float3 worldTangentS, const float3 worldTangentT,
  131. const float fSpecularExponent, const float3 vEyeDir,
  132. const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], float fFresnel,
  133. const float2 anisoDir, const float flDirectShadow,
  134. // Outputs
  135. out float3 specularLighting )
  136. {
  137. specularLighting = float3( 0.0f, 0.0f, 0.0f );
  138. float3 localSpecularTerm;
  139. if( nNumLights > 0 )
  140. {
  141. // First local light will always be forced to a directional light in CS:GO (see CanonicalizeMaterialLightingState() in shaderapidx8.cpp) - it may be completely black.
  142. PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
  143. PixelShaderGetLightColor( cLightInfo, 0 ),
  144. PixelShaderGetLightVector( worldPos, cLightInfo, 0 ),
  145. anisoDir, localSpecularTerm );
  146. specularLighting += localSpecularTerm * flDirectShadow; // Accumulate specular and rim terms
  147. }
  148. if( nNumLights > 1 )
  149. {
  150. PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
  151. PixelShaderGetLightColor( cLightInfo, 1 ),
  152. PixelShaderGetLightVector( worldPos, cLightInfo, 1 ),
  153. anisoDir, localSpecularTerm );
  154. specularLighting += localSpecularTerm; // Accumulate specular and rim terms
  155. }
  156. if( nNumLights > 2 )
  157. {
  158. PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
  159. PixelShaderGetLightColor( cLightInfo, 2 ),
  160. PixelShaderGetLightVector( worldPos, cLightInfo, 2 ),
  161. anisoDir, localSpecularTerm );
  162. specularLighting += localSpecularTerm; // Accumulate specular and rim terms
  163. }
  164. if( nNumLights > 3 )
  165. {
  166. PixelShaderDoAnisotropicSpecularLight( worldNormal, worldTangentS, worldTangentT, fSpecularExponent, vEyeDir, lightAtten,
  167. PixelShaderGetLightColor( cLightInfo, 3 ),
  168. PixelShaderGetLightVector( worldPos, cLightInfo, 3 ),
  169. anisoDir, localSpecularTerm );
  170. specularLighting += localSpecularTerm; // Accumulate specular and rim terms
  171. }
  172. specularLighting *= fFresnel;
  173. }
  174. #if ( DESATBASETINT == 1 )
  175. static const float3 g_desat = { 0.299, 0.587, 0.114 };
  176. #endif
  177. float4_color_return_type main( PS_INPUT i ) : COLOR
  178. {
  179. #if defined( _X360 ) || defined( _PS3 )
  180. float4 cOut = float4( 0.0f, 0.0f, 0.0f, 1.0f );
  181. #else
  182. float4 cOut = tex2D( BaseSampler, i.vBaseUV_PatternUV.zw );
  183. #if ( DESATBASETINT == 1 )
  184. cOut.rgb = lerp( dot(g_desat.rgb, cOut.rgb).xxx, cOut.rgb, g_flTintLerpBase );
  185. #endif
  186. #if ( ALPHAMASK == 1 )
  187. cOut.a = step( 0.1f, cOut.a );
  188. cOut.rgb = cOut.a;
  189. cOut.a = 1;
  190. return cOut;
  191. #endif
  192. #if ( THIRDPERSON == 1 )
  193. //clip off any pixels outside 0-1 UV space to prevent smearing edge pixels on lower mips
  194. clip( (saturate( i.vBaseUV_PatternUV.z ) != i.vBaseUV_PatternUV.z) ? -1 : 1 );
  195. clip( (saturate( i.vBaseUV_PatternUV.w ) != i.vBaseUV_PatternUV.w) ? -1 : 1 );
  196. #endif
  197. //alpha values above 0.1 locally decrease wear to retain important areas of the sticker
  198. float flUnWearImportance = g_flUnWearStrength * ( 1.0f - cOut.a );
  199. //semi-on/off alpha
  200. cOut.a = step( 0.1f, cOut.a );
  201. #if (HIGHLIGHT == 0) && (PEEL == 0)
  202. clip( cOut.a - 0.001f );
  203. #endif
  204. #if (DECALSTYLE != 2) // non-color-replace logos can still be color tinted by the first color tint value
  205. #if (DESATBASETINT == 1)
  206. cOut.rgb = lerp( cOut.rgb * g_fvColorTint, cOut.rgb, cOut.g * g_flTintLerpBase );
  207. #else
  208. cOut.rgb *= g_fvColorTint;
  209. #endif
  210. #endif
  211. #if (PHONG == 1)
  212. // default to numerically defined specular values
  213. float4 fvSpecularExponent = float4( g_flPhongExponent, g_bPhongAlbedoTint, 0.0f, 1.0f );
  214. #if (PHONGEXPONENTTEXTURE == 1)
  215. // override the existing specular exponent values with values from the exponent map
  216. fvSpecularExponent.xy = tex2D( ExpSampler, i.vBaseUV_PatternUV.xy ).xy;
  217. #endif
  218. #endif
  219. float3 vWorldPos = i.worldPos;
  220. float3 vEyeDir = normalize( g_EyePos - vWorldPos );
  221. #if ( (DECALSTYLE == 4) || ( DECALSTYLE == 5 ) )// foil emboss uses normal map
  222. float4 vNormalTexel = tex2D( NormalMapSampler, i.vBaseUV_PatternUV.zw );
  223. float3 vTangentSpaceNormal = 2.0f * vNormalTexel.xyz - 1.0f;
  224. float3 vWorldNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentSpaceNormal ) );
  225. #if ( DECALSTYLE == 5)
  226. // flatten the normal for anisotropic spec to reduce aliasing
  227. float3 vSpecNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, lerp( vTangentSpaceNormal, float3( 0.0f, 0.0f, 1.0f ), 0.95f ) ) );
  228. #endif
  229. #else
  230. float3 vWorldNormal = normalize ( i.vWorldNormal.xyz );
  231. #endif
  232. #if (DECALSTYLE == 2) // color-replace logo
  233. cOut.rgb = lerp( lerp( lerp( g_fvColorTint, g_fvColorTint2, cOut.r ), g_fvColorTint3, cOut.g ), g_fvColorTint4, cOut.b );
  234. #endif
  235. #if (DECALSTYLE == 3) // hologram
  236. float3 fvHoloMask = tex2D( HoloMaskSampler, i.vBaseUV_PatternUV.zw ).rgb;
  237. #if (NUM_LIGHTS > 0)
  238. float2 fvSpectrumUV = float2( fvHoloMask.g + dot( vEyeDir, vWorldNormal ), fvHoloMask.b );
  239. float3 fvlightdir0 = normalize(cLightInfo[0].pos.xyz - vWorldPos);
  240. fvSpectrumUV.x += dot( vEyeDir, fvlightdir0 );
  241. #else
  242. float2 fvSpectrumUV = float2( fvHoloMask.g + dot( vEyeDir + vWorldNormal, float3( 0, 1, 0 ) ), fvHoloMask.b );
  243. #endif
  244. float3 fvHoloSpectrumSrc = tex2D( HoloSpectrumSampler, fvSpectrumUV ).rgb;
  245. cOut.rgb = lerp( cOut.rgb, fvHoloSpectrumSrc, fvHoloMask.r );
  246. #endif
  247. // lighting
  248. #if ( (CASCADED_SHADOW_MAPPING == 1) && (DYN_CSM_ENABLED == 1) )
  249. float flCSMShadow = CSMComputeShadowing( vWorldPos );
  250. #else
  251. float flCSMShadow = 1.0f;
  252. #endif
  253. 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 );
  254. #if (CUBEMAP == 1)
  255. float3 vReflect = CalcReflectionVectorUnnormalized( vWorldNormal, vEyeDir );
  256. float3 envMapColor = ENV_MAP_SCALE * texCUBE( EnvmapSampler, vReflect ).rgb * g_fvEnvmapTint;
  257. // TODO: envmap fresnel
  258. #if (DECALSTYLE == 4)
  259. envMapColor *= cOut.rgb * linearColor.rgb;
  260. #endif
  261. #endif
  262. #if (PHONG == 1)
  263. float3 specularLighting, rimLighting;
  264. float fFresnelRanges = Fresnel( vWorldNormal, vEyeDir, g_fvPhongFresnelRanges );
  265. #if ( DECALSTYLE == 5)
  266. float3 vTangentS = float3( i.tangentSpaceTranspose[0][0], i.tangentSpaceTranspose[1][0], i.tangentSpaceTranspose[2][0] );
  267. vTangentS = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentS ) );
  268. float3 vTangentT = float3( i.tangentSpaceTranspose[0][1], i.tangentSpaceTranspose[1][1], i.tangentSpaceTranspose[2][1] );
  269. vTangentT = normalize( mul( (float3x3)i.tangentSpaceTranspose, vTangentT ) );
  270. vTangentS = normalize( cross( vSpecNormal, vTangentT ) );
  271. vTangentT = normalize( cross( vSpecNormal, vTangentS ) );
  272. float4 vAnisoDirSample = tex2D( AnisoDirSampler, i.vBaseUV_PatternUV.zw );
  273. float2 vAnisoDir = vAnisoDirSample.yx * 2.0f - 1.0f;
  274. PixelShaderDoAnisotropicSpecularLighting( vWorldPos, vWorldNormal, vTangentS, vTangentT, fvSpecularExponent.r * 255.0f, vEyeDir, i.lightAtten, NUM_LIGHTS, cLightInfo, fFresnelRanges, vAnisoDir, 1.0f, specularLighting );
  275. rimLighting = 0.0f;
  276. specularLighting *= vAnisoDirSample.a;
  277. #else
  278. PixelShaderDoSpecularLighting( vWorldPos, vWorldNormal, fvSpecularExponent.r * 255.0f, vEyeDir, i.lightAtten, NUM_LIGHTS, cLightInfo, false, NULL, fFresnelRanges, false, 1.0f, 1.0f, specularLighting, rimLighting );
  279. #endif
  280. specularLighting *= max( g_flPhongBoost.xxx, fvSpecularExponent.g * g_flPhongAlbedoBoost ) * cOut.rgb ;
  281. //specularLighting *= lerp( g_flPhongBoost.xxx, g_flPhongAlbedoBoost * cOut.rgb, fvSpecularExponent.g );
  282. //specularLighting *= g_flPhongBoost;
  283. #if ( DECALSTYLE != 5 )
  284. specularLighting *= cOut.a * fFresnelRanges; // specular mask
  285. #endif
  286. #endif
  287. #if ( THIRDPERSON == 0 )
  288. //sample ao
  289. float4 fvAOSrc = tex2D( AOSampler, i.vBaseUV_PatternUV.xy );
  290. //apply scratches and grunge
  291. //sample cavity and ao
  292. float4 fvScratchesSrc = tex2D( ScratchesSampler, i.vBaseUV_PatternUV.xy * 0.5 );
  293. float4 fvGrungeSrc = tex2D( GrungeSampler, i.vBaseUV_PatternUV.zw * g_flGrungeScale );
  294. float cavity = 1 - fvAOSrc.r * fvAOSrc.g * fvScratchesSrc.g;
  295. //apply uniform grunge
  296. cOut.rgb = lerp( cOut.rgb, cOut.rgb * fvGrungeSrc.rgb, g_flWearAmt * 0.7 );
  297. float flLocalRemappedWear = g_flWearRemapped - flUnWearImportance;
  298. float alphaWearPoint = saturate( flLocalRemappedWear - g_flWearWidth );
  299. //fast wear vertical threshold
  300. //float flFastWearThresholdValue = step( g_flFastWearThreshold, i.vBaseUV_PatternUV.w ) * g_flWearAmt * 2.0f;
  301. //alphaWearPoint += flFastWearThresholdValue;
  302. //flLocalRemappedWear += flFastWearThresholdValue;
  303. #if (DECALSTYLE == 4)
  304. //foil embossed labels have hard wear edges
  305. cOut.a *= step( alphaWearPoint + g_flScratchwidth, cavity );
  306. #else
  307. cOut.a *= smoothstep( alphaWearPoint - g_flScratchwidth, alphaWearPoint + g_flScratchwidth, cavity );
  308. #endif
  309. #if ( DECALSTYLE == 1 || DECALSTYLE == 3 ) //paper-backed or holographic (which is also paper-backed)
  310. // wear down color to white paper backing
  311. float colorWear = smoothstep( flLocalRemappedWear - g_flScratchwidth, flLocalRemappedWear + g_flScratchwidth, cavity );
  312. cOut.rgb = lerp( fvGrungeSrc.rgb, cOut.rgb, colorWear );
  313. #endif
  314. #if ( ( DECALSTYLE != 4 ) && ( DECALSTYLE != 5 ) ) //foil stickers don't lose their shine
  315. // wear down spec and envmap
  316. #if (PHONG == 1 || CUBEMAP == 1)
  317. float specWearPoint = saturate( flLocalRemappedWear + g_flWearWidth );
  318. float specWear = smoothstep( specWearPoint - g_flScratchwidth, specWearPoint + g_flScratchwidth, cavity );
  319. #if (PHONG == 1)
  320. specularLighting *= specWear;
  321. #endif
  322. #if (CUBEMAP == 1)
  323. envMapColor *= specWear;
  324. #endif
  325. #endif
  326. #endif
  327. #endif //THIRDPERSON == 0
  328. #if ( DECALSTYLE == 5 ) // color burn lighting for extra saturation
  329. cOut.rgb = lerp( cOut.rgb * cOut.rgb * cOut.rgb, cOut.rgb, linearColor );
  330. #endif
  331. #if (PHONG == 1)
  332. cOut.rgb += specularLighting;
  333. #endif
  334. // apply lighting
  335. cOut.rgb *= linearColor;
  336. #if (CUBEMAP == 1)
  337. cOut.rgb += envMapColor;
  338. #endif
  339. #if ( THIRDPERSON == 0 )
  340. //secondary blurred ao
  341. cOut.rgb *= lerp( 1.0, fvAOSrc.b, g_flWearAmt * 0.35 );
  342. //apply AO
  343. cOut.rgb *= fvAOSrc.g;
  344. #endif //THIRDPERSON == 0
  345. #if ( HIGHLIGHT > 0 )
  346. // cheap highlighting base pass
  347. float flModdedCycle = fmod( 0.5f * i.vBaseUV_PatternUV.x + i.vBaseUV_PatternUV.y + g_flHighlightCycle, 1.5f );
  348. flModdedCycle = smoothstep( 0.2f, 0.6f, abs( flModdedCycle - 0.5f ) );
  349. #if (CUBEMAP == 1)
  350. vReflect.r += flModdedCycle;
  351. float3 envMapColorSelect = texCUBE( EnvmapSampler, vReflect ).rgb * HDR_INPUT_MAP_SCALE;
  352. float3 selectionColor = max( 4*envMapColorSelect, CSTRIKE_BLUE );
  353. #else
  354. float3 selectionColor = max( 4*cOut, CSTRIKE_BLUE );
  355. #endif
  356. cOut.rgb = lerp( cOut.rgb, selectionColor, flModdedCycle * g_flHighlightAmount );
  357. #endif
  358. #if ( HIGHLIGHT == 2)
  359. //also do expensive edge detection
  360. float flEdgeAlphaDetect = 0.0f;
  361. float2 offsets[16] = {
  362. float2( 1.0f, 0.0f ),
  363. float2( 0.9211f, 0.3894f ),
  364. float2( 0.6967f, 0.7174f ),
  365. float2( 0.3624f, 0.932f ),
  366. float2( -0.0292f, 0.9996f ),
  367. float2( -0.4161f, 0.9093f ),
  368. float2( -0.7374f, 0.6755f ),
  369. float2( -0.9422f, 0.335f ),
  370. float2( -0.9983f, -0.0584f ),
  371. float2( -0.8968f, -0.4425f ),
  372. float2( -0.6536f, -0.7568f ),
  373. float2( -0.3073f, -0.9516f ),
  374. float2( 0.0875f, -0.9962f ),
  375. float2( 0.4685f, -0.8835f ),
  376. float2( 0.7756f, -0.6313f ),
  377. float2( 0.9602f, -0.2794f ),
  378. };
  379. for ( int k = 0; k < 16; k++ )
  380. {
  381. float flAlphaTap = tex2D( BaseSampler, i.vBaseUV_PatternUV.zw + offsets[k] * 0.015f ).a;
  382. flEdgeAlphaDetect += step( 0.1f, flAlphaTap );
  383. }
  384. flEdgeAlphaDetect = step( abs( (flEdgeAlphaDetect * ONE_OVER_SIXTEEN) - 0.5f ), 0.499f );
  385. cOut = lerp( cOut, float4(selectionColor, 1), flEdgeAlphaDetect * g_flHighlightAmount );
  386. #endif
  387. #if ( PEEL == 1 )
  388. //sticker peeling application effect in 2D
  389. float invHighlight = 1.0f - g_flHighlightAmount;
  390. float distort = pow( (invHighlight - i.vBaseUV_PatternUV.x), 0.3f ) * 0.3f;
  391. float2 backingUV = float2(invHighlight + (invHighlight - i.vBaseUV_PatternUV.x), i.vBaseUV_PatternUV.y );
  392. //fake vertical parallax
  393. float flParallaxY = dot( float3(0,0,1), vWorldNormal );
  394. backingUV.y += (flParallaxY * distort );
  395. float4 flBackingSample = tex2D( BaseSampler, backingUV );
  396. //desaturate backing sample
  397. flBackingSample.rgb = dot( flBackingSample.rgb, float3(0.299,0.587,0.114) );
  398. distort = smoothstep( 0.01f, 0.2f, distort);
  399. flBackingSample.rgb = lerp( flBackingSample.rgb, 0.5f, 0.2f ) * distort;
  400. flBackingSample.a = step( 0.1f, flBackingSample.a );
  401. //if ( flBackingSample.a > 0 && i.vBaseUV_PatternUV.x < invHighlight )
  402. //{
  403. // cOut.rgb = flBackingSample.rgb;
  404. // float edgeFade = smoothstep( 0.0f, 0.2f, min( i.vBaseUV_PatternUV.x, i.vBaseUV_PatternUV.y ) );
  405. // cOut.a = max( cOut.a, edgeFade );
  406. //}
  407. //becomes:
  408. cOut = lerp( cOut,
  409. float4( flBackingSample.rgb, max( cOut.a, smoothstep( 0.0f, 0.2f, min( i.vBaseUV_PatternUV.x, i.vBaseUV_PatternUV.y ) ) ) ),
  410. step( i.vBaseUV_PatternUV.x, invHighlight ) * flBackingSample.a );
  411. //if ( i.vBaseUV_PatternUV.x > invHighlight )
  412. //{
  413. // cOut.rgb = 0;
  414. // cOut.a *= (1.0f - distort) * 0.8f;
  415. //}
  416. //becomes:
  417. cOut = lerp( cOut, float4( 0, 0, 0, cOut.a * (1.0f - distort) * 0.8f ), step( invHighlight, i.vBaseUV_PatternUV.x ) );
  418. #endif
  419. #endif
  420. return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR );
  421. }