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.

152 lines
4.7 KiB

  1. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  2. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  3. // STATIC: "MULTITEXTURE" "0..1"
  4. // STATIC: "FRESNEL" "0..1"
  5. // STATIC: "BLEND" "0..1"
  6. // STATIC: "REFRACTALPHA" "0..1"
  7. // STATIC: "HDRTYPE" "0..2"
  8. // STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX]
  9. // STATIC: "NORMAL_DECODE_MODE" "0..0" [PC]
  10. // DYNAMIC: "HDRENABLED" "0..1"
  11. // DYNAMIC: "PIXELFOGTYPE" "0..1"
  12. #include "common_ps_fxc.h"
  13. const HALF3 g_WaterFogColor : register( c0 );
  14. const HALF4 g_CheapWaterParams : register( c1 );
  15. const HALF4 g_ReflectTint : register( c2 );
  16. const float4 g_PixelFogParams : register( c3 );
  17. #define g_CheapWaterStart g_CheapWaterParams.x
  18. #define g_CheapWaterEnd g_CheapWaterParams.y
  19. #define g_CheapWaterDeltaRecip g_CheapWaterParams.z
  20. #define g_CheapWaterStartDivDelta g_CheapWaterParams.w
  21. sampler EnvmapSampler : register( s0 );
  22. sampler NormalMapSampler : register( s1 );
  23. #if REFRACTALPHA
  24. sampler RefractSampler : register( s2 );
  25. #endif
  26. sampler NormalizeSampler : register( s6 );
  27. struct PS_INPUT
  28. {
  29. float2 normalMapTexCoord : TEXCOORD0;
  30. HALF3 worldSpaceEyeVect : TEXCOORD1;
  31. HALF3x3 tangentSpaceTranspose : TEXCOORD2;
  32. float4 vRefract_W_ProjZ : TEXCOORD5;
  33. #if MULTITEXTURE
  34. float4 vExtraBumpTexCoord : TEXCOORD6;
  35. #endif
  36. float4 fogFactorW : COLOR1;
  37. };
  38. float4 main( PS_INPUT i ) : COLOR
  39. {
  40. bool bBlend = BLEND ? true : false;
  41. #if MULTITEXTURE
  42. float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord );
  43. float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy );
  44. float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw );
  45. vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 );
  46. #if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N )
  47. vNormal.xy = vNormal.xy * 2.0f - 1.0f;
  48. vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) );
  49. #else
  50. vNormal = 2.0 * vNormal - 1.0;
  51. #endif
  52. #else
  53. float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORMAL_DECODE_MODE );
  54. #endif
  55. HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose );
  56. HALF3 worldSpaceEye;
  57. HALF flWorldSpaceDist = 1.0f;
  58. #ifdef NV3X
  59. // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes.
  60. if (bBlend)
  61. {
  62. worldSpaceEye = i.worldSpaceEyeVect;
  63. HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye );
  64. HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr );
  65. worldSpaceEye *= rcpWorldSpaceDist;
  66. flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist;
  67. }
  68. else
  69. {
  70. worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect );
  71. }
  72. #else // !NV3X
  73. if (bBlend)
  74. {
  75. worldSpaceEye = i.worldSpaceEyeVect;
  76. flWorldSpaceDist = length( worldSpaceEye );
  77. worldSpaceEye /= flWorldSpaceDist;
  78. }
  79. else
  80. {
  81. worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect );
  82. }
  83. #endif
  84. HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye );
  85. HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect );
  86. specularLighting *= g_ReflectTint;
  87. #if FRESNEL
  88. // FIXME: It's unclear that we want to do this for cheap water
  89. // but the code did this previously and I didn't want to change it
  90. HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal );
  91. flDotResult = 1.0f - max( 0.0f, flDotResult );
  92. HALF flFresnelFactor = flDotResult * flDotResult;
  93. flFresnelFactor *= flFresnelFactor;
  94. flFresnelFactor *= flDotResult;
  95. #else
  96. HALF flFresnelFactor = g_ReflectTint.a;
  97. #endif
  98. HALF flAlpha;
  99. if (bBlend)
  100. {
  101. HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta );
  102. flAlpha = saturate( flFresnelFactor + flReflectAmount );
  103. #if REFRACTALPHA
  104. // Perform division by W only once
  105. float ooW = 1.0f / i.vRefract_W_ProjZ.z;
  106. float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW;
  107. float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a;
  108. // Fade on the border between the water and land.
  109. flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f );
  110. #endif
  111. }
  112. else
  113. {
  114. flAlpha = 1.0f;
  115. #if HDRTYPE == 0 || HDRENABLED == 0
  116. specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor );
  117. #else
  118. specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor );
  119. #endif
  120. }
  121. // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders.
  122. #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE)
  123. float fogFactor = CalcRangeFog( i.vRefract_W_ProjZ.w, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w );
  124. #else
  125. float fogFactor = 0;
  126. #endif
  127. return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR );
  128. }