Team Fortress 2 Source Code as on 22/4/2020
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.

189 lines
7.3 KiB

  1. //====== Copyright � 1996-2007, Valve Corporation, All rights reserved. ===========================
  2. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  3. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  4. // DYNAMIC: "QUALITY" "0..3"
  5. #ifdef HDRTYPE
  6. #undef HDRTYPE
  7. #endif
  8. #define HDRTYPE HDR_TYPE_NONE
  9. // Includes =======================================================================================
  10. #include "common_ps_fxc.h"
  11. // Texture Samplers ===============================================================================
  12. sampler g_tTexSampler : register( s0 );
  13. // Shaders Constants and Globals ==================================================================
  14. float g_flMaxMotionBlur : register( c0 );
  15. float4 g_vConst5 : register( c1 );
  16. #define g_vGlobalBlurVector g_vConst5.xy
  17. #define g_flFallingMotionIntensity g_vConst5.z
  18. #define g_flRollBlurIntensity g_vConst5.w
  19. // Interpolated values ============================================================================
  20. struct PS_INPUT
  21. {
  22. float2 vUv0 : TEXCOORD0;
  23. };
  24. // Main ===========================================================================================
  25. float4 main( PS_INPUT i ) : COLOR
  26. {
  27. // Calculate blur vector
  28. float2 vFallingMotionBlurVector = ( ( i.vUv0.xy * 2.0f ) - 1.0f );
  29. float2 vRollBlurVector = cross( float3( vFallingMotionBlurVector.xy, 0.0f ), float3( 0.0f, 0.0f, 1.0f ) ).xy;
  30. float2 vGlobalBlurVector = g_vGlobalBlurVector;
  31. vGlobalBlurVector.y = -vGlobalBlurVector.y;
  32. //vGlobalBlurVector.xy = float2( 1.0f, 0.0f ); // For debugging
  33. float flFallingMotionBlurIntensity = -abs( g_flFallingMotionIntensity ); // Keep samples on screen by keeping vector pointing in
  34. //flFallingMotionBlurIntensity = step( 10, abs(g_flFallingMotionIntensity) ); // For finding the sweet spot in debug mode
  35. vFallingMotionBlurVector.xy *= dot( vFallingMotionBlurVector.xy, vFallingMotionBlurVector.xy ); // Dampen the effect in the middle of the screen
  36. vFallingMotionBlurVector.xy *= flFallingMotionBlurIntensity;
  37. float flRollBlurIntensity = g_flRollBlurIntensity;
  38. vRollBlurVector.xy *= flRollBlurIntensity;
  39. float2 vFinalBlurVector = vGlobalBlurVector.xy + vFallingMotionBlurVector.xy + vRollBlurVector.xy;
  40. // Clamp length of blur vector to unit length
  41. //vFinalBlurVector.xy = max( -1.0f, min( 1.0f, vFinalBlurVector.xy ) );
  42. if ( length( vFinalBlurVector.xy ) > g_flMaxMotionBlur )
  43. {
  44. vFinalBlurVector.xy = normalize( vFinalBlurVector.xy ) * g_flMaxMotionBlur;
  45. }
  46. // Set number of samples
  47. #if QUALITY == 0
  48. const int kNumSamples = 1;
  49. #endif
  50. #if QUALITY == 1
  51. const int kNumSamples = 7;
  52. #endif
  53. #if QUALITY == 2
  54. const int kNumSamples = 11;
  55. #endif
  56. #if QUALITY == 3
  57. const int kNumSamples = 15;
  58. #endif
  59. float4 cColor = { 0.0f, 0.0f, 0.0f, 0.0f };
  60. float2 vUvOffset = vFinalBlurVector.xy / ( kNumSamples - 1 );
  61. for ( int x=0; x<kNumSamples; x++ )
  62. {
  63. // Calculate uv
  64. float2 vUvTmp = i.vUv0.xy + ( vUvOffset.xy * x );
  65. // Sample pixel
  66. //cColor += kernel[x] * tex2D( g_tTexSampler, vUvTmp ); // Use kernal from above
  67. cColor += ( 1.0f / kNumSamples ) * tex2D( g_tTexSampler, vUvTmp ); // Evenly weight all samples
  68. }
  69. /*
  70. // Brute-force experimental code to keep colors in NTSC and PAL gamut, but I don't think this will work correctly.
  71. // I think we need to know the final RGB values sent to the TV, which would mean applying the final HW gamma curve first
  72. // to each RGB chanel and then just subtracting 191 instead of the funky algorithm here. Then the results would need to
  73. // to be converted back to the 360 gamma PWL space and applied here to cColor.rgb. Too much effort right now.
  74. #if QUALITY == 30
  75. // This washes out the darks...no good
  76. float flLargest360GammaValue = max( max( cColor.r, cColor.g ), cColor.b );
  77. float flLargestFinalGamma25Value = pow( SrgbLinearToGamma( X360GammaToLinear( flLargest360GammaValue ) ), ( 2.5f / 2.2f ) ) * ( 219.0f / 255.0f ) + ( 16.0f / 255.0f );
  78. float flSmallestFinalGamma25ValueAllowed = saturate( flLargestFinalGamma25Value - ( 191.0f / 255.0f ) );
  79. float flSmallest360GammaValueAllowed = X360LinearToGamma( SrgbGammaToLinear( pow( ( flSmallestFinalGamma25ValueAllowed - ( 16.0f / 255.0f ) ) / ( 219.0f / 255.0f ), ( 2.2f / 2.5f ) ) ) );
  80. cColor.rgb = max( flSmallest360GammaValueAllowed, cColor.rgb );
  81. #endif
  82. #if QUALITY == 3
  83. // This brings down the saturated colors. I think the 360 hardware is already doing this for us
  84. float flSmallest360GammaValue = min( min( cColor.r, cColor.g ), cColor.b );
  85. float flSmallestFinalGamma25Value = pow( SrgbLinearToGamma( X360GammaToLinear( flSmallest360GammaValue ) ), ( 2.5f / 2.2f ) ) * ( 219.0f / 255.0f ) + ( 16.0f / 255.0f );
  86. float flLargestFinalGamma25ValueAllowed = saturate( flSmallestFinalGamma25Value + ( 191.0f / 255.0f ) );
  87. float flLargest360GammaValueAllowed = X360LinearToGamma( SrgbGammaToLinear( pow( ( flLargestFinalGamma25ValueAllowed - ( 16.0f / 255.0f ) ) / ( 219.0f / 255.0f ), ( 2.2f / 2.5f ) ) ) );
  88. cColor.rgb = min( flLargest360GammaValueAllowed, cColor.rgb );
  89. #endif
  90. //*/
  91. //return float4( cColor.rgb, 1.0f );
  92. return FinalOutput( float4( cColor.rgb, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  93. // This is histogram testing code that I need access to for a while on other machines to tweak the 360
  94. /*
  95. if ( 1 )
  96. {
  97. float4 cColor = { 0.0f, 0.0f, 0.0f, 0.0f };
  98. float2 uv = ( i.vUv0.xy * 1.2f - 0.1 );
  99. if ( ( uv.x < 0.0f ) || ( uv.x > 1.0f ) || ( uv.y < 0.0f ) || ( uv.y > 1.0f ) )
  100. {
  101. cColor.rgb = float3( 1.0f, 0.0f, 0.0f ) * ( 1 - abs( uv.x ) );
  102. }
  103. else
  104. {
  105. cColor.rgb = uv.x;
  106. //cColor = tex2D( g_tTexSampler, uv.xy );
  107. // Simulate 360 sRGB read
  108. //float3 v360Linear = { X360GammaToLinear( cColor.r ), X360GammaToLinear( cColor.g ), X360GammaToLinear( cColor.b ) };
  109. //cColor.rgb = v360Linear.rgb;
  110. // On the PC, simulate the remapping for the 360
  111. }
  112. // Blue ruler
  113. if ( ( uv.y <= 1.0f ) && ( uv.x >= 0.0f ) && ( uv.x <= 1.0f ) )
  114. {
  115. if ( uv.y > 0.9f )
  116. {
  117. if ( frac( uv.x * 10.0f ) < 0.01f )
  118. {
  119. cColor.rgb = float3( 0.0f, 0.0f, 1.0f );
  120. }
  121. }
  122. if ( uv.y > 0.925f )
  123. {
  124. if ( frac( uv.x * 20.0f ) < 0.02f )
  125. {
  126. cColor.rgb = float3( 0.0f, 0.0f, 1.0f );
  127. }
  128. }
  129. if ( uv.y > 0.95f )
  130. {
  131. if ( frac( uv.x * 100.0f ) < 0.1f )
  132. {
  133. cColor.rgb = float3( 0.0f, 0.0f, 1.0f );
  134. }
  135. }
  136. }
  137. //if ( ( uv.x >= 0.0f ) && ( uv.x <= 1.0f ) && ( uv.y >= 0.0f ) && ( uv.y <= 1.0f ) )
  138. //{
  139. // cColor = tex2D( g_tTexSampler, uv.xy );
  140. //}
  141. float3 vShaderColor = cColor.rgb;
  142. float3 v360Linear = { SrgbGammaToLinear( vShaderColor.r ), SrgbGammaToLinear( vShaderColor.g ), SrgbGammaToLinear( vShaderColor.b ) };
  143. cColor.rgb = v360Linear.rgb;
  144. //float3 v360Gamma = { X360LinearToGamma( v360Linear.r ), X360LinearToGamma( v360Linear.g ), X360LinearToGamma( v360Linear.b ) };
  145. //cColor.rgb = v360Gamma.rgb;
  146. //float3 vGamma = { SrgbLinearToGamma( vShaderColor.r ), SrgbLinearToGamma( vShaderColor.g ), SrgbLinearToGamma( vShaderColor.b ) };
  147. //float3 v360Linear = { X360GammaToLinear( vShaderColor.r ), X360GammaToLinear( vShaderColor.g ), X360GammaToLinear( vShaderColor.b ) };
  148. //cColor.rgb = v360Linear.rgb;
  149. // Simulate 360 sRGB write
  150. //float3 v360Gamma = { X360LinearToGamma( vShaderColor.r ), X360LinearToGamma( vShaderColor.g ), X360LinearToGamma( vShaderColor.b ) };
  151. //cColor.rgb = v360Gamma.rgb;
  152. return cColor;
  153. }
  154. //*/
  155. }