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.

569 lines
19 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // FIXMEL4DTOMAINMERGE
  3. // Need to re-enable bloom and disable other L4D-only features in here and the cpp file.
  4. // STATIC: "TOOL_MODE" "0..1"
  5. // STATIC: "DEPTH_BLUR_ENABLE" "0..1"
  6. // STATIC: "LINEAR_INPUT" "0..1" [ps20b] [ps30] [PC]
  7. // STATIC: "LINEAR_INPUT" "0..0" [ps20b] [CONSOLE]
  8. // STATIC: "LINEAR_OUTPUT" "0..1" [ps20b] [ps30] [PC]
  9. // STATIC: "LINEAR_OUTPUT" "0..0" [ps20b] [CONSOLE]
  10. // DYNAMIC: "AA_ENABLE" "0..0" [ps20] [ps20b] [PC]
  11. // DYNAMIC: "AA_ENABLE" "0..1" [ps30] [PC]
  12. // DYNAMIC: "AA_ENABLE" "0..1" [CONSOLE]
  13. // DYNAMIC: "COL_CORRECT_NUM_LOOKUPS" "0..3"
  14. // DYNAMIC: "CONVERT_FROM_LINEAR" "0..1" [ps20b] [ps30] [PC]
  15. // DYNAMIC: "CONVERT_TO_LINEAR" "0..1" [ps20b] [ps30] [PC]
  16. // DYNAMIC: "CONVERT_FROM_LINEAR" "0..0" [ps20b] [CONSOLE]
  17. // DYNAMIC: "CONVERT_TO_LINEAR" "0..0" [ps20b] [CONSOLE]
  18. // SKIP: ( $CONVERT_FROM_LINEAR == 0 ) && ( $CONVERT_TO_LINEAR == 1 )
  19. // SKIP: ( $TOOL_MODE == 0 ) && ( $CONVERT_FROM_LINEAR == 1 )
  20. // SKIP: ( $TOOL_MODE == 0 ) && ( $CONVERT_TO_LINEAR == 1 )
  21. // These are similar but mutually exclusive, the former for SFM PC and the latter for Mac
  22. // SKIP: ( $CONVERT_FROM_LINEAR == 1 ) && ( $LINEAR_INPUT == 1 )
  23. // SKIP: ( $CONVERT_TO_LINEAR == 1 ) && ( $LINEAR_OUTPUT == 1 )
  24. // DYNAMIC: "FADE_TO_BLACK" "0..1"
  25. // DYNAMIC: "FADE_TYPE" "0..2"
  26. // These two are enabled for PC, but only used in special cases
  27. // DYNAMIC: "NOISE_ENABLE" "0..0" [ps20b] [ps30] [PC]
  28. // DYNAMIC: "VIGNETTE_ENABLE" "0..1" [ps20b] [ps30] [PC]
  29. // DYNAMIC: "NOISE_ENABLE" "0..0" [ps20b] [CONSOLE]
  30. // DYNAMIC: "VIGNETTE_ENABLE" "0..1" [ps20b] [CONSOLE]
  31. // None of these effects are utilized by Portal 2, so they're always zero:
  32. // DYNAMIC: "LOCAL_CONTRAST_ENABLE" "0..1" [ps20b] [ps30]
  33. // DYNAMIC: "BLURRED_VIGNETTE_ENABLE" "0..1" [ps20b] [ps30]
  34. // DYNAMIC: "VOMIT_ENABLE" "0..0"
  35. // SKIP: ( $LOCAL_CONTRAST_ENABLE == 0 ) && ( $BLURRED_VIGNETTE_ENABLE == 1 )
  36. // DYNAMIC: "TV_GAMMA" "0..1" [ps20b] [ps30] [PC]
  37. // DYNAMIC: "DESATURATEENABLE" "0..1" [ps20b] [ps30] [PC]
  38. // SKIP: ( $TOOL_MODE == 0 ) && $TV_GAMMA
  39. // SKIP: ( $TOOL_MODE == 0 ) && $DESATURATEENABLE
  40. #include "common_ps_fxc.h"
  41. #define FXAA_ENABLE 1
  42. #include "fxaa3_11_fxc.h"
  43. sampler BaseTextureSampler : register( s0 );
  44. sampler FBTextureSampler : register( s1 );
  45. sampler3D ColorCorrectionVolumeTexture0 : register( s2 );
  46. sampler3D ColorCorrectionVolumeTexture1 : register( s3 );
  47. sampler3D ColorCorrectionVolumeTexture2 : register( s4 );
  48. sampler3D ColorCorrectionVolumeTexture3 : register( s5 );
  49. sampler NoiseSampler : register( s6 );
  50. sampler VignetteSampler : register( s7 );
  51. sampler ScreenEffectSampler : register( s8 ); // used for vomit/paint screen particle effects
  52. float4 psTapOffs_Packed : register( c0 ); // psTapOffs_packed contains 1-pixel offsets: ( +dX, 0, +dY, -dX )
  53. float4 tweakables : register( c1 ); // (x - AA strength/unused) (y - reduction of 1-pixel-line blur)
  54. // (z - edge threshold multipler) (w - tap offset multiplier)
  55. float4 uvTransform : register( c2 ); // Transform BaseTexture UVs for use with the FBTexture
  56. float ColorCorrectionDefaultWeight : register( c3 );
  57. float4 ColorCorrectionVolumeWeights : register( c4 );
  58. // Bloom & Depth Blur parameters
  59. // x: bloom amount; multiply bloom downscale buffer by this value and add to base color
  60. // y: bloom lerp amount; lerp between base color and blurred bloom buffer with this factor (allows for color bleeding in dark areas)
  61. // z: depth blur focal plane distance. Value is in dest alpha space [0,1], not world units.
  62. // w: depth blur scale value; scale distance from focal plane by this amount
  63. float4 BloomParameters : register( c5 );
  64. #define g_flBloomAmount ( BloomParameters.x )
  65. #define g_flBloomLerpFactor ( BloomParameters.y )
  66. #define g_flDepthBlurFocalDistance ( BloomParameters.z )
  67. #define g_flDepthBlurScale ( BloomParameters.w )
  68. float g_flNoiseScalar : register( c6 );
  69. float g_flTime : register( c7 );
  70. float4 g_vLocalContrastParams : register( c8 );
  71. #define g_flLocalContrastStrength g_vLocalContrastParams.x
  72. #define g_flLocalContrastMidToneMask g_vLocalContrastParams.y
  73. #define g_flBlurredVignetteStrength g_vLocalContrastParams.z
  74. float4 g_vLocalContrastVignetteParams : register( c9 );
  75. #define g_flLocalContrastVignetteStart g_vLocalContrastVignetteParams.x
  76. #define g_flLocalContrastVignetteEnd g_vLocalContrastVignetteParams.y
  77. #define g_flLocalContrastEdgeStrength g_vLocalContrastVignetteParams.z
  78. float g_flFadeToBlackStrength : register( c10 );
  79. float4 g_vVomitColor[2] : register( c11 );
  80. #define g_flVomitRefractStrength g_vVomitColor[0].a
  81. float4 g_vViewportTransform : register( c13 );
  82. float4 g_vInvViewportTransform : register( c14 );
  83. float4 g_vViewFadeColor : register( c15 );
  84. float g_flDesaturation : register( c16 );
  85. // FXAA consts
  86. float4 g_fxaaConsoleRcpFrameOpt : register( c17 );
  87. float4 g_fxaaConsoleRcpFrameOpt2 : register( c18 );
  88. float4 g_fxaaConsole360RcpFrameOpt2 : register( c19 );
  89. float4 g_fxaaConsoleEdge : register( c20 );
  90. float4 g_fxaaConsole360ConstDir : register( c21 );
  91. float4 g_fxaaQualityRcpFrame : register( c22 );
  92. float4 g_fxaaQualitySubpixEdge : register( c23 );
  93. HALF Luminance( HALF3 cColor )
  94. {
  95. HALF3 tmpv = { 0.2125f, 0.7154f, 0.0721f };
  96. HALF flLuminance = dot( cColor.rgb, tmpv.rgb );
  97. return flLuminance;
  98. }
  99. HALF LuminanceLinear( HALF3 cColor )
  100. {
  101. // Alternate formula for calculating luminance for linear RGB space (Widely used in color hue and saturation computations)
  102. HALF3 tmpv = { 0.3086f, 0.6094f, 0.0820f };
  103. HALF flLuminance = dot( cColor.rgb, tmpv.rgb );
  104. return flLuminance;
  105. }
  106. HALF4 GetBloomColor( float2 bloomUV )
  107. {
  108. HALF4 vBloomSample = tex2D( BaseTextureSampler, bloomUV );
  109. #if ( LINEAR_INPUT == 1 )
  110. {
  111. // In this case, which is only used on OpenGL, we want sRGB data from this tex2D.
  112. // Hence, we have to undo the sRGB conversion that we are forced to apply by OpenGL
  113. vBloomSample.rgb = SrgbLinearToGamma( vBloomSample.rgb );
  114. }
  115. #endif
  116. #if defined( _X360 )
  117. {
  118. #if defined( CSTRIKE15 )
  119. {
  120. // [mariod] - no pwl space for CS:GO
  121. }
  122. #else
  123. {
  124. // Since bloom is added in gamma space, the 360's PWL gamma space requires an artificial
  125. // dim factor to match the look of the PC and PS3. 0.5 works best for portal2
  126. vBloomSample.rgb *= 0.5f;
  127. vBloomSample.rgb = SrgbLinearToGamma( vBloomSample.rgb );
  128. }
  129. #endif
  130. }
  131. #endif
  132. // Scale bloom by 50% for all platforms
  133. vBloomSample.rgb *= 0.5f;
  134. return vBloomSample.rgba;
  135. }
  136. HALF4 PerformColorCorrection( HALF4 outColor )
  137. {
  138. #if ( COL_CORRECT_NUM_LOOKUPS > 0 )
  139. {
  140. // NOTE: This code requires the color correction texture to be 32 units to be correct.
  141. // This code will cause (0,0,0) to be read from 0.5f/32
  142. // and (1,1,1) to be read from 31.5f/32
  143. HALF4 offsetOutColor = outColor * (HALF)(31.0f / 32.0f) + (HALF)(0.5f / 32.0f);
  144. outColor.rgb = outColor.rgb * (HALF)ColorCorrectionDefaultWeight;
  145. #if ( defined( _PS3 ) )
  146. {
  147. outColor.rgb += h3tex3D( ColorCorrectionVolumeTexture0, offsetOutColor.rgb ).rgb * (HALF3)ColorCorrectionVolumeWeights.xxx;
  148. }
  149. #else
  150. {
  151. outColor.rgb += tex3D( ColorCorrectionVolumeTexture0, offsetOutColor.rgb ).rgb * ColorCorrectionVolumeWeights.xxx;
  152. }
  153. #endif
  154. if ( COL_CORRECT_NUM_LOOKUPS > 1 )
  155. {
  156. outColor.rgb += tex3D( ColorCorrectionVolumeTexture1, offsetOutColor.rgb ).rgb * ColorCorrectionVolumeWeights.yyy;
  157. if ( COL_CORRECT_NUM_LOOKUPS > 2 )
  158. {
  159. outColor.rgb += tex3D( ColorCorrectionVolumeTexture2, offsetOutColor.rgb ).rgb * ColorCorrectionVolumeWeights.zzz;
  160. if ( COL_CORRECT_NUM_LOOKUPS > 3 )
  161. {
  162. outColor.rgb += tex3D( ColorCorrectionVolumeTexture3, offsetOutColor.rgb ).rgb * ColorCorrectionVolumeWeights.www;
  163. }
  164. }
  165. }
  166. }
  167. #endif
  168. return outColor;
  169. }
  170. float3 PerformVomitBlend( float3 vRefractParams, float3 vFullResColor, float3 vBlurredColor )
  171. {
  172. #ifdef _PS3
  173. // Compensate for gamma badness. Turns out that the particle system rendering for the vomit effect
  174. // is blending is gamma space on ps3. Doing this to somewhat compensate for this.
  175. // Would do a sqrt here, but it introduces a lot of banding artifacts.
  176. vRefractParams.z = saturate( vRefractParams.z * 2.0f );
  177. #endif
  178. float3 vVomitColor = lerp( g_vVomitColor[0].rgb, g_vVomitColor[1].rgb, vRefractParams.z ); // vomit tint
  179. // Get the luminance of the color buffer.
  180. float vFullResLum = dot( vFullResColor, float3( 0.3, 0.59, 0.11 ) );
  181. // Tint color buffer with vomit color.
  182. vFullResColor.rgb = lerp( vFullResColor, vFullResLum * vVomitColor, saturate( 1.0f * vRefractParams.z ) ); // vomit tint full-res buffer
  183. // blend to the solid vomit color so that the color is more apparent.
  184. vFullResColor.rgb = lerp( vFullResColor, vVomitColor, 1.0f * vRefractParams.z ); // vomit tint full-res buffer
  185. // blend in blurred backbuffer.
  186. vFullResColor.rgb = lerp ( vFullResColor.rgb, vVomitColor.rgb * vBlurredColor.rgb, saturate( 1.0f * vRefractParams.z ) );
  187. return vFullResColor.rgb;
  188. }
  189. // Apply TV Gamma for movie layoff specific to 360 TV movie playback path
  190. float3 SrgbGammaToTvGamma( float3 cInput )
  191. {
  192. float3 cLinear = SrgbGammaToLinear( cInput );
  193. return pow( cLinear, 1.0f / 2.5f );
  194. }
  195. /*============================================================================*/
  196. struct PS_INPUT
  197. {
  198. float4 bloombaseCoords : TEXCOORD0;
  199. float4 fxaaCoords : TEXCOORD1;
  200. };
  201. float4_color_return_type main( PS_INPUT i ) : COLOR
  202. {
  203. // float4 fbTexCoord = float4( i.bloomCoords, i.baseCoords );
  204. float4 fbTexCoord = i.bloombaseCoords;
  205. HALF4 cBloomBlurredLum = GetBloomColor( i.bloombaseCoords.zw ); // bloom color and blurred luminance in alpha
  206. float4 vVomitRefractParams;
  207. #if ( VOMIT_ENABLE == 1 )
  208. {
  209. // perturb texture coordinate
  210. vVomitRefractParams = tex2D( ScreenEffectSampler, i.bloombaseCoords.zw );
  211. fbTexCoord = fbTexCoord + g_flVomitRefractStrength * ( vVomitRefractParams.xyxy - 0.5 );
  212. #if !defined( SHADER_MODEL_PS_2_0 )
  213. {
  214. // screen coords -> viewport coords
  215. float4 vNormalizedTexCoord = g_vViewportTransform.xyxy * fbTexCoord + g_vViewportTransform.zwzw;
  216. // mirrored repeat texcoord math doesn't fit into 2.0
  217. vNormalizedTexCoord = min( 2.0 - vNormalizedTexCoord, abs( vNormalizedTexCoord ) );
  218. // viewport coords -> screen coords
  219. fbTexCoord = g_vInvViewportTransform.xyxy * vNormalizedTexCoord + g_vInvViewportTransform.zwzw;
  220. cBloomBlurredLum = GetBloomColor( fbTexCoord.zw ); // fetch again with perturbed texcoords
  221. }
  222. #else
  223. {
  224. cBloomBlurredLum = GetBloomColor( fbTexCoord.xy ); // fetch again with perturbed texcoords
  225. }
  226. #endif
  227. }
  228. #endif
  229. #if ( defined( _PS3 ) )
  230. HALF4 rawColor = h4tex2D( FBTextureSampler, fbTexCoord.xy ).rgba;
  231. #else
  232. HALF4 rawColor = tex2D( FBTextureSampler, fbTexCoord.xy ).rgba;
  233. #endif
  234. HALF3 baseColor = rawColor.rgb;
  235. float depthValue = rawColor.a;
  236. #if ( CONVERT_FROM_LINEAR == 1 )
  237. {
  238. baseColor.rgb = SrgbLinearToGamma( baseColor.rgb );
  239. }
  240. #endif
  241. HALF4 outColor = HALF4( baseColor, 1 );
  242. // In this case, which is only used on OpenGL, we have linear inputs.
  243. // This means we converted to sRGB prior to accessing the color correction textures.
  244. #if ( LINEAR_INPUT )
  245. {
  246. outColor.rgb = SrgbLinearToGamma( saturate( outColor.rgb ) );
  247. }
  248. #endif
  249. #if ( AA_ENABLE == 1 )
  250. {
  251. half3 aaRGB;
  252. #if ( FXAA_ENABLE == 1 )
  253. {
  254. // FXAA for all platforms if using software AA
  255. //
  256. // args - compute in shader where necessary for now, use shader constants when working
  257. // see fxaa3_11_fxc.h for documentation on arguments
  258. //
  259. //
  260. FxaaFloat2 pos = fbTexCoord.xy;
  261. //
  262. FxaaFloat4 fxaaConsolePosPos = i.fxaaCoords;
  263. // tex = FBTextureSampler
  264. // fxaaConsole360TexExpBiasNegOne - FIXME: just use tex and do the biasing in shader for now
  265. // fxaaConsole360TexExpBiasNegTwo - "
  266. // do FXAA
  267. aaRGB = FxaaPixelShader( pos,
  268. fxaaConsolePosPos,
  269. FBTextureSampler, FBTextureSampler, FBTextureSampler,
  270. g_fxaaQualityRcpFrame,
  271. g_fxaaConsoleRcpFrameOpt,
  272. g_fxaaConsoleRcpFrameOpt2,
  273. g_fxaaConsole360RcpFrameOpt2,
  274. g_fxaaQualitySubpixEdge.x, // QualitySubpix
  275. g_fxaaQualitySubpixEdge.z, // QualityEdgeThreshold
  276. g_fxaaQualitySubpixEdge.w, // QualityEdgeThresholdMin
  277. g_fxaaConsoleEdge.y, // ConsoleEdgeSharpness
  278. g_fxaaConsoleEdge.z, // ConsoleEdgeThreshold,
  279. g_fxaaConsoleEdge.w, // ConsoleThresholdMin,
  280. g_fxaaConsole360ConstDir );
  281. }
  282. #else
  283. {
  284. // TODO: put old code back here?
  285. aaRGB = ouColor.rgb;
  286. }
  287. #endif
  288. outColor.rgb = aaRGB;
  289. }
  290. #endif
  291. #if ( VOMIT_ENABLE == 1 )
  292. {
  293. outColor.rgb = PerformVomitBlend( vVomitRefractParams.xyz, outColor.rgb, cBloomBlurredLum.aaa );
  294. }
  295. #endif
  296. #if ( LOCAL_CONTRAST_ENABLE == 1 )
  297. {
  298. HALF fMask = 1.0;
  299. // Extract midtones and limit contrast enhancement there
  300. // TODO: This can probably go away for perf.
  301. //float fBrightness = dot( outColor.rgb, float3( 0.3, 0.59, 0.11 ) );
  302. // bell-shaped mask
  303. //fMask = smoothstep( 0.5 - g_flLocalContrastMidToneMask, 0.5, fBrightness );
  304. //fMask *= smoothstep( 0.5 + g_flLocalContrastMidToneMask, 0.5, fBrightness );
  305. //fMask = smoothstep( 1.0, 0.5, fBrightness );
  306. /*
  307. // unsharp mask on luminance only
  308. // This is the technically correct way, going to YUV, applying contrast to Y, and converting back to RGB
  309. float3 outColorYUV;
  310. outColorYUV.x = dot( outColor.rgb, float3( 0.299, 0.587, 0.114 ) );
  311. outColorYUV.y = dot( outColor.rgb, float3( -0.14713, -0.28886, 0.436 ) );
  312. outColorYUV.z = dot( outColor.rgb, float3( 0.615, -0.51499, -0.10001 ) );
  313. outColorYUV.x = outColorYUV.x + g_flLocalContrastStrength * fMask * ( outColorYUV.x - cBloomBlurredLum.aaa );
  314. outColor.r = dot( outColorYUV.xyz, float3( 1.0, 0.0, 1.13983 ) );
  315. outColor.g = dot( outColorYUV.xyz, float3( 1.0, -0.39465, -0.58060 ) );
  316. outColor.b = dot( outColorYUV.xyz, float3( 1.0, 2.03211, 0.0 ) );
  317. */
  318. // This applies the delta contrast derived from the luminance to all color channels. The difference to the
  319. // correct way is imperceptible.
  320. HALF fLuminance = dot( outColor.rgb, HALF3( 0.299, 0.587, 0.114 ) );
  321. HALF fContrastLum = fLuminance + (HALF)g_flLocalContrastStrength * ( fLuminance - cBloomBlurredLum.a );
  322. // Mask off pixels that got very bright, to control super-contrast
  323. //fMask = 1.0 - smoothstep( 0.3, 1.0, fContrastLum );
  324. HALF2 vCenterDir = ( (HALF)2.0f * (HALF2)i.bloombaseCoords.zw ) - (HALF)1.0f;
  325. HALF fMyVignette = smoothstep( (HALF)g_flLocalContrastVignetteStart, (HALF)g_flLocalContrastVignetteEnd, length( vCenterDir ) );
  326. HALF fMyVignette2 = fMyVignette;
  327. fMyVignette = lerp( (HALF)g_flLocalContrastStrength, (HALF)g_flLocalContrastEdgeStrength, fMyVignette );
  328. fMask = fMyVignette;
  329. // If the mask is positive, only brighten pixels. If the mask is negative, don't let it get less than -1.0.
  330. //outColor.rgb += fMask * ( fLuminance - cBloomBlurredLum.aaa );
  331. outColor.rgb += max( fMask * ( fLuminance - cBloomBlurredLum.aaa ), (HALF)-1.0f + step( (HALF)0.0f, fMask ) ); // Selective clamp to positive adds 4 instructions
  332. #if ( BLURRED_VIGNETTE_ENABLE == 1 )
  333. outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.aaa, fMyVignette2 * (HALF)g_flBlurredVignetteStrength );
  334. #endif
  335. }
  336. #endif
  337. // Composite bloom and full-screen + depth blur effects
  338. #if ( DEPTH_BLUR_ENABLE )
  339. {
  340. float blurFactor = g_flBloomLerpFactor + abs( depthValue - g_flDepthBlurFocalDistance ) * g_flDepthBlurScale;
  341. blurFactor = clamp( blurFactor, 0, 1 );
  342. outColor.rgb = lerp( outColor.rgb, cBloomBlurredLum.rgb, blurFactor );
  343. outColor.rgb += g_flBloomAmount * cBloomBlurredLum.rgb;
  344. }
  345. #else
  346. {
  347. outColor.rgb += (HALF)g_flBloomAmount * (HALF3)cBloomBlurredLum.rgb;
  348. }
  349. #endif
  350. #if ( FADE_TYPE == 1 )
  351. {
  352. outColor.rgb = lerp( outColor.rgb, (HALF3)g_vViewFadeColor.rgb, (HALF3)g_vViewFadeColor.aaa );
  353. }
  354. #elif ( FADE_TYPE == 2 )
  355. {
  356. outColor.rgb = lerp( outColor.rgb, (HALF3)g_vViewFadeColor.rgb * outColor.rgb, (HALF3)g_vViewFadeColor.aaa );
  357. }
  358. #endif
  359. #if ( DESATURATEENABLE )
  360. {
  361. float flLum = saturate( dot( outColor.rgb, HALF3( 0.3f, 0.59f, 0.11f) ) );
  362. outColor.rgb = lerp( saturate( outColor.rgb ), flLum.xxx, saturate( g_flDesaturation ) );
  363. }
  364. #else
  365. {
  366. outColor = PerformColorCorrection( outColor ); // Color correction
  367. }
  368. #endif
  369. // Vignette
  370. #if ( VIGNETTE_ENABLE == 1 )
  371. {
  372. // Vignette
  373. float2 vUv = i.bloombaseCoords.zw;
  374. float2 vTmp = ( vUv.xy * 2.0 ) - 1.0;
  375. float flVignette;
  376. #if ( defined( _X360 ) ) && ( !defined( CSTRIKE15 ) )
  377. {
  378. // Make title safe and deal with different gamma space
  379. flVignette = 1.0 - pow( abs( vTmp.x ), 4.0f );
  380. flVignette *= 1.0 - pow( abs( vTmp.y ), 4.0f );
  381. flVignette = 1.0 - ( 1.0 - flVignette ) * ( ( saturate( ( 1.0 - vUv.y ) - 0.1 ) / 0.9 ) );
  382. // This tex2D solves the 3 lines of math above
  383. //flVignette = tex2D( VignetteSampler, vUv.xy ).g; // Green is for the 360
  384. //flVignette = saturate( flVignette * 0.75 + 0.26 );
  385. }
  386. #else
  387. {
  388. flVignette = 1.0 - pow( abs( vTmp.x ), 6.0f );
  389. flVignette *= 1.0 - pow( abs( vTmp.y ), 6.0f );
  390. flVignette = 1.0 - ( 1.0 - flVignette ) * ( ( saturate( ( 1.0 - vUv.y ) - 0.3 ) / 0.7 ) );
  391. // This tex2D solves the 3 lines of math above
  392. //flVignette = tex2D( VignetteSampler, vUv.xy ).r; // Red is for the PC
  393. //flVignette = saturate( flVignette * 0.55 + 0.46 );
  394. }
  395. #endif
  396. // Artificially lighten the vignette. We may have to tune this differently for the 360.
  397. //outColor.rgb *= ( flVignette * 0.75 ) + 0.25;
  398. outColor.rgb *= ( flVignette * 0.33 ) + 0.67;
  399. }
  400. #endif
  401. // Noise
  402. #if ( NOISE_ENABLE == 1 )
  403. {
  404. // Additive Noise
  405. float2 vUv0 = i.bloombaseCoords.zw * 10.0 + g_flTime;
  406. float2 vUv1 = i.bloombaseCoords.wz * 20.0 - g_flTime;
  407. float2 vNoiseTexelUv;
  408. vNoiseTexelUv.x = tex2D( NoiseSampler, vUv0.xy ).g;
  409. vNoiseTexelUv.y = tex2D( NoiseSampler, vUv1.xy ).g;
  410. float flNoiseTexel = tex2D( NoiseSampler, vNoiseTexelUv.xy ).g;
  411. HALF3 vTmp = { 0.2125f, 0.7154f, 0.0721f };
  412. float flLuminance = saturate( dot( outColor.rgb, vTmp.rgb ) );
  413. #if defined( _X360 ) && !defined( CSTRIKE15 )
  414. {
  415. // 360
  416. float flNoiseScalar = 0.2f + 1.0f * ( saturate( pow( 1.0 - flLuminance, 64.0 ) ) );
  417. outColor.rgb += ( ( flNoiseTexel * 0.3f ) - 0.15f ) * g_flNoiseScalar * flNoiseScalar;
  418. }
  419. #else
  420. {
  421. // PC
  422. float flNoiseScalar = 0.2f + 0.8f * ( saturate( pow( 1.0 - flLuminance, 12.0 ) ) );
  423. outColor.rgb += ( ( flNoiseTexel * 0.3f ) - 0.15f ) * g_flNoiseScalar * flNoiseScalar;
  424. }
  425. #endif
  426. }
  427. #endif
  428. #if ( FADE_TO_BLACK )
  429. {
  430. // Fade to black
  431. outColor.rgb = lerp( outColor.rgb, (HALF3)0.0f, (HALF)g_flFadeToBlackStrength );
  432. }
  433. #endif
  434. #if TV_GAMMA
  435. {
  436. // Used for SFM to record movies in native TV gamma space
  437. outColor.rgb = SrgbGammaToTvGamma( outColor.rgb );
  438. }
  439. #endif
  440. #if ( CONVERT_TO_LINEAR == 1 )
  441. {
  442. // If we have a float back buffer, we want to remain in linear space after this shader
  443. outColor.rgb = SrgbGammaToLinear( outColor.rgb );
  444. }
  445. #endif
  446. outColor = FinalOutput( outColor, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  447. // Go to linear since we're forced to do an sRGB write on OpenGL in ps2b
  448. #if ( LINEAR_OUTPUT )
  449. {
  450. outColor.rgb = SrgbGammaToLinear( outColor.rgb );
  451. }
  452. #endif
  453. /* Debug code for evaluating gamma spaces from the framebuffer to the TV
  454. outColor.rgba = 0;
  455. float flTmp = saturate( i.bloombaseCoords.z * 1.2 - 0.1 );
  456. if ( ( flTmp <= 0.0f ) || ( flTmp >= 1.0f ) )
  457. flTmp = 0.5f;
  458. #if defined( _X360 )
  459. outColor.rgb = X360LinearToGamma( flTmp );
  460. #else
  461. outColor.rgb = SrgbLinearToGamma( flTmp );
  462. #endif
  463. //*/
  464. return outColor;
  465. }