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.

381 lines
11 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "ADDITIVE" "0..1"
  3. // STATIC: "DETAIL1" "0..1"
  4. // STATIC: "DETAIL1BLENDMODE" "0..1"
  5. // STATIC: "DETAIL2" "0..1"
  6. // STATIC: "DETAIL2BLENDMODE" "0..1"
  7. // STATIC: "TANGENTTOPACITY" "0..1"
  8. // STATIC: "TANGENTSOPACITY" "0..1"
  9. // STATIC: "FRESNELOPACITY" "0..1"
  10. // STATIC: "DEPTHBLEND" "0..1" [CONSOLE]
  11. // STATIC: "DEPTHBLEND" "0..0" [PC]
  12. // STATIC: "VERTEXCOLOR" "0..1"
  13. // STATIC: "FLOWMAP" "0..1"
  14. // STATIC: "FLOW_CHEAP" "0..1" [PC]
  15. // STATIC: "FLOW_CHEAP" "0..0" [CONSOLE]
  16. // DYNAMIC: "ACTIVE" "0..1"
  17. // DYNAMIC: "POWERUP" "0..1"
  18. // DYNAMIC: "VORTEX1" "0..1"
  19. // DYNAMIC: "VORTEX2" "0..1"
  20. // SKIP: ( ( $DETAIL1 == 0 ) && ( $DETAIL2 != 0 ) )
  21. // SKIP: ( ( $DETAIL1 == 0 ) && ( $DETAIL1BLENDMODE != 0 ) )
  22. // SKIP: ( ( $DETAIL2 == 0 ) && ( $DETAIL2BLENDMODE != 0 ) )
  23. // SKIP: ( $TANGENTTOPACITY && $TANGENTSOPACITY )
  24. // SKIP: ( $FRESNELOPACITY ) && ( $TANGENTTOPACITY || $TANGENTSOPACITY )
  25. // SKIP: ( $FLOWMAP && ( $DETAIL1 || $DETAIL2 ) )
  26. // SKIP: ( $FLOW_CHEAP && !$FLOWMAP )
  27. // SKIP: ( ( $FLOWMAP == 0 ) && ( $VORTEX1 || $VORTEX2 || $POWERUP ) )
  28. // SKIP: ( ( $ACTIVE == 0 ) && ( $VORTEX1 || $VORTEX2 || $POWERUP ) )
  29. #include "common_fog_ps_fxc.h"
  30. #include "shader_constant_register_map.h"
  31. // SAMPLERS
  32. sampler g_tBase : register( s0 );
  33. #if DETAIL1
  34. sampler g_tDetail1 : register( s1 );
  35. #endif
  36. #if DEPTHBLEND
  37. sampler g_tDepth : register( s3 );
  38. #endif
  39. #if DETAIL2
  40. sampler g_tDetail2 : register( s4 );
  41. #endif
  42. #if FLOWMAP
  43. sampler g_tFlowMap : register( s5 );
  44. sampler g_tFlowNoise : register( s6 );
  45. sampler g_tFlowBounds : register( s7 );
  46. #endif
  47. // SHADER CONSTANTS
  48. const float4 g_vTangentTOpacityRanges : register( c0 );
  49. const float4 g_vTangentSOpacityRanges : register( c1 );
  50. const float4 g_vFresnelOpacityRanges : register( c2 );
  51. const float4 g_vWriteDepthToAlpha_FlowParams : register( c3 );
  52. #define g_bWriteDepthToAlpha ( g_vWriteDepthToAlpha_FlowParams.x )
  53. #define g_flTime ( g_vWriteDepthToAlpha_FlowParams.y )
  54. #define g_flPowerUp ( g_vWriteDepthToAlpha_FlowParams.z )
  55. #define g_flIntensity ( g_vWriteDepthToAlpha_FlowParams.w )
  56. const float4 g_DepthFeatheringConstants : register( c4 );
  57. const float4 g_DiffuseModulation : register( c5 );
  58. const float4 g_vFlowParams1 : register( c6 );
  59. #define g_flWorldUvScale ( g_vFlowParams1.x ) // 1.0f / 10.0f
  60. #define g_flNormalUvScale ( g_vFlowParams1.y ) // 1.0f / 1.15f
  61. //#define UNUSED g_vFlowParams1.z
  62. #define g_flOutputIntensity ( g_vFlowParams1.w )
  63. const float4 g_vFlowParams2 : register( c7 );
  64. #define g_flFlowTimeIntervalInSeconds ( g_vFlowParams2.x ) // 0.4f // Number of seconds to lerp from texture 1 to texture 2
  65. #define g_flFlowUvScrollDistance ( g_vFlowParams2.y ) // 0.25f // Distance in uv space to fetch
  66. //#define UNUSED ( g_vFlowParams2.z )
  67. #define g_flColorFlowLerpExp ( g_vFlowParams2.w )
  68. const float4 g_vFlowColor : register( c8 );
  69. #define g_cFlow ( g_vFlowColor.xyz )
  70. //#define UNUSED g_cFlow.w
  71. const float4 g_vVortexParams : register( c9 );
  72. #define g_cVortex ( g_vVortexParams.xyz )
  73. #define g_flVortexSize ( g_vVortexParams.w )
  74. struct PS_INPUT
  75. {
  76. float4 vUV0_UV1 : TEXCOORD0;
  77. float4 vFlowUV_UV2 : TEXCOORD1;
  78. float4 vIteratedProjPos : TEXCOORD2;
  79. #if ( VORTEX1 )
  80. float3 vVortexPositions1 : TEXCOORD3;
  81. #endif
  82. #if ( VORTEX2 )
  83. float3 vVortexPositions2 : TEXCOORD4;
  84. #endif
  85. #if ( TANGENTSOPACITY || TANGENTTOPACITY || FRESNELOPACITY )
  86. float4 vWorldNormal_worldEyeX : TEXCOORD5;
  87. float4 vWorldTangent_worldEyeY : TEXCOORD6;
  88. float4 vTangentAlignedView_worldEyeZ : TEXCOORD7;
  89. #endif
  90. #if ( VERTEXCOLOR )
  91. float4 vColor : COLOR0;
  92. #endif
  93. };
  94. float4_color_return_type main( PS_INPUT i ) : COLOR
  95. {
  96. float4 cOut = { 0.0f, 0.0f, 0.0f, 1.0f };
  97. float4 cBase = { 0.0f, 0.0f, 0.0f, 1.0f };
  98. float3 vWorldEyeDir = float3( 0.0f, 0.0f, 0.0f );
  99. float3 vWorldNormal = float3( 0.0f, 0.0f, 0.0f );
  100. float3 vWorldTangent = float3( 0.0f, 0.0f, 0.0f );
  101. #if( TANGENTSOPACITY || TANGENTTOPACITY || FRESNELOPACITY )
  102. vWorldEyeDir = float3( i.vWorldNormal_worldEyeX.w, i.vWorldTangent_worldEyeY.w, i.vTangentAlignedView_worldEyeZ.w );
  103. vWorldNormal = i.vWorldNormal_worldEyeX.xyz;
  104. vWorldTangent = i.vWorldTangent_worldEyeY.xyz;
  105. #endif
  106. float fBackfaceRatio = 0.0f;
  107. #if ( ACTIVE )
  108. {
  109. #if ( FLOWMAP )
  110. {
  111. float4 vBoundsTexel = tex2D( g_tFlowBounds, i.vUV0_UV1.xy );
  112. float2 vFlowVectorTs = float2( 0.0f, 0.0f );
  113. #if ( !FLOW_CHEAP )
  114. {
  115. float2 vFlowUV = i.vFlowUV_UV2.xy * g_flWorldUvScale;
  116. float4 vFlowTexel = tex2D( g_tFlowMap, vFlowUV.xy );
  117. vFlowVectorTs = ( vFlowTexel.rg * 2.0f ) - 1.0f;
  118. vFlowVectorTs *= vBoundsTexel.r; // slow flow
  119. }
  120. #endif
  121. float flVortexIntensity = 0.0f;
  122. // vortex 1
  123. #if ( VORTEX1 )
  124. {
  125. float flVortex1Intensity = saturate( g_flVortexSize / length( i.vVortexPositions1.xyz ) - 0.5f );
  126. #if ( !FLOW_CHEAP )
  127. {
  128. vFlowVectorTs = lerp( vFlowVectorTs, normalize( i.vVortexPositions1.xy ), flVortex1Intensity * 0.5f );
  129. }
  130. #endif
  131. flVortexIntensity += flVortex1Intensity;
  132. }
  133. #endif
  134. #if ( VORTEX2 )
  135. {
  136. float flVortex2Intensity = saturate( g_flVortexSize / length( i.vVortexPositions2.xyz ) - 0.5f );
  137. #if ( !FLOW_CHEAP )
  138. {
  139. vFlowVectorTs = lerp( vFlowVectorTs, normalize( i.vVortexPositions2.xy ), flVortex2Intensity * 0.5f );
  140. }
  141. #endif
  142. flVortexIntensity += flVortex2Intensity;
  143. }
  144. #endif
  145. // Unpack world flow vector from texture
  146. float flNoise = tex2D( g_tFlowNoise, i.vFlowUV_UV2.zw ).g;
  147. // Every interval has a unique offset so we don't see the same bump texels repeating continuously
  148. float flTimeInIntervals = ( g_flTime / ( g_flFlowTimeIntervalInSeconds * 2.0f ) ) + flNoise;
  149. float flScrollTime1 = frac( flTimeInIntervals ) - 0.5;
  150. float flScrollTime2 = frac( flTimeInIntervals + 0.5f ) - 0.5; // Half an interval off from texture 1
  151. float flOffset1 = 0.0f;
  152. float flOffset2 = 0.5f;
  153. #if ( !FLOW_CHEAP )
  154. {
  155. flOffset1 = floor( flTimeInIntervals ) * 0.311f;
  156. flOffset2 = floor( flTimeInIntervals + 0.5f ) * 0.311f + 0.5f; // The +0.5 is to match the phase offset
  157. }
  158. #endif
  159. float flColorFlowLerpExp = g_flColorFlowLerpExp;
  160. float flWeight1 = abs( ( 2.0f * frac( flTimeInIntervals + 0.5f ) ) - 1.0f );
  161. float flWeight2 = abs( ( 2.0f * frac( flTimeInIntervals ) ) - 1.0f );
  162. #if ( !FLOW_CHEAP )
  163. {
  164. flWeight1 = pow( flWeight1, g_flColorFlowLerpExp );
  165. flWeight2 = pow( flWeight2, g_flColorFlowLerpExp );
  166. }
  167. #else
  168. {
  169. flWeight1 *= flWeight1;
  170. flWeight2 *= flWeight2;
  171. }
  172. #endif
  173. float flFlowUvScrollDistance = g_flFlowUvScrollDistance;
  174. float2 vFlowUV0 = i.vUV0_UV1.zw + flOffset1;
  175. float2 vFlowUV1 = i.vUV0_UV1.zw + flOffset2;
  176. #if ( !FLOW_CHEAP )
  177. {
  178. flFlowUvScrollDistance *= ( 1.0f + flVortexIntensity );
  179. vFlowUV0 += ( flScrollTime1 * ( flFlowUvScrollDistance * vFlowVectorTs.xy ) );
  180. vFlowUV1 += ( flScrollTime2 * ( flFlowUvScrollDistance * vFlowVectorTs.xy ) );
  181. }
  182. #endif
  183. cBase.rgba = tex2D( g_tBase, vFlowUV0 ) * flWeight1;
  184. cBase.rgba += tex2D( g_tBase, vFlowUV1 ) * flWeight2;
  185. #if ( POWERUP )
  186. {
  187. float flNoiseReveal = ( flNoise + ( 1.0f - vBoundsTexel.g ) ) * 0.5;
  188. float flPowerStage1 = saturate( 0.7f - g_flPowerUp );
  189. float flPowerStage2 = saturate( g_flPowerUp * 3.0f );
  190. float flPowerUpRange1 = smoothstep( 0.02f, 0.0f, abs( flNoiseReveal - g_flPowerUp ) );
  191. float flPowerUpRange2 = smoothstep( 0.02f, 0.0f, ( flNoiseReveal - g_flPowerUp ) );
  192. cBase.ag += flPowerUpRange1 * g_flPowerUp * (1.0f - g_flPowerUp );
  193. cBase.ag *= flPowerStage2 * flPowerUpRange2;
  194. cBase.ag += vBoundsTexel.g * flPowerStage2;
  195. }
  196. #else
  197. {
  198. cBase.ag += vBoundsTexel.g;
  199. }
  200. #endif
  201. float3 cFlowField = cBase.a * g_cFlow.rgb;
  202. #if( VORTEX1 || VORTEX2 )
  203. {
  204. float3 cVortex = cBase.g * g_cVortex.rgb;
  205. cBase.rgb = lerp( cFlowField, cVortex, flVortexIntensity );
  206. }
  207. #else
  208. {
  209. cBase.rgb = cFlowField;
  210. }
  211. #endif
  212. cBase.rgb *= vBoundsTexel.b * g_flIntensity;
  213. }
  214. #else
  215. {
  216. cBase = tex2D( g_tBase, i.vUV0_UV1.xy );
  217. }
  218. #endif
  219. #if( TANGENTTOPACITY || TANGENTSOPACITY || FRESNELOPACITY )
  220. {
  221. vWorldEyeDir.xyz = normalize( vWorldEyeDir.xyz );
  222. vWorldNormal.xyz = normalize( vWorldNormal.xyz );
  223. fBackfaceRatio = dot( vWorldEyeDir.xyz, vWorldNormal.xyz ) * 0.5f + 0.5f;
  224. fBackfaceRatio *= fBackfaceRatio;
  225. }
  226. #endif
  227. #if( TANGENTSOPACITY || TANGENTTOPACITY )
  228. {
  229. vWorldTangent.xyz = normalize( vWorldTangent.xyz );
  230. }
  231. #endif
  232. //alpha
  233. float alpha = 1.0f;
  234. float fBackfaceAlpha = 1.0f;
  235. #if TANGENTTOPACITY
  236. {
  237. float fTTFacing = abs( dot( vWorldTangent, normalize( i.vTangentAlignedView_worldEyeZ.xyz ) ) );
  238. alpha *= lerp( g_vTangentTOpacityRanges.x, g_vTangentTOpacityRanges.y, pow( fTTFacing, g_vTangentTOpacityRanges.z ) );
  239. fBackfaceAlpha = lerp( 1.0f, g_vTangentTOpacityRanges.w, fBackfaceRatio );
  240. }
  241. #endif
  242. #if TANGENTSOPACITY
  243. {
  244. float fTSFacing = abs( dot( vWorldTangent, normalize( i.vTangentAlignedView_worldEyeZ.xyz ) ) );
  245. alpha *= lerp( g_vTangentSOpacityRanges.x, g_vTangentSOpacityRanges.y, pow( fTSFacing, g_vTangentTOpacityRanges.z ) );
  246. fBackfaceAlpha = min( fBackfaceAlpha, lerp( g_vTangentSOpacityRanges.w, 1.0f, fBackfaceRatio ) );
  247. }
  248. #endif
  249. #if FRESNELOPACITY
  250. {
  251. float tNFacing = abs( dot( vWorldNormal, vWorldEyeDir.xyz ) );
  252. alpha *= lerp( g_vFresnelOpacityRanges.x, g_vFresnelOpacityRanges.y, pow( tNFacing, g_vFresnelOpacityRanges.z ) );
  253. fBackfaceAlpha = min( fBackfaceAlpha, lerp( g_vFresnelOpacityRanges.w, 1.0f, dot( vWorldEyeDir.xyz, vWorldNormal.xyz ) * 0.5f + 0.5f ) );
  254. }
  255. #endif
  256. alpha *= fBackfaceAlpha;
  257. #if DEPTHBLEND
  258. {
  259. alpha *= DepthFeathering( g_tDepth, i.vIteratedProjPos, g_DepthFeatheringConstants );
  260. }
  261. #endif
  262. #if ( !FLOWMAP && !TANGENTTOPACITY && !TANGENTSOPACITY && !FRESNELOPACITY && !( DETAIL1 && DETAIL1BLENDMODE == 1 ) )
  263. alpha *= cBase.a;
  264. #endif
  265. float flCameraFade = ComputeCameraFade( i.vIteratedProjPos );
  266. //color
  267. float4 cDetail1 = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  268. float4 cDetail2 = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  269. #if( DETAIL2 )
  270. {
  271. cDetail2 = tex2D( g_tDetail2, i.vFlowUV_UV2.zw );
  272. }
  273. #endif
  274. #if( DETAIL1 )
  275. {
  276. cDetail1 = tex2D( g_tDetail1, i.vUV0_UV1.zw );
  277. #if( DETAIL1BLENDMODE == 0 )
  278. {
  279. cBase.rgb *= 2.0f * cDetail1.rgb;
  280. }
  281. #else
  282. {
  283. cBase.rgb = lerp( cBase.rgb * cDetail1.rgb, cBase.rgb, cBase.a );
  284. }
  285. #endif
  286. }
  287. #endif
  288. #if( DETAIL2 )
  289. {
  290. #if( DETAIL2BLENDMODE == 0 )
  291. {
  292. #if( DETAIL1 )
  293. {
  294. cDetail2.rgb *= cDetail1.rgb;
  295. }
  296. #endif
  297. cBase.rgb += cDetail2.rgb;
  298. }
  299. #else
  300. {
  301. cBase.rgb *= cDetail2.rgb;
  302. }
  303. #endif
  304. }
  305. #endif
  306. cOut.a = alpha;
  307. cOut.rgb = cBase.rgb;
  308. #if ( POWERUP && !FLOWMAP )
  309. {
  310. cOut.rgb *= g_flPowerUp;
  311. }
  312. #endif
  313. #if ( ADDITIVE )
  314. {
  315. cOut.rgb *= ( 1.0f + alpha ) * flCameraFade;
  316. cOut.a = 1.0f;
  317. }
  318. #endif
  319. #if ( VERTEXCOLOR )
  320. {
  321. // fun with saturation:
  322. float3 vColor = pow( i.vColor.rgb, ( 2.0f - alpha ) * 2.0f );
  323. cOut.rgb *= vColor.rgb;
  324. }
  325. #endif
  326. }
  327. #endif // ACTIVE
  328. // Limit tonemap scalar to 0.0-1.0 so the colors don't oversaturate, but let it drop down to 0 in case we're fading
  329. float flTonemapScalar = saturate( LINEAR_LIGHT_SCALE );
  330. // g_flOutputIntensity is normally 1.0f, except to work around overall intensity problems on platforms that blend in gamma space (such as PS3).
  331. return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ) * flTonemapScalar * g_flOutputIntensity;
  332. }