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.

775 lines
26 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "SFM" "0..0" [ps20] [ps20b] [PC]
  3. // STATIC: "SFM" "0..1" [ps30] [PC]
  4. // STATIC: "SFM" "0..0" [CONSOLE]
  5. // STATIC: "DETAILTEXTURE" "0..1"
  6. // STATIC: "CUBEMAP" "0..1"
  7. // STATIC: "DIFFUSELIGHTING" "0..1"
  8. // STATIC: "ENVMAPMASK" "0..1"
  9. // STATIC: "BASEALPHAENVMAPMASK" "0..1"
  10. // STATIC: "SELFILLUM" "0..1"
  11. // STATIC: "VERTEXCOLOR" "0..1"
  12. // STATIC: "FLASHLIGHT" "0..1"
  13. // STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1"
  14. // STATIC: "DETAIL_BLEND_MODE" "0..9"
  15. // disable outline, glow, soft edges, seamless base/detail(doesn't seem to be used)
  16. // STATIC: "OUTLINE" "0..0"
  17. // STATIC: "OUTER_GLOW" "0..0"
  18. // STATIC: "SOFT_MASK" "0..0"
  19. // STATIC: "SEAMLESS_BASE" "0..0"
  20. // STATIC: "SEAMLESS_DETAIL" "0..0"
  21. // STATIC: "DISTANCEALPHA" "0..0"
  22. // STATIC: "DISTANCEALPHAFROMDETAIL" "0..0"
  23. // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..3" [ps20b] [PC]
  24. // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC]
  25. // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..1" [ps20b] [CONSOLE]
  26. // STATIC: "SHADER_SRGB_READ" "0..1" [XBOX]
  27. // STATIC: "SHADER_SRGB_READ" "0..0" [PC]
  28. // STATIC: "SHADER_SRGB_READ" "0..0" [SONYPS3]
  29. // STATIC: "DESATURATEWITHBASEALPHA" "0..1"
  30. // STATIC: "LIGHTING_PREVIEW" "0..0" [PC] // Disabled. Unused on CS:GO --Thorsten
  31. // STATIC: "LIGHTING_PREVIEW" "0..0" [CONSOLE]
  32. // STATIC: "ENVMAPFRESNEL" "0..1"
  33. // STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b]
  34. // STATIC: "CASCADED_SHADOW_MAPPING" "0..1" [CONSOLE]
  35. // STATIC: "CASCADED_SHADOW_MAPPING" "0..0" [ps20] [PC]
  36. // STATIC: "CASCADED_SHADOW_MAPPING" "0..1" [ps20b] [ps30] [PC]
  37. // STATIC: "CSM_MODE" "0..0" [CONSOLE]
  38. // STATIC: "CSM_MODE" "0..0" [ps20] [ps20b] [PC]
  39. // STATIC: "CSM_MODE" "0..3" [ps30] [PC]
  40. // STATIC: "CSM_BLENDING" "0..1"
  41. // STATIC: "DECAL_BLEND_MODE" "0..2"
  42. // STATIC: "TINTMASKTEXTURE" "0..1" [ps30] // not enough combos to support this - use vertexlit..bump or phong
  43. // STATIC: "TINTMASKTEXTURE" "0..0" [ps20] [ps20b]
  44. // STATIC: "TINTMASKTEXTURE" "0..0" [CONSOLE]
  45. // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b]
  46. // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30]
  47. // DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
  48. // DYNAMIC: "UBERLIGHT" "0..1" [ps30] [PC]
  49. // DYNAMIC: "CASCADE_SIZE" "0..1" [CONSOLE]
  50. // DYNAMIC: "CASCADE_SIZE" "0..1" [ps20b] [PC]
  51. // DYNAMIC: "CASCADE_SIZE" "0..0" [ps20] [ps30] [PC]
  52. // DYNAMIC: "SMOKEGRENADEBLEND" "0..1"
  53. // SKIP: ( $SFM == 0 ) && ( $UBERLIGHT == 1 )
  54. // detail blend mode 6 = ps20b only
  55. // SKIP: $DETAIL_BLEND_MODE == 6 [ps20]
  56. // SKIP: ( $FLASHLIGHT == 1 ) && ( $CUBEMAP == 1 ) [PC]
  57. // SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 )
  58. // SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL )
  59. // SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL)
  60. // SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
  61. // SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM
  62. // SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA
  63. // SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK)
  64. // SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL)
  65. // SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW)
  66. // SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL)
  67. // envmap stuff is meaningless if we're not using a cubemap
  68. // SKIP: ( $CUBEMAP == 0 ) && ( ( $ENVMAPFRESNEL == 1 ) || ( $BASEALPHAENVMAPMASK == 1 ) )
  69. // SKIP: ( $CUBEMAP == 0 ) && ( $ENVMAPMASK == 1 ) && ( $SELFILLUM_ENVMAPMASK_ALPHA == 0 )
  70. // We don't care about flashlight depth unless the flashlight is on
  71. // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b]
  72. // SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30]
  73. // We don't care about uberlight unless the flashlight is on
  74. // SKIP: ( $FLASHLIGHT == 0 ) && ( $UBERLIGHT == 1 ) [ps30]
  75. // DISTANCEALPHA-related skips
  76. // SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA || $ENVMAPFRESNEL)
  77. // SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP )
  78. // SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS )
  79. // SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER
  80. // Don't do this with seamless textures for now until we determine if we want to use this. Could probably skip more here to save some combos
  81. // skipping detailtextures to keep combos down
  82. // SKIP: $DESATURATEWITHBASEALPHA && ( $SEAMLESS_BASE || $DETAILTEXTURE )
  83. // These don't make sense together since they both use the base alpha channel
  84. // Also, using the same constant for the desaturate amount and the selfillumtint
  85. // SKIP: $DESATURATEWITHBASEALPHA && ( $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA )
  86. // These won't fit in ps20 at the same time.
  87. // SKIP: $DESATURATEWITHBASEALPHA && $BASEALPHAENVMAPMASK
  88. // SKIP: $FLASHLIGHTSHADOWS && ($LIGHTING_PREVIEW == 3)
  89. // SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $CASCADE_SIZE != 0 )
  90. // SKIP: ( $CASCADED_SHADOW_MAPPING != 0 ) && ( $SFM != 0 )
  91. // SKIP: ( $CASCADED_SHADOW_MAPPING != 0 ) && ( $FLASHLIGHT != 0 )
  92. // SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $CSM_MODE != 0 )
  93. #define PC_FLASHLIGHT ((FLASHLIGHT == 1) && !defined( _GAMECONSOLE ))
  94. #include "common_fog_ps_supportsvertexfog_fxc.h"
  95. #include "shader_constant_register_map.h"
  96. #include "common_flashlight_fxc.h"
  97. #include "common_vertexlitgeneric_dx9.h"
  98. #include "common_decaltexture_fxc.h"
  99. const float4 g_EnvmapTint_SPF : register( c0 ); //SPF=Single Pass Flashlight, stored in previously unused alpha.
  100. const float4 g_DiffuseModulation : register( c1 );
  101. const float4 g_ShadowTweaks : register( c2 );
  102. const float4 g_EnvmapParams : register( c19 );
  103. #define g_EnvmapContrast g_EnvmapParams.x
  104. #define g_DiffuseCubemapScale g_EnvmapParams.y
  105. #define g_fvDiffuseCubemapMin g_EnvmapParams.z
  106. #define g_fvDiffuseCubemapMax g_EnvmapParams.w
  107. const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 );
  108. const float4 g_SelfIllumTintOrSaturateFactor_and_BlendFactor : register( c4 );
  109. // glow params
  110. const float4 g_GlowParameters : register( c5 );
  111. const float4 g_GlowColor : register( c6 );
  112. #define GLOW_UV_OFFSET g_GlowParameters.xy
  113. #define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z
  114. #define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w
  115. #define OUTER_GLOW_COLOR g_GlowColor
  116. const float4 g_DistanceAlphaParams : register( c7 );
  117. #define SOFT_MASK_MAX g_DistanceAlphaParams.x
  118. #define SOFT_MASK_MIN g_DistanceAlphaParams.y
  119. #define g_flBaseAlphaEnvMapMaskBias g_DistanceAlphaParams.z
  120. #define g_flBaseAlphaEnvMapMaskScale g_DistanceAlphaParams.w
  121. const float4 g_OutlineColor : register( c8 );
  122. #define OUTLINE_COLOR g_OutlineColor
  123. const float4 g_OutlineParams : register( c9 );
  124. #define OUTLINE_MIN_VALUE0 g_OutlineParams.x
  125. #define OUTLINE_MIN_VALUE1 g_OutlineParams.y
  126. #define OUTLINE_MAX_VALUE0 g_OutlineParams.z
  127. #define OUTLINE_MAX_VALUE1 g_OutlineParams.w
  128. #if DETAILTEXTURE
  129. const float3 g_DetailTint : register( c10 );
  130. #endif
  131. const float2 g_flSelfIllumScale_g_flIsDecal : register( c11 );
  132. #define g_flSelfIllumScale g_flSelfIllumScale_g_flIsDecal.x
  133. #define g_flIsDecal g_flSelfIllumScale_g_flIsDecal.y
  134. const float4 g_ShaderControls : register( c12 );
  135. #define g_fInverseBlendTintByBaseAlpha g_ShaderControls.x
  136. #define g_fWriteDepthToAlpha g_ShaderControls.y
  137. #define g_fEnvMapMaskInTintMaskTexture g_ShaderControls.z
  138. #define g_fVertexAlpha g_ShaderControls.w
  139. const float4 g_FresnelConstants : register( c13 );
  140. #define g_flFresnelBias g_FresnelConstants.x
  141. #define g_flFresnelScale g_FresnelConstants.y
  142. #define g_flFresnelExp g_FresnelConstants.z
  143. #define g_flBaseAlphaEnvMapMaskExp g_FresnelConstants.w
  144. #if defined( SHADER_MODEL_PS_2_B )
  145. const float4 g_vCSMLightColor : register( c14 );
  146. #endif
  147. const float4 g_EyePos_BaseTextureTranslucency : register( c20 );
  148. const float4 g_FogParams : register( c21 );
  149. #if SELFILLUM || SELFILLUM_ENVMAPMASK_ALPHA
  150. #define g_SelfIllumTint g_SelfIllumTintOrSaturateFactor_and_BlendFactor.xyz
  151. #elif DESATURATEWITHBASEALPHA
  152. #define g_SaturateFactor g_SelfIllumTintOrSaturateFactor_and_BlendFactor.x
  153. #endif
  154. #define g_DetailBlendFactor g_SelfIllumTintOrSaturateFactor_and_BlendFactor.w
  155. #define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz
  156. #define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w
  157. const float4 g_FlashlightAttenuationFactors : register( c22 );
  158. const float3 g_FlashlightPos : register( c23 );
  159. const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27
  160. //const float g_flTime : register( c25 );
  161. #if UBERLIGHT
  162. // ps_3_0 and up (over 32 registers)
  163. const float3 g_vSmoothEdge0 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_0 );
  164. const float3 g_vSmoothEdge1 : register( PSREG_UBERLIGHT_SMOOTH_EDGE_1 );
  165. const float3 g_vSmoothOneOverWidth : register( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW );
  166. const float4 g_vShearRound : register( PSREG_UBERLIGHT_SHEAR_ROUND );
  167. const float4 g_aAbB : register( PSREG_UBERLIGHT_AABB );
  168. const float4x4 g_FlashlightWorldToLight : register( PSREG_UBERLIGHT_WORLD_TO_LIGHT );
  169. #endif
  170. sampler BaseTextureSampler : register( s0 );
  171. samplerCUBE EnvmapSampler : register( s1 );
  172. sampler DetailSampler : register( s2 );
  173. sampler EnvmapMaskSampler : register( s4 );
  174. sampler RandRotSampler : register( s6 ); // RandomRotation sampler
  175. sampler FlashlightSampler : register( s7 );
  176. sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler
  177. sampler DepthSampler : register( s10 ); // depth buffer sampler for depth blending
  178. sampler SelfIllumMaskSampler : register( s11 ); // selfillummask
  179. #if ( DECAL_BLEND_MODE != 2 )
  180. sampler DecalSampler : register( s12 );
  181. #endif
  182. #if ( TINTMASKTEXTURE )
  183. sampler TintMaskSampler : register( s13 );
  184. #endif
  185. #if defined(_PS3)
  186. // Needed for optimal shadow filter code generation on PS3.
  187. #pragma texformat ShadowDepthSampler DEPTH_COMPONENT24
  188. #endif
  189. struct PS_INPUT
  190. {
  191. // Stuff that isn't seen by the pixel shader
  192. float4 projPos : POSITION;
  193. #if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
  194. float fog : FOG;
  195. #endif
  196. // Stuff that is seen by the pixel shader
  197. float4 baseTexCoord_baseTexCoord2u : TEXCOORD0; // Base texture coordinates in .xy, seamless in .xyz, 2nd (decal) uv set 'u' in .w
  198. float4 detailTexCoord_baseTexCoord2v : TEXCOORD1; // Detail texture coordinates in .xy, seamless in .xyz, 2nd (decal) uv set 'v' in .w
  199. float4 vWorldNormal_fogFactorW : TEXCOORD2; // world space normal in .xyz, fog factor in .w
  200. float4 vWorldPos_csmXform0z : TEXCOORD3; // world pos in .xyz, csm lightToWorldxformcascade0.z in .w
  201. float4 directionalLightingColor_flShadowDimScalar : TEXCOORD4;
  202. float4 csmXform0or1_csmXform2 : TEXCOORD5; // csm lightToWorldxformcascade0 or 1.xy in .xy lightToWorldxformcascade2.xy in .zw
  203. float4 color : TEXCOORD6; // vertex color from lighting or unlit in .xyz
  204. float4 vProjPos : TEXCOORD7; // proj pos .xyzw
  205. #if FLASHLIGHT && defined( SHADER_MODEL_PS_3_0 )
  206. float4 flashlightSpacePos : TEXCOORD8;
  207. #endif
  208. #if SEAMLESS_DETAIL || SEAMLESS_BASE
  209. float3 SeamlessWeights : COLOR0; // x y z projection weights
  210. #endif
  211. #if defined( _X360 )
  212. float2 vScreenPos : VPOS;
  213. #endif
  214. };
  215. #if defined( _X360 ) || defined( _PS3 )
  216. #define SINGLE_PASS_FLASHLIGHT 1
  217. #else
  218. #define SINGLE_PASS_FLASHLIGHT 0
  219. #endif
  220. #define FLASHLIGHT_ONLY ( FLASHLIGHT && !SINGLE_PASS_FLASHLIGHT )
  221. #if ( CASCADED_SHADOW_MAPPING ) && !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  222. const bool g_bCSMEnabled : register(b0);
  223. #undef CASCADE_SIZE
  224. #define CASCADE_SIZE 1
  225. #endif
  226. #if ( ( !SFM ) && ( !FLASHLIGHT_ONLY ) && ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  227. #define CSM_ENABLED 1
  228. #else
  229. #define CSM_ENABLED 0
  230. #endif
  231. #if ( CSM_ENABLED )
  232. sampler CSMDepthAtlasSampler : register( s15 );
  233. #if defined(_PS3)
  234. // Needed for optimal shadow filter code generation on PS3.
  235. #pragma texformat CSMDepthAtlasSampler DEPTH_COMPONENT24
  236. #endif
  237. #if defined( SHADER_MODEL_PS_2_B )
  238. #define CSM_VERTEXLIT_AND_UNLIT_GENERIC
  239. #endif
  240. #include "csm_common_fxc.h"
  241. #endif
  242. float Luminance( float3 cColor )
  243. {
  244. // Formula for calculating luminance based on NTSC standard
  245. return dot( cColor.rgb, float3( 0.2125, 0.7154, 0.0721 ) );
  246. }
  247. #if LIGHTING_PREVIEW == 2
  248. LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR
  249. #else
  250. float4_color_return_type main( PS_INPUT i ) : COLOR
  251. #endif
  252. {
  253. HALF4 baseColor = HALF4( 1.00f, 1.0f, 1.0f, 1.0f );
  254. #if ( SEAMLESS_BASE )
  255. {
  256. baseColor =
  257. i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord_baseTexCoord2u.yz )+
  258. i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord_baseTexCoord2u.zx )+
  259. i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord_baseTexCoord2u.xy );
  260. #if defined ( _X360 ) && ( SHADER_SRGB_READ == 1 )
  261. {
  262. // Do this after the blending to save shader ops
  263. #if defined ( CSTRIKE15 )
  264. // [mariod] - 2.2 reads of srgb textures in cstrike15
  265. baseColor.rgb = GammaToLinear( baseColor.rgb );
  266. #else
  267. baseColor.rgb = X360GammaToLinear( baseColor.rgb );
  268. #endif
  269. }
  270. #endif
  271. }
  272. #else
  273. {
  274. baseColor = h4tex2Dsrgb( BaseTextureSampler, i.baseTexCoord_baseTexCoord2u.xy );
  275. #if ( SRGB_INPUT_ADAPTER )
  276. {
  277. baseColor.rgb = GammaToLinear( baseColor.rgb );
  278. }
  279. #endif
  280. }
  281. #endif
  282. HALF distAlphaMask;
  283. #if( DISTANCEALPHA && ( DISTANCEALPHAFROMDETAIL == 0 ) )
  284. {
  285. distAlphaMask = baseColor.a;
  286. }
  287. #endif
  288. HALF4 detailColor;
  289. #if ( DETAILTEXTURE )
  290. {
  291. #if( SEAMLESS_DETAIL )
  292. {
  293. detailColor =
  294. i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord_baseTexCoord2v.yz )+
  295. i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord_baseTexCoord2v.zx )+
  296. i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord_baseTexCoord2v.xy );
  297. }
  298. #else
  299. {
  300. detailColor = tex2D( DetailSampler, i.detailTexCoord_baseTexCoord2v.xy );
  301. }
  302. #endif
  303. detailColor.rgb *= g_DetailTint;
  304. #if ( DISTANCEALPHA && ( DISTANCEALPHAFROMDETAIL == 1 ) )
  305. {
  306. distAlphaMask = detailColor.a;
  307. detailColor.a = 1.0; // make tcombine treat as 1.0
  308. }
  309. #endif
  310. baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor );
  311. }
  312. #endif
  313. #if ( DESATURATEWITHBASEALPHA )
  314. {
  315. float grey = dot( baseColor.rgb, float3( 0.3, 0.59, 0.11 ) );
  316. baseColor.rgb = lerp( baseColor.rgb, ( float3 )grey, baseColor.a * g_SaturateFactor );
  317. }
  318. #endif
  319. #if ( DISTANCEALPHA )
  320. {
  321. // now, do all distance alpha effects
  322. if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) )
  323. {
  324. float oFactor = 1.0f;
  325. if ( distAlphaMask <= OUTLINE_MIN_VALUE1 )
  326. {
  327. oFactor = smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask );
  328. }
  329. else
  330. {
  331. oFactor = smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask );
  332. }
  333. baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor );
  334. }
  335. float mskUsed;
  336. #if ( SOFT_MASK )
  337. {
  338. mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask );
  339. baseColor.a *= mskUsed;
  340. }
  341. #else
  342. {
  343. mskUsed = distAlphaMask >= 0.5f;
  344. #if ( DETAILTEXTURE )
  345. {
  346. baseColor.a *= mskUsed;
  347. }
  348. #else
  349. {
  350. baseColor.a = mskUsed;
  351. }
  352. #endif
  353. }
  354. #endif
  355. #if ( OUTER_GLOW )
  356. {
  357. float glowTexel;
  358. #if ( DISTANCEALPHAFROMDETAIL )
  359. {
  360. glowTexel = tex2D( DetailSampler, i.detailTexCoord_baseTexCoord2v.xy+GLOW_UV_OFFSET ).a;
  361. }
  362. #else
  363. {
  364. glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord_baseTexCoord2u.xy+GLOW_UV_OFFSET ).a;
  365. }
  366. #endif
  367. float4 glowc = OUTER_GLOW_COLOR * smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel );
  368. baseColor = lerp( glowc, baseColor, mskUsed );
  369. }
  370. #endif
  371. }
  372. #endif
  373. HALF3 specularFactor = 1.0h;
  374. HALF4 envmapMaskTexel;
  375. #if ( ENVMAPMASK )
  376. {
  377. envmapMaskTexel = h4tex2D( EnvmapMaskSampler, i.baseTexCoord_baseTexCoord2u.xy );
  378. specularFactor *= (HALF)envmapMaskTexel.xyz;
  379. }
  380. #endif
  381. #if ( BASEALPHAENVMAPMASK )
  382. {
  383. specularFactor *= saturate( g_flBaseAlphaEnvMapMaskScale * pow( baseColor.a, g_flBaseAlphaEnvMapMaskExp ) + g_flBaseAlphaEnvMapMaskBias );
  384. }
  385. #endif
  386. #if ( ENVMAPFRESNEL )
  387. {
  388. float3 vEyeDir = normalize( g_EyePos_BaseTextureTranslucency.xyz - i.vWorldPos_csmXform0z.xyz );
  389. float flFresnel = 1-saturate( dot( normalize( i.vWorldNormal_fogFactorW.xyz ), vEyeDir ) );
  390. flFresnel = g_flFresnelScale * pow( flFresnel, g_flFresnelExp ) + g_flFresnelBias;
  391. specularFactor *= flFresnel;
  392. }
  393. #endif
  394. float flDirectionalShadow = 1.0f;
  395. #if ( CSM_ENABLED )
  396. {
  397. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  398. if ( g_bCSMEnabled )
  399. {
  400. #endif
  401. #if !defined( _X360 ) && !defined( _PS3 ) && defined( SHADER_MODEL_PS_2_B )
  402. flDirectionalShadow = CSMComputeShadowing( i.vWorldPos_csmXform0z.xyz, i.csmXform0or1_csmXform2.xy, i.csmXform0or1_csmXform2.zw, i.vWorldPos_csmXform0z.w );
  403. #else
  404. flDirectionalShadow = CSMComputeShadowing( i.vWorldPos_csmXform0z.xyz );
  405. #endif
  406. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  407. }
  408. #endif
  409. }
  410. #endif
  411. HALF3 diffuseLighting = HALF3( 1.0f, 1.0f, 1.0f );
  412. #if ( DIFFUSELIGHTING || VERTEXCOLOR && !( VERTEXCOLOR && DIFFUSELIGHTING ) )
  413. {
  414. diffuseLighting = (HALF3)i.color.rgb;
  415. diffuseLighting.rgb += i.directionalLightingColor_flShadowDimScalar.rgb * flDirectionalShadow;
  416. #if ( CSM_ENABLED && !VERTEXCOLOR )
  417. {
  418. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  419. if ( g_bCSMEnabled )
  420. {
  421. #endif
  422. #if ( !FLASHLIGHT )
  423. {
  424. float flSunAmount = i.directionalLightingColor_flShadowDimScalar.w;
  425. #if ( CSM_BLENDING == 1 )
  426. if ( flSunAmount > 0.0f )
  427. {
  428. float3 direct = flSunAmount * g_vCSMLightColor.rgb;
  429. float3 indirect = i.color.rgb;
  430. // Apply csm shadows
  431. diffuseLighting.rgb = ( direct * flDirectionalShadow ) + indirect;
  432. }
  433. #else
  434. float flSunPercent = flSunAmount / Luminance( diffuseLighting.rgb );
  435. float flShadowScalar = 1.0 - ( flSunPercent * ( 1.0 - flDirectionalShadow ) );
  436. /* Debug - blink full shadows
  437. if ( step( frac( g_flTime * 0.5 ), 0.5 ) )
  438. {
  439. flShadowScalar = 1.0 - flSunPercent;
  440. }
  441. //*/
  442. // Apply csm shadows
  443. diffuseLighting.rgb *= flShadowScalar;
  444. // Desaturate shadow color since we only have a grayscale dim factor
  445. diffuseLighting.rgb = lerp( diffuseLighting.bgr, diffuseLighting.rgb, flShadowScalar * 0.5 + 0.5 );
  446. #endif
  447. }
  448. #endif
  449. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  450. }
  451. #endif
  452. }
  453. #endif
  454. }
  455. #endif
  456. HALF3 albedo = baseColor.rgb;
  457. HALF alpha = 1.0f;
  458. #if ( !BASEALPHAENVMAPMASK && !SELFILLUM )
  459. {
  460. alpha *= lerp( 1.0h, baseColor.a, (HALF)g_EyePos_BaseTextureTranslucency.w );
  461. }
  462. #endif
  463. #if ( FLASHLIGHT )
  464. {
  465. int nShadowSampleLevel = 0;
  466. bool bDoShadows = false;
  467. // Do shadow mapping on shader models 2b and 30.
  468. #if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) )
  469. {
  470. nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE;
  471. bDoShadows = true;
  472. }
  473. #endif
  474. float4 flashlightSpacePosition;
  475. #if defined( SHADER_MODEL_PS_3_0 )
  476. flashlightSpacePosition = i.flashlightSpacePos;
  477. #else
  478. flashlightSpacePosition = TransformFlashlightWorldToTexture( i.vWorldPos_csmXform0z.xyz, g_FlashlightWorldToTexture );
  479. #endif
  480. // We want the N.L to happen on the flashlight pass, but can't afford it on ps20
  481. bool bUseWorldNormal = true;
  482. #if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) )
  483. {
  484. bUseWorldNormal = false;
  485. }
  486. #endif
  487. HALF3 flashlightColor = DoFlashlight( g_FlashlightPos, i.vWorldPos_csmXform0z.xyz, flashlightSpacePosition,
  488. i.vWorldNormal_fogFactorW.xyz, g_FlashlightAttenuationFactors.xyz,
  489. g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler,
  490. RandRotSampler, nShadowSampleLevel, bDoShadows, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bUseWorldNormal );
  491. #if ( UBERLIGHT )
  492. {
  493. float4 uberLightPosition = mul( float4( i.vWorldPos_csmXform0z.xyz, 1.0f ), g_FlashlightWorldToLight ).yzxw;
  494. flashlightColor *= uberlight( uberLightPosition.xyz, g_vSmoothEdge0, g_vSmoothEdge1,
  495. g_vSmoothOneOverWidth, g_vShearRound.xy, g_aAbB, g_vShearRound.zw );
  496. }
  497. #endif
  498. //add to diffuse in single pass flashlight mode, replace diffuse in additive two pass mode
  499. #if defined ( _GAMECONSOLE )
  500. {
  501. diffuseLighting += flashlightColor;
  502. }
  503. #else
  504. {
  505. diffuseLighting = (diffuseLighting * g_EnvmapTint_SPF.a) + flashlightColor;
  506. }
  507. #endif
  508. }
  509. #endif
  510. #if ( DECAL_BLEND_MODE != 2 )
  511. float3 decalLighting = diffuseLighting;
  512. #endif
  513. #if ( defined( SHADER_MODEL_PS_2_0 ) )
  514. {
  515. // This branch means that g_fInverseBlendTintByBaseAlpha doesn't work with ps20, but we don't care since we're dropping ps20
  516. diffuseLighting *= g_DiffuseModulation.rgb;
  517. }
  518. #else
  519. {
  520. #if ( TINTMASKTEXTURE )
  521. // Optionally use inverseblendtint texture to blend in the diffuse modulation (saturated add of g_fInverseBlendTintByBaseAlpha turns this on/off)
  522. float4 tintMask = h4tex2Dsrgb( TintMaskSampler, i.baseTexCoord_baseTexCoord2u.xy ).rgba; // use g channel since common use will be mono or dxt1 (greater precision in g).
  523. // g_fInverseBlendTintByBaseAlpha will be 0 in this combo so that tintMask.g has an effect, or -1 if notint is set in the material
  524. diffuseLighting *= lerp( HALF3( 1.0h, 1.0h, 1.0h ), (HALF3)g_DiffuseModulation.rgb, saturate( tintMask.g + (HALF)g_fInverseBlendTintByBaseAlpha ) );
  525. specularFactor = g_fEnvMapMaskInTintMaskTexture ? tintMask.r : specularFactor;
  526. #else
  527. // Optionally use basealpha to blend in the diffuse modulation (saturated add of g_fInverseBlendTintByBaseAlpha turns this on/off)
  528. diffuseLighting *= lerp( HALF3( 1.0h, 1.0h, 1.0h ), (HALF3)g_DiffuseModulation.rgb, saturate( baseColor.a + (HALF)g_fInverseBlendTintByBaseAlpha ) );
  529. #endif
  530. }
  531. #endif
  532. alpha *= (HALF)g_DiffuseModulation.a;
  533. #if ( VERTEXCOLOR && DIFFUSELIGHTING )
  534. {
  535. albedo *= (HALF)i.color.rgb;
  536. }
  537. #endif
  538. alpha = lerp( alpha, alpha * (HALF)i.color.a, (HALF)g_fVertexAlpha );
  539. HALF3 diffuseComponent = albedo * diffuseLighting;
  540. #if ( DECAL_BLEND_MODE != 2 )
  541. float4 decalColor = tex2D( DecalSampler, float2(i.baseTexCoord_baseTexCoord2u.w, i.detailTexCoord_baseTexCoord2v.w ) );
  542. diffuseComponent = TextureCombineDecal( diffuseComponent, decalColor, decalLighting );
  543. #endif
  544. #if ( DETAILTEXTURE )
  545. {
  546. diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor );
  547. }
  548. #endif
  549. #if !( FLASHLIGHT && defined( SHADER_MODEL_PS_2_0 ) )
  550. {
  551. #if SELFILLUM_ENVMAPMASK_ALPHA
  552. {
  553. // range of alpha:
  554. // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8)
  555. // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows)
  556. float3 selfIllumComponent = g_SelfIllumTint * albedo;
  557. half Adj_Alpha = 8 * envmapMaskTexel.a;
  558. diffuseComponent = ( max( 0, 1 - Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent;
  559. }
  560. #elif SELFILLUM
  561. {
  562. float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord_baseTexCoord2u.xy ).rgb;
  563. vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl );
  564. diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask * g_flSelfIllumScale );
  565. }
  566. #endif
  567. }
  568. #endif
  569. HALF3 specularLighting = HALF3( 0.0h, 0.0h, 0.0h );
  570. //Single pass flashlight mode runs out of instructions and constant registers when both detail textures and cubemaps are enabled on PC. Silently drop cubemaps in that case.
  571. #if ( !PC_FLASHLIGHT )
  572. {
  573. #if ( CUBEMAP )
  574. {
  575. float3 vEyeDir = g_EyePos_BaseTextureTranslucency.xyz - i.vWorldPos_csmXform0z.xyz;
  576. float3 reflectVect = CalcReflectionVectorUnnormalized( i.vWorldNormal_fogFactorW.xyz, vEyeDir.xyz );
  577. specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ).rgb;
  578. specularLighting *= specularFactor;
  579. specularLighting *= g_EnvmapTint_SPF.rgb;
  580. #if defined( SHADER_MODEL_PS_3_0 )
  581. {
  582. float3 cubemapLight = ( diffuseLighting - g_fvDiffuseCubemapMin ) * g_fvDiffuseCubemapMax;
  583. specularLighting = lerp( specularLighting, specularLighting * cubemapLight, g_DiffuseCubemapScale ); //reduce the cubemap contribution when the pixel is in shadow
  584. float3 specularLightingSquared = specularLighting * specularLighting;
  585. specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
  586. float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) );
  587. specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
  588. }
  589. #endif
  590. }
  591. #endif
  592. }
  593. #endif
  594. HALF3 result = diffuseComponent + specularLighting;
  595. #if ( SMOKEGRENADEBLEND )
  596. float flSmokeDistance = length( i.vWorldPos_csmXform0z.xyz - g_GlowColor.rgb ) * 0.0008f;
  597. flSmokeDistance = smoothstep( 0.08f, 0.12f, flSmokeDistance );
  598. //result.rgb = lerp( float3(1,0,0), result.rgb, flSmokeDistance );
  599. alpha *= flSmokeDistance;
  600. #endif
  601. #if ( LIGHTING_PREVIEW == 0 )
  602. {
  603. HALF fogFactor;
  604. HALF flVertexFogFactor = 0.0f;
  605. #if ( !HARDWAREFOGBLEND && !DOPIXELFOG )
  606. {
  607. flVertexFogFactor = (HALF)i.vWorldNormal_fogFactorW.w;
  608. }
  609. #endif
  610. fogFactor = CalcPixelFogFactorSupportsVertexFog( PIXELFOGTYPE, g_FogParams, g_EyePos_BaseTextureTranslucency.xyz, i.vWorldPos_csmXform0z.xyz, i.vProjPos.z, flVertexFogFactor );
  611. if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT && WRITEWATERFOGTODESTALPHA )
  612. {
  613. alpha = fogFactor;
  614. }
  615. float4_color_return_type vOutput = FinalOutputHalf( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.vProjPos.z );
  616. #if ( defined( _X360 ) )
  617. {
  618. vOutput.xyz += ScreenSpaceOrderedDither( i.vScreenPos );
  619. }
  620. #endif
  621. return vOutput;
  622. }
  623. #endif
  624. #if ( LIGHTING_PREVIEW == 1 )
  625. {
  626. float dotprod = 0.2 + abs( dot( normalize(i.vWorldNormal_fogFactorW.xyz), normalize(g_EyePos_BaseTextureTranslucency.xyz - i.vWorldPos_csmXform0z.xyz) ) );
  627. return FinalOutput( float4( dotprod * albedo *
  628. lerp( HALF3( 1.0h, 1.0h, 1.0h ), (HALF3)g_DiffuseModulation.rgb, saturate( baseColor.a + (HALF)g_fInverseBlendTintByBaseAlpha ) ) // color tint
  629. , alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  630. }
  631. #endif
  632. #if ( LIGHTING_PREVIEW == 2 )
  633. {
  634. LPREVIEW_PS_OUT ret;
  635. ret.flags = float4( 1, 1, 1, 1 );
  636. ret.color = float4( albedo.xyz, alpha );
  637. ret.normal = float4( i.vWorldNormal_fogFactorW.xyz, alpha );
  638. ret.position = float4( i.vWorldPos_csmXform0z.xyz, alpha );
  639. return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  640. }
  641. #endif
  642. #if ( LIGHTING_PREVIEW == 3 ) // normal + depth
  643. return float4( normalize( i.vWorldNormal_fogFactorW.xyz ), i.vProjPos.z );
  644. #endif
  645. }