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.

190 lines
5.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: "BASETEXTURE" "0..1"
  4. // STATIC: "REFLECT" "0..1"
  5. // STATIC: "REFRACT" "0..1"
  6. // STATIC: "ENVMAPMASK" "0..1"
  7. // DYNAMIC: "PIXELFOGTYPE" "0..1"
  8. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC]
  9. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX]
  10. #if defined( SHADER_MODEL_PS_2_0 )
  11. # define WRITE_DEPTH_TO_DESTALPHA 0
  12. #endif
  13. #include "common_ps_fxc.h"
  14. sampler RefractSampler : register( s0 );
  15. sampler BaseTextureSampler : register( s1 );
  16. sampler ReflectSampler : register( s2 );
  17. #if BASETEXTURE
  18. sampler LightmapSampler : register( s3 );
  19. #endif
  20. #if ENVMAPMASK
  21. sampler EnvMapMaskSampler : register( s6 );
  22. #endif
  23. sampler NormalSampler : register( s4 );
  24. const HALF4 vRefractTint : register( c1 );
  25. const float4 g_FresnelConstants : register( c3 );
  26. const HALF4 vReflectTint : register( c4 );
  27. const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale
  28. const float4 g_PixelFogParams : register( c8 );
  29. static const bool g_bReflect = REFLECT ? true : false;
  30. static const bool g_bRefract = REFRACT ? true : false;
  31. struct PS_INPUT
  32. {
  33. float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0;
  34. half3 vTangentEyeVect : TEXCOORD1;
  35. float4 vReflectXY_vRefractYX : TEXCOORD2;
  36. float W : TEXCOORD3;
  37. float4 vProjPos : TEXCOORD4;
  38. float screenCoord : TEXCOORD5;
  39. #if BASETEXTURE
  40. // CENTROID: TEXCOORD6
  41. HALF4 lightmapTexCoord1And2 : TEXCOORD6;
  42. // CENTROID: TEXCOORD7
  43. HALF4 lightmapTexCoord3 : TEXCOORD7;
  44. #endif
  45. float4 fogFactorW : COLOR1;
  46. };
  47. float4 main( PS_INPUT i ) : COLOR
  48. {
  49. // Load normal and expand range
  50. HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoordXY_vTexCoordXY.xy );
  51. HALF3 vNormal = normalize( vNormalSample * 2.0 - 1.0 );
  52. // Perform division by W only once
  53. float ooW = 1.0f / i.W;
  54. float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW;
  55. float4 reflectRefractScale = g_ReflectRefractScale;
  56. // Compute coordinates for sampling Reflection
  57. float2 vReflectTexCoord;
  58. float2 vRefractTexCoord;
  59. // vectorize the dependent UV calculations (reflect = .xy, refract = .wz)
  60. #ifdef NV3X
  61. float4 vDependentTexCoords = vNormal.xyxy * vNormalSample.a * reflectRefractScale;
  62. #else
  63. float4 vN;
  64. vN.xy = vNormal.xy;
  65. vN.w = vNormal.x;
  66. vN.z = vNormal.y;
  67. float4 vDependentTexCoords = vN * vNormalSample.a * reflectRefractScale;
  68. #endif
  69. vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW );
  70. vReflectTexCoord = vDependentTexCoords.xy;
  71. vRefractTexCoord = vDependentTexCoords.wz;
  72. // Sample reflection and refraction
  73. HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord );
  74. HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord );
  75. vReflectColor *= vReflectTint;
  76. vRefractColor *= vRefractTint;
  77. half3 vEyeVect;
  78. vEyeVect = normalize( i.vTangentEyeVect );
  79. // Fresnel term
  80. HALF fNdotV = saturate( dot( vEyeVect, vNormal ) );
  81. HALF fFresnelScalar = g_FresnelConstants.x * pow( 1.0 - fNdotV, g_FresnelConstants.y ) + g_FresnelConstants.z;
  82. HALF4 fFresnel = HALF4( fFresnelScalar, fFresnelScalar, fFresnelScalar, fFresnelScalar );
  83. #if BASETEXTURE
  84. float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoordXY_vTexCoordXY.zw );
  85. HALF2 bumpCoord1;
  86. HALF2 bumpCoord2;
  87. HALF2 bumpCoord3;
  88. ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
  89. bumpCoord1, bumpCoord2, bumpCoord3 );
  90. HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 );
  91. HALF3 lightmapColor1 = lightmapSample1.rgb;
  92. HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 );
  93. HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 );
  94. float3 dp;
  95. dp.x = saturate( dot( vNormal, bumpBasis[0] ) );
  96. dp.y = saturate( dot( vNormal, bumpBasis[1] ) );
  97. dp.z = saturate( dot( vNormal, bumpBasis[2] ) );
  98. dp *= dp;
  99. float3 diffuseLighting = dp.x * lightmapColor1 +
  100. dp.y * lightmapColor2 +
  101. dp.z * lightmapColor3;
  102. float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
  103. diffuseLighting *= LIGHT_MAP_SCALE / sum;
  104. HALF3 diffuseComponent = baseSample.rgb * diffuseLighting;
  105. #endif
  106. float4 flMask;
  107. #if ENVMAPMASK
  108. flMask = tex2D( EnvMapMaskSampler, i.vBumpTexCoordXY_vTexCoordXY.zw );
  109. #else
  110. flMask = float4( 1.0f, 1.0f, 1.0f, 1.0f );
  111. #endif
  112. // NOTE: the BASETEXTURE path hasn't been tested (or really written for that matter, just copied from water)
  113. // What I think should happen is that the alpha of base texture should be its 'translucency'
  114. // which should indicate how much refraction to use.
  115. // We should add an envmapmask to deal with how much reflection to use
  116. // along with all the focus, etc. features
  117. float4 result;
  118. float flAlpha = 1.0f;
  119. if( g_bReflect && g_bRefract )
  120. {
  121. result = lerp( vRefractColor, vReflectColor, fFresnel ) * flMask;
  122. #if BASETEXTURE
  123. result += float4( diffuseComponent, 1.0f );
  124. flAlpha = baseSample.a;
  125. #endif
  126. }
  127. else if( g_bReflect )
  128. {
  129. #if BASETEXTURE
  130. result = float4( diffuseComponent, 1.0f ) + vReflectColor * flMask;
  131. flAlpha = baseSample.a;
  132. #else
  133. result = vReflectColor;
  134. #endif
  135. }
  136. else if( g_bRefract )
  137. {
  138. #if BASETEXTURE
  139. result = float4( diffuseComponent, 1.0f ) + vRefractColor * flMask;
  140. flAlpha = baseSample.a;
  141. #else
  142. result = vRefractColor;
  143. #endif
  144. }
  145. else
  146. {
  147. #if BASETEXTURE
  148. result = float4( diffuseComponent, 1.0f );
  149. flAlpha = baseSample.a;
  150. #else
  151. result = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  152. #endif
  153. }
  154. #if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE )
  155. float fogFactor = CalcRangeFog( i.vProjPos.z, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w );
  156. #else
  157. float fogFactor = 0;
  158. #endif
  159. return FinalOutput( float4( result.rgb, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z );
  160. }