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.

239 lines
8.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include "common_ps_fxc.h"
  3. struct DrawWater_params_t
  4. {
  5. float2 vBumpTexCoord;
  6. #if MULTITEXTURE
  7. float4 vExtraBumpTexCoord;
  8. #endif
  9. float4 vReflectXY_vRefractYX;
  10. float w;
  11. float4 vReflectRefractScale;
  12. float fReflectOverbright;
  13. float4 vReflectTint;
  14. float4 vRefractTint;
  15. half3 vTangentEyeVect;
  16. float4 waterFogColor;
  17. #if BASETEXTURE
  18. HALF4 lightmapTexCoord1And2;
  19. HALF4 lightmapTexCoord3;
  20. #endif
  21. float4 vProjPos;
  22. float4 pixelFogParams;
  23. float fWaterFogStart;
  24. float fWaterFogEndMinusStart;
  25. };
  26. void DrawWater( in DrawWater_params_t i,
  27. #if BASETEXTURE
  28. in sampler BaseTextureSampler,
  29. in sampler LightmapSampler,
  30. #endif
  31. in sampler NormalSampler,
  32. in sampler RefractSampler,
  33. in sampler ReflectSampler,
  34. out float4 result, out float fogFactor )
  35. {
  36. bool bReflect = REFLECT ? true : false;
  37. bool bRefract = REFRACT ? true : false;
  38. #if MULTITEXTURE
  39. float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord );
  40. float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy );
  41. float4 vNormal2 = tex2D( NormalSampler, i.vExtraBumpTexCoord.zw );
  42. vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 );
  43. #if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N )
  44. vNormal.xy = vNormal.xy * 2.0f - 1.0f;
  45. vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) );
  46. vNormal.a = 1.0f;
  47. #else
  48. vNormal.xyz = 2.0 * vNormal.xyz - 1.0;
  49. #endif
  50. #else
  51. float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORMAL_DECODE_MODE );
  52. #endif
  53. // Perform division by W only once
  54. float ooW = 1.0f / i.w;
  55. float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW;
  56. #if ABOVEWATER
  57. float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a;
  58. #else
  59. // We don't actually have valid depth values in alpha when we are underwater looking out, so
  60. // just set to farthest value.
  61. float waterFogDepthValue = 1.0f;
  62. #endif
  63. float4 reflectRefractScale = i.vReflectRefractScale;
  64. #if !BASETEXTURE
  65. #if ( BLURRY_REFRACT == 0 )
  66. reflectRefractScale *= waterFogDepthValue;
  67. #endif
  68. #endif
  69. // Compute coordinates for sampling Reflection
  70. float2 vReflectTexCoord;
  71. float2 vRefractTexCoord;
  72. // vectorize the dependent UV calculations (reflect = .xy, refract = .wz)
  73. float4 vN;
  74. vN.xy = vNormal.xy;
  75. vN.w = vNormal.x;
  76. vN.z = vNormal.y;
  77. float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale;
  78. vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW );
  79. vReflectTexCoord = vDependentTexCoords.xy;
  80. vRefractTexCoord = vDependentTexCoords.wz;
  81. HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord );
  82. #if BLURRY_REFRACT
  83. // Sample reflection and refraction
  84. float2 ddx1=float2(0.005,0);
  85. float2 ddy1=float2(0,0.005);
  86. float4 vRefractColor=float4(0,0,0,0);
  87. #if 0
  88. float sumweights=0;
  89. for(int ix=-2;ix<=2;ix++)
  90. {
  91. for(int iy=-2;iy<=2;iy++)
  92. {
  93. float weight=1; ///(1+abs(ix)+abs(iy));
  94. vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1);
  95. sumweights+=weight;
  96. }
  97. }
  98. #else
  99. // NOTE: Generated by genwaterloop.pl in the stdshaders directory.
  100. // Need to unroll for 360 to avoid shader compilation problems.
  101. // Modified genwaterloop.pl and regenerate if you need different params
  102. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 );
  103. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 );
  104. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 );
  105. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 );
  106. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 );
  107. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 );
  108. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 );
  109. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 );
  110. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 );
  111. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 );
  112. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 );
  113. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 );
  114. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 );
  115. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 );
  116. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 );
  117. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 );
  118. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 );
  119. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 );
  120. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 );
  121. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 );
  122. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 );
  123. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 );
  124. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 );
  125. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 );
  126. vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 );
  127. float sumweights = 25;
  128. // NOTE: end of generated code.
  129. #endif
  130. vRefractColor *= (1.0/sumweights);
  131. vReflectColor *= i.fReflectOverbright;
  132. vReflectColor *= i.vReflectTint;
  133. vRefractColor *= i.vRefractTint;
  134. # if ABOVEWATER
  135. // Don't mess with this in the underwater case since we don't really have
  136. // depth values there.
  137. // get the blurred depth value to be used for fog.
  138. waterFogDepthValue = vRefractColor.a;
  139. # endif
  140. #else
  141. vReflectColor *= i.vReflectTint;
  142. HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord );
  143. // get the depth value from the refracted sample to be used for fog.
  144. # if ABOVEWATER
  145. // Don't mess with this in the underwater case since we don't really have
  146. // depth values there.
  147. waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a;
  148. # endif
  149. #endif
  150. half3 vEyeVect;
  151. vEyeVect = normalize( i.vTangentEyeVect );
  152. // Fresnel term
  153. HALF fNdotV = saturate( dot( vEyeVect, vNormal ) );
  154. HALF fFresnel = pow( 1.0 - fNdotV, 5 );
  155. #if !BASETEXTURE
  156. // fFresnel == 1.0f means full reflection
  157. fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f );
  158. #endif
  159. // blend between refraction and fog color.
  160. #if ABOVEWATER
  161. vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) );
  162. #else
  163. float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart );
  164. vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor );
  165. #endif
  166. #if BASETEXTURE
  167. float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy );
  168. HALF2 bumpCoord1;
  169. HALF2 bumpCoord2;
  170. HALF2 bumpCoord3;
  171. ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
  172. bumpCoord1, bumpCoord2, bumpCoord3 );
  173. HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 );
  174. HALF3 lightmapColor1 = lightmapSample1.rgb;
  175. HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 );
  176. HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 );
  177. float3 dp;
  178. dp.x = saturate( dot( vNormal, bumpBasis[0] ) );
  179. dp.y = saturate( dot( vNormal, bumpBasis[1] ) );
  180. dp.z = saturate( dot( vNormal, bumpBasis[2] ) );
  181. dp *= dp;
  182. float3 diffuseLighting = dp.x * lightmapColor1 +
  183. dp.y * lightmapColor2 +
  184. dp.z * lightmapColor3;
  185. float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
  186. diffuseLighting *= LIGHT_MAP_SCALE / sum;
  187. HALF3 diffuseComponent = baseSample.rgb * diffuseLighting;
  188. #endif
  189. if( bReflect && bRefract )
  190. {
  191. result = lerp( vRefractColor, vReflectColor, fFresnel );
  192. }
  193. else if( bReflect )
  194. {
  195. #if BASETEXTURE
  196. result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a;
  197. #else
  198. result = vReflectColor;
  199. #endif
  200. }
  201. else if( bRefract )
  202. {
  203. result = vRefractColor;
  204. }
  205. else
  206. {
  207. result = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  208. }
  209. #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE)
  210. fogFactor = CalcRangeFog( i.vProjPos.z, i.pixelFogParams.x, i.pixelFogParams.z, i.pixelFogParams.w );
  211. #else
  212. fogFactor = 0;
  213. #endif
  214. }