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.

250 lines
8.2 KiB

  1. //====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =======
  2. //
  3. //=============================================================================
  4. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  5. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  6. // STATIC: "BLUR" "0..1"
  7. // STATIC: "FADEOUTONSILHOUETTE" "0..1"
  8. // STATIC: "CUBEMAP" "0..1"
  9. // STATIC: "REFRACTTINTTEXTURE" "0..1"
  10. // STATIC: "MASKED" "0..1"
  11. // STATIC: "COLORMODULATE" "0..1"
  12. // STATIC: "SECONDARY_NORMAL" "0..1"
  13. // STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX]
  14. // STATIC: "NORMAL_DECODE_MODE" "0..0" [PC]
  15. // STATIC: "SHADER_SRGB_READ" "0..1" [ps20b]
  16. // DYNAMIC: "PIXELFOGTYPE" "0..1"
  17. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC]
  18. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX]
  19. // SKIP: $MASKED && $BLUR
  20. #if defined( SHADER_MODEL_PS_2_0 )
  21. # define WRITE_DEPTH_TO_DESTALPHA 0
  22. #endif
  23. #include "common_ps_fxc.h"
  24. #include "shader_constant_register_map.h"
  25. sampler NormalSampler2 : register( s1 );
  26. sampler RefractSampler : register( s2 );
  27. sampler NormalSampler : register( s3 );
  28. #if CUBEMAP
  29. sampler EnvmapSampler : register( s4 );
  30. #endif
  31. #if REFRACTTINTTEXTURE
  32. sampler RefractTintSampler : register( s5 );
  33. #endif
  34. #if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA
  35. sampler AlphaMapSampler : register( s6 ); // alpha
  36. sampler AlphaMapSampler2 : register( s7 );
  37. #else
  38. #define AlphaMapSampler2 NormalSampler
  39. #define AlphaMapSampler NormalSampler2
  40. #endif
  41. const float3 g_EnvmapTint : register( c0 );
  42. const float3 g_RefractTint : register( c1 );
  43. const float3 g_EnvmapContrast : register( c2 );
  44. const float3 g_EnvmapSaturation : register( c3 );
  45. const float4 g_c5 : register( c5 );
  46. #define g_RefractScale g_c5.x
  47. #define g_flTime g_c5.w
  48. const float4 g_FogParams : register( PSREG_FOG_PARAMS );
  49. const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT );
  50. static const int g_BlurCount = BLUR;
  51. static const float g_BlurFraction = 1.0f / 512.0f;
  52. static const float g_HalfBlurFraction = 0.5 * g_BlurFraction;
  53. static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction,
  54. -g_BlurFraction,-g_HalfBlurFraction );
  55. struct PS_INPUT
  56. {
  57. float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz
  58. float3 vTangentVertToEyeVector : TEXCOORD1;
  59. float3 vWorldNormal : TEXCOORD2;
  60. float3 vWorldTangent : TEXCOORD3;
  61. float3 vWorldBinormal : TEXCOORD4;
  62. float3 vRefractXYW : TEXCOORD5;
  63. float3 vWorldViewVector : TEXCOORD6;
  64. #if COLORMODULATE
  65. float4 ColorModulate : COLOR0;
  66. #endif
  67. float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog
  68. float4 fogFactorW : COLOR1;
  69. };
  70. float4 main( PS_INPUT i ) : COLOR
  71. {
  72. float3 result;
  73. float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
  74. #if FADEOUTONSILHOUETTE
  75. //float blend = -i.projNormal.z;
  76. float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) );
  77. blend = blend * blend * blend;
  78. #else
  79. float blend = 1.0f;
  80. #endif
  81. // Decompress normal
  82. float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORMAL_DECODE_MODE, AlphaMapSampler );
  83. #if SECONDARY_NORMAL
  84. float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORMAL_DECODE_MODE, AlphaMapSampler2 );
  85. vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz );
  86. #endif
  87. #if REFRACTTINTTEXTURE
  88. float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy );
  89. #else
  90. float3 refractTintColor = g_RefractTint;
  91. #endif
  92. #if COLORMODULATE
  93. refractTintColor *= i.ColorModulate.rgb;
  94. #endif
  95. // Perform division by W only once
  96. float ooW = 1.0f / i.vRefractXYW.z;
  97. // Compute coordinates for sampling refraction
  98. float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW;
  99. float2 vRefractTexCoord = vNormal.xy;
  100. float scale = vNormal.a * g_RefractScale;
  101. #if COLORMODULATE
  102. scale *= i.ColorModulate.a;
  103. #endif
  104. vRefractTexCoord *= scale;
  105. vRefractTexCoord += vRefractTexCoordNoWarp;
  106. #if (BLUR==1) // use polyphase magic to convert 9 lookups into 4
  107. // basic principle behind this transformation:
  108. // [ A B C ]
  109. // [ D E F ]
  110. // [ G H I ]
  111. // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]).
  112. // scale the upper 2x2 by 4/9 (total area of kernel occupied)
  113. // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F])
  114. // scale right 1x2 by 2/9
  115. // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H])
  116. // scale bottom 2x1 by 2/9
  117. // fetch last sample (I) and scale by 1/9.
  118. float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction);
  119. float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction);
  120. float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction);
  121. float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction);
  122. result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444;
  123. result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222;
  124. result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222;
  125. result += tex2D(RefractSampler, singleton_loc) * 0.1111111;
  126. #if ( SHADER_SRGB_READ == 1 )
  127. {
  128. // Just do this once rather than after every blur step, which is wrong, but much more efficient
  129. result = GammaToLinear( result );
  130. }
  131. #endif
  132. float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy);
  133. #if ( SHADER_SRGB_READ == 1 )
  134. {
  135. unblurredColor = GammaToLinear( unblurredColor );
  136. }
  137. #endif
  138. result = lerp(unblurredColor, result * refractTintColor, blend);
  139. #elif (BLUR>0) // iteratively step through render target
  140. int x, y;
  141. result = float3( 0.0f, 0.0f, 0.0f );
  142. for( x = -g_BlurCount; x <= g_BlurCount; x++ )
  143. {
  144. for( y = -g_BlurCount; y <= g_BlurCount; y++ )
  145. {
  146. result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) );
  147. }
  148. }
  149. int width = g_BlurCount * 2 + 1;
  150. result *= 1.0f / ( width * width );
  151. #if ( SHADER_SRGB_READ == 1 )
  152. {
  153. // Just do this once rather than after every blur step, which is wrong, but much more efficient
  154. result = GammaToLinear( result );
  155. }
  156. #endif
  157. // result is the blurred one now. . .now lerp.
  158. float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy );
  159. #if ( SHADER_SRGB_READ == 1 )
  160. {
  161. unblurredColor = GammaToLinear( unblurredColor );
  162. }
  163. #endif
  164. result = lerp( unblurredColor, result * refractTintColor, blend );
  165. #else
  166. # if MASKED
  167. float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy );
  168. #if ( SHADER_SRGB_READ == 1 )
  169. {
  170. fMaskedResult = GammaToLinear( fMaskedResult );
  171. }
  172. #endif
  173. return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
  174. # else
  175. float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy );
  176. #if ( SHADER_SRGB_READ == 1 )
  177. {
  178. colorWarp = GammaToLinear( colorWarp );
  179. }
  180. #endif
  181. float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy );
  182. #if ( SHADER_SRGB_READ == 1 )
  183. {
  184. colorNoWarp = GammaToLinear( colorNoWarp );
  185. }
  186. #endif
  187. colorWarp *= refractTintColor;
  188. result = lerp( colorNoWarp, colorWarp, blend );
  189. # endif
  190. #endif
  191. #if CUBEMAP
  192. float specularFactor = vNormal.a;
  193. float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal );
  194. float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector );
  195. float3 specularLighting = texCUBE( EnvmapSampler, reflectVect );
  196. specularLighting *= specularFactor;
  197. specularLighting *= g_EnvmapTint;
  198. float3 specularLightingSquared = specularLighting * specularLighting;
  199. specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
  200. float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) );
  201. specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
  202. result += specularLighting;
  203. #endif
  204. #if COLORMODULATE
  205. float resultAlpha = i.ColorModulate.a * vNormal.a;
  206. #else
  207. float resultAlpha = vNormal.a;
  208. #endif
  209. return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w );
  210. }