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.

355 lines
12 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "COMPOSITEMODE" "0..2"
  3. // STATIC: "CASCADED_SHADOW_MAPPING" "0..1" [ps30]
  4. // STATIC: "CSM_MODE" "0..0" [ = 0 ] [ps20] [ps20b] [PC]
  5. // STATIC: "CSM_MODE" "0..3" [ps30] [PC]
  6. // STATIC: "USE_PATTERN1" "0..1"
  7. // STATIC: "USE_PATTERN2" "0..1"
  8. // STATIC: "USE_PATTERN_OFFSET" "0..1"
  9. // STATIC: "USE_LOGO1" "0..1"
  10. // STATIC: "USE_LOGO2" "0..1"
  11. // STATIC: "SWAP_PATTERN_MASKS" "0..1"
  12. // DYNAMIC: "NUM_LIGHTS" "0..2" [ps20]
  13. // DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] [ps30]
  14. // DYNAMIC: "DYN_CSM_ENABLED" "0..1"
  15. // DYNAMIC: "AO_MODE" "0..1"
  16. // SKIP: ( ( $COMPOSITEMODE == 1 ) && ( $CASCADED_SHADOW_MAPPING != 0 ) )
  17. // SKIP: ( ( $COMPOSITEMODE == 1 ) && ( $NUM_LIGHTS != 0 ) )
  18. // SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $DYN_CSM_ENABLED == 1 )
  19. // SKIP: ( $CASCADED_SHADOW_MAPPING == 0 ) && ( $CSM_MODE != 0 )
  20. // SKIP: ( $USE_PATTERN2 == 1 ) && ( $USE_PATTERN1 == 0 )
  21. // SKIP: ( $USE_PATTERN_OFFSET == 1 ) && ( $USE_PATTERN1 == 0 && $USE_PATTERN2 == 0 )
  22. // SKIP: ( $SWAP_PATTERN_MASKS == 1 ) && ( $USE_PATTERN1 == 0 && $USE_PATTERN2 == 0 )
  23. // SKIP: ( $USE_LOGO2 == 1 ) && ( $USE_LOGO1 == 0 )
  24. // SKIP: ( $COMPOSITEMODE == 2 ) && ( $USE_PATTERN1 == 1 )
  25. // SKIP: ( $COMPOSITEMODE == 2 ) && ( $USE_PATTERN2 == 1 )
  26. // SKIP: ( $COMPOSITEMODE == 2 ) && ( $USE_PATTERN_OFFSET == 1 )
  27. // SKIP: ( $COMPOSITEMODE == 2 ) && ( $USE_LOGO1 == 1 )
  28. // SKIP: ( $COMPOSITEMODE == 2 ) && ( $USE_LOGO2 == 1 )
  29. // SKIP: ( $AO_MODE == 1 ) && ( $COMPOSITEMODE == 1 )
  30. // SKIP: ( $AO_MODE == 1 ) && ( $NUM_LIGHTS != 0 )
  31. // SKIP: ( $AO_MODE == 1 ) && ( $DYN_CSM_ENABLED == 1 )
  32. #include "common_ps_fxc.h"
  33. #include "shader_constant_register_map.h"
  34. #define NEED_COMPOSITE_INPUTS ( COMPOSITEMODE == 0 || COMPOSITEMODE == 1 ) //3D preview or 2D composite
  35. #define IS_3D_MODE ( COMPOSITEMODE != 1 ) //Not mode 1, that is anything other than 2D composite mode. Silly name to avoid starting with a numeral
  36. #define IS_3D_POSTCOMPOSITE ( COMPOSITEMODE == 2 )
  37. #define USE_HALF_LAMBERT false
  38. #define SSAO_EFFECT_MULTIPLIER 0.9f
  39. // SAMPLERS
  40. sampler BaseSampler : register( s0 );
  41. sampler NormalMapSampler : register( s1 );
  42. #if AO_MODE == 0
  43. sampler SSAOMapSampler : register( s10 );
  44. #endif
  45. #if NEED_COMPOSITE_INPUTS
  46. sampler AOMapSampler : register( s2 );
  47. sampler MaskMapSampler : register( s3 );
  48. #if USE_PATTERN1
  49. sampler Pattern1Sampler : register( s4 );
  50. #endif
  51. #if USE_PATTERN2
  52. sampler Pattern2Sampler : register( s6 );
  53. #endif
  54. sampler GrimeSampler : register( s7 );
  55. #if USE_PATTERN_OFFSET
  56. sampler OffsetSampler : register( s8 );
  57. #endif
  58. #if USE_LOGO1
  59. sampler LogoSampler : register( s9 );
  60. #endif
  61. #endif
  62. #if IS_3D_MODE
  63. sampler NormalizeSampler : register( s5 );
  64. #endif
  65. #if ( CASCADED_SHADOW_MAPPING == 1 )
  66. sampler CSMDepthAtlasSampler : register( s15 );
  67. #undef CASCADE_SIZE
  68. #define CASCADE_SIZE 3
  69. #define CSM_ENABLED 1
  70. //#define CSM_VERTEXLIT_AND_UNLIT_GENERIC_BUMP //use the same CSM const registers?
  71. #include "csm_common_fxc.h"
  72. #endif
  73. // REGISTERS
  74. #if IS_3D_MODE
  75. const float3 g_cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); // 4 through 9
  76. PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 20 through 25
  77. //for normalized screen-space coords
  78. const float4 g_fvConstRegister17 : register( c17 );
  79. const float4 g_fvConstRegister18 : register( c18 );
  80. #define g_vEyePos g_fvConstRegister18.xyz
  81. #define g_flElementDistance g_fvConstRegister18.w
  82. #endif
  83. #if NEED_COMPOSITE_INPUTS
  84. const float4 g_fvConstRegister0 : register( c0 );
  85. const float4 g_fvConstRegister1 : register( c1 );
  86. const float4 g_fvConstRegister2 : register( c2 );
  87. const float4 g_fvConstRegister10 : register( c10 );
  88. const float4 g_fvConstRegister11 : register( c11 );
  89. const float4 g_fvConstRegister12 : register( c12 );
  90. #define g_vPattern1Color1 float3( g_fvConstRegister0.x, g_fvConstRegister0.y, g_fvConstRegister0.z )
  91. #define g_vPattern1Color2 float3( g_fvConstRegister1.x, g_fvConstRegister1.y, g_fvConstRegister1.z )
  92. #define g_vPattern1Color3 float3( g_fvConstRegister2.x, g_fvConstRegister2.y, g_fvConstRegister2.z )
  93. #define g_vPattern1Color4 float3( g_fvConstRegister0.w, g_fvConstRegister1.w, g_fvConstRegister2.w )
  94. #define g_vPattern2Color1 float3( g_fvConstRegister10.x, g_fvConstRegister10.y, g_fvConstRegister10.z )
  95. #define g_vPattern2Color2 float3( g_fvConstRegister11.x, g_fvConstRegister11.y, g_fvConstRegister11.z )
  96. #define g_vPattern2Color3 float3( g_fvConstRegister12.x, g_fvConstRegister12.y, g_fvConstRegister12.z )
  97. #define g_vPattern2Color4 float3( g_fvConstRegister10.w, g_fvConstRegister11.w, g_fvConstRegister12.w )
  98. const float4 g_fvConstRegister13 : register( c13 );
  99. #define g_vPattern1Scale g_fvConstRegister13.x
  100. #define g_vPattern2Scale g_fvConstRegister13.y
  101. #define g_flCavityPower g_fvConstRegister13.z
  102. #define g_flOffsetAmount g_fvConstRegister13.w
  103. const float4 g_fvConstRegister14 : register( c14 );
  104. #define g_vLogoOffset g_fvConstRegister14.xy
  105. #define g_fLogoScale g_fvConstRegister14.z
  106. #define g_fLogoRotation g_fvConstRegister14.w
  107. const float4 g_fvConstRegister15 : register( c15 );
  108. #define g_vLogo2Offset g_fvConstRegister15.xy
  109. #define g_fLogo2Scale g_fvConstRegister15.z
  110. #define g_fLogo2Rotation g_fvConstRegister15.w
  111. const float4 g_fvConstRegister16 : register( c16 );
  112. #define g_fLogoMaskCrispnessMin g_fvConstRegister16.x
  113. #define g_fLogoMaskCrispnessMax g_fvConstRegister16.y
  114. #define g_fLogoWear g_fvConstRegister16.z
  115. #endif
  116. #define DESAT float3( 0.3f, 0.59f, 0.11f )
  117. float2 rotate( float2 inputUV, float rotateTau )
  118. {
  119. return float2( inputUV.x * cos(rotateTau) - inputUV.y * sin(rotateTau),
  120. inputUV.x * sin(rotateTau) + inputUV.y * cos(rotateTau) );
  121. }
  122. float2 getLogoUV( float2 inputUV, float2 inputOffset, float inputScale, float inputRotation )
  123. {
  124. float2 vLogoUV = inputUV;
  125. vLogoUV -= float2( 0.5f , 0.5f );
  126. vLogoUV -= inputOffset;
  127. vLogoUV *= inputScale;
  128. vLogoUV = rotate( vLogoUV, inputRotation );
  129. return (vLogoUV + float2( 0.5f , 0.5f ));
  130. }
  131. struct PS_INPUT
  132. {
  133. float4 vBaseUV_PatternUV : TEXCOORD0;
  134. float4 vWearUV_GrungeUV : TEXCOORD1;
  135. #if IS_3D_MODE
  136. float4 lightAtten : TEXCOORD2;
  137. float3 worldPos : TEXCOORD3;
  138. float3x3 tangentSpaceTranspose : TEXCOORD4;
  139. // second row : TEXCOORD5;
  140. // third row : TEXCOORD6;
  141. float4 vProjPos : TEXCOORD7;
  142. #endif
  143. };
  144. float3 PhotoshopOverlay( float3 cBase, float3 cBlend )
  145. {
  146. float3 cNew;
  147. cNew = step( 0.5, cBase );
  148. cNew = lerp( (cBase*cBlend*2), (1.0-(2.0*(1.0-cBase)*(1.0-cBlend))), cNew );
  149. return cNew;
  150. }
  151. float2 PackFloat2( float f)
  152. {
  153. float2 packed;
  154. f *= 256.0f;
  155. packed.x = floor( f ) * (1.0f / 256.0f);
  156. packed.y = frac( f );
  157. return packed;
  158. }
  159. float4_color_return_type main( PS_INPUT i ) : COLOR
  160. {
  161. #if AO_MODE == 1
  162. float flLocalDistance = smoothstep( g_flElementDistance - 40.0f, g_flElementDistance + 40.0f, length( g_vEyePos.xyz - i.worldPos.xyz ) );
  163. float3 vNormalTexel = 2.0f * (tex2D( NormalMapSampler, i.vBaseUV_PatternUV.xy ).rgb) - 1.0f;
  164. float3 vWorldPixelNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, vNormalTexel ) );
  165. float3 vEyeDir = normalize(g_vEyePos.xyz - i.worldPos.xyz);
  166. float3 vLeftDir = cross( vEyeDir, float3(0,0,1) );
  167. float3 vUpDir = cross( vEyeDir, vLeftDir );
  168. return float4( (dot( vLeftDir, vWorldPixelNormal ) + 1.0f) * 0.5f, (dot( vUpDir, vWorldPixelNormal ) + 1.0f) * 0.5f, PackFloat2( flLocalDistance ) );
  169. //return float4( dot( vLeftDir, vWorldPixelNormal ), dot( vUpDir, vWorldPixelNormal ), PackFloat2( flLocalDistance ) );
  170. #else
  171. float3 vColorTexel = tex2D( BaseSampler, i.vBaseUV_PatternUV.xy ).rgb;
  172. #if NEED_COMPOSITE_INPUTS
  173. float3 vMasksTexel = tex2D( MaskMapSampler, i.vBaseUV_PatternUV.xy ).rgb;
  174. float3 vAOTexel = tex2D( AOMapSampler, i.vBaseUV_PatternUV.xy ).rgb;
  175. float flCavityPostPow = pow(vAOTexel.g, g_flCavityPower);
  176. vAOTexel.b = smoothstep( g_fLogoMaskCrispnessMin, g_fLogoMaskCrispnessMax, vAOTexel.b );
  177. float3 vGrime = tex2D( GrimeSampler, i.vBaseUV_PatternUV.xy ).rgb;
  178. #if USE_PATTERN1
  179. #if SWAP_PATTERN_MASKS
  180. vMasksTexel.rg = vMasksTexel.gr;
  181. #endif
  182. float2 vPatternUV = i.vBaseUV_PatternUV.xy;
  183. #if USE_PATTERN_OFFSET
  184. float distAlphaMask = tex2D( OffsetSampler, i.vBaseUV_PatternUV.xy ).a;
  185. //offset pattern UVs by distance-field offset mask
  186. vPatternUV.x += step( 0.5f, distAlphaMask ) * g_flOffsetAmount;
  187. #endif
  188. //sample patterns
  189. float3 vColorPattern1 = tex2D( Pattern1Sampler, vPatternUV * g_vPattern1Scale ).rgb;
  190. #if USE_PATTERN2
  191. float3 vColorPattern2 = tex2D( Pattern2Sampler, vPatternUV * g_vPattern2Scale ).rgb;
  192. #endif
  193. //bash pattern1 by solid color mask (fixme)
  194. vColorPattern1 = lerp( vColorPattern1, float3(0,1,0), vMasksTexel.b );
  195. #if USE_PATTERN2
  196. vColorPattern2 = lerp( vColorPattern2, float3(0,0,1), vMasksTexel.b );
  197. #endif
  198. //colorize patterns
  199. vColorPattern1 = lerp( lerp( lerp( g_vPattern1Color1, g_vPattern1Color2, vColorPattern1.r ), g_vPattern1Color3, vColorPattern1.g ), g_vPattern1Color4, vColorPattern1.b );
  200. #if USE_PATTERN2
  201. vColorPattern2 = lerp( lerp( lerp( g_vPattern2Color1, g_vPattern2Color2, vColorPattern2.r ), g_vPattern2Color3, vColorPattern2.g ), g_vPattern2Color4, vColorPattern2.b );
  202. #endif
  203. //apply colorized patterns using per-pattern masks
  204. vColorTexel = lerp( vColorTexel, vColorPattern1, vMasksTexel.r );
  205. #if USE_PATTERN2
  206. vColorTexel = lerp( vColorTexel, vColorPattern2, vMasksTexel.g );
  207. #endif
  208. #if USE_PATTERN_OFFSET
  209. //darken seams caused by pattern offset
  210. float flPatternOffsetSeamMask = saturate( (abs(distAlphaMask - 0.5f) * 8.0f) + 0.5f);
  211. vColorTexel *= flPatternOffsetSeamMask;
  212. #endif
  213. #endif //USE_PATTERN1
  214. #if USE_LOGO1
  215. float fLogoMaskCavity = vAOTexel.b * pow( (1.0f - flCavityPostPow), g_fLogoWear );
  216. //logo1
  217. float4 vLogoColor = tex2D( LogoSampler, getLogoUV( i.vBaseUV_PatternUV.xy, g_vLogoOffset, g_fLogoScale, g_fLogoRotation ) );
  218. //apply logo with alpha
  219. vColorTexel.rgb = lerp( vColorTexel.rgb, vLogoColor.rgb, vLogoColor.a * fLogoMaskCavity );
  220. #if USE_LOGO2
  221. //logo2
  222. float4 vLogo2Color = tex2D( LogoSampler, getLogoUV( i.vBaseUV_PatternUV.xy, g_vLogo2Offset, g_fLogo2Scale, g_fLogo2Rotation ) );
  223. //apply logo2 with alpha
  224. vColorTexel.rgb = lerp( vColorTexel.rgb, vLogo2Color.rgb, vLogo2Color.a * fLogoMaskCavity );
  225. #endif
  226. #endif //USE_LOGO1
  227. //desaturate by cavity and apply grime
  228. vColorTexel = lerp( vColorTexel, dot(DESAT, vColorTexel) * vGrime.rgb, flCavityPostPow );
  229. //apply ao
  230. vColorTexel *= (2.0f * vAOTexel.r);
  231. #endif // NEED_COMPOSITE_INPUTS
  232. #if !(IS_3D_MODE) // (2d compositing)
  233. // draw pink squares onto the composite to make sure it's working
  234. //if ( fmod( i.vBaseUV_PatternUV.x, 0.1f ) < 0.05f && fmod( i.vBaseUV_PatternUV.y, 0.1f ) < 0.05f )
  235. //{
  236. // vColorTexel = float3(1,0,1);
  237. //}
  238. float4 cOut = float4( vColorTexel.rgb, 1 );
  239. return cOut;
  240. #else // (any 3d mode)
  241. // apply normal map driven lighting in 3d mode
  242. float3 vNormalTexel = 2.0f * (tex2D( NormalMapSampler, i.vBaseUV_PatternUV.xy ).rgb) - 1.0f;
  243. float3 vWorldPixelNormal = normalize( mul( (float3x3)i.tangentSpaceTranspose, vNormalTexel ) );
  244. //return float4( vNormalTexel, 1 );
  245. #if ( (CASCADED_SHADOW_MAPPING == 1) && (DYN_CSM_ENABLED == 1) )
  246. float flCSMShadow = CSMComputeShadowing( i.worldPos );
  247. #else
  248. float flCSMShadow = 1.0f;
  249. #endif
  250. float3 linearColor = PixelShaderDoLighting( i.worldPos, vWorldPixelNormal, float3( 0.1f, 0.1f, 0.1f),
  251. false, true, i.lightAtten, g_cAmbientCube, NormalizeSampler, NUM_LIGHTS, cLightInfo,
  252. USE_HALF_LAMBERT, false, NULL, flCSMShadow );
  253. #if IS_3D_POSTCOMPOSITE
  254. //incorporate AO from the offscreen buffer rendered earlier in the frame
  255. float2 vScreenPos = (i.vProjPos.xy / i.vProjPos.w) * g_fvConstRegister17.xy + g_fvConstRegister17.zw;
  256. vScreenPos += float2( 0.0005f, 0.0005f );
  257. float3 vAO = tex2D( SSAOMapSampler, vScreenPos).rgb;
  258. float flCenterDepth = length( g_vEyePos.xyz - i.worldPos.xyz );
  259. float flDepthFadeDistance = smoothstep( 500.0f, 400.f, flCenterDepth );
  260. linearColor = lerp( linearColor, linearColor * vAO, flDepthFadeDistance * SSAO_EFFECT_MULTIPLIER );
  261. #endif // IS_3D_POSTCOMPOSITE
  262. vColorTexel *= linearColor;
  263. //vColorTexel = linearColor;
  264. float4 cOut = float4( vColorTexel.rgb, 1 );
  265. return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR );
  266. #endif // any 3D mode
  267. #endif // not AO_MODE
  268. }