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.

218 lines
7.1 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  7. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  8. // STATIC: "CUBEMAP" "0..1"
  9. // STATIC: "FLOWMAP" "0..1"
  10. // STATIC: "CORECOLORTEXTURE" "0..1"
  11. // STATIC: "REFRACT" "0..1"
  12. // DYNAMIC: "PIXELFOGTYPE" "0..1"
  13. // SKIP: ( $REFRACT || $CORECOLORTEXTURE ) && $CUBEMAP
  14. #include "common_ps_fxc.h"
  15. sampler RefractSampler : register( s2 );
  16. sampler NormalSampler : register( s3 );
  17. #if CUBEMAP
  18. sampler EnvmapSampler : register( s4 );
  19. #endif
  20. #if FLOWMAP
  21. sampler FlowmapSampler : register( s6 );
  22. #endif
  23. #if CORECOLORTEXTURE
  24. sampler CoreColorSampler : register( s7 );
  25. #endif
  26. const HALF3 g_EnvmapTint : register( c0 );
  27. const HALF3 g_RefractTint : register( c1 );
  28. const HALF3 g_EnvmapContrast : register( c2 );
  29. const HALF3 g_EnvmapSaturation : register( c3 );
  30. const HALF2 g_RefractScale : register( c5 );
  31. #if FLOWMAP
  32. const float g_Time : register( c6 );
  33. const float2 g_FlowScrollRate : register( c7 );
  34. //const float3 g_SphereCenter : register( c9 );
  35. //const float3 g_SphereRadius : register( c10 );
  36. const float g_CoreColorTexCoordOffset : register( c9 );
  37. #endif
  38. const float3 g_EyePos : register( c8 );
  39. const float4 g_FogParams : register( c11 );
  40. float LengthThroughSphere( float3 vecRayOrigin, float3 vecRayDelta,
  41. float3 vecSphereCenter, float flRadius, out float alpha )
  42. {
  43. // Solve using the ray equation + the sphere equation
  44. // P = o + dt
  45. // (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2
  46. // (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2
  47. // (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 +
  48. // (oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 +
  49. // (oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2
  50. // (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t +
  51. // (ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0
  52. // or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a
  53. // a = DotProduct( vecRayDelta, vecRayDelta );
  54. // b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta )
  55. // c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius;
  56. float3 vecSphereToRay;
  57. vecSphereToRay = vecRayOrigin - vecSphereCenter;
  58. float a = dot( vecRayDelta, vecRayDelta );
  59. // This would occur in the case of a zero-length ray
  60. // if ( a == 0.0f )
  61. // {
  62. // *pT1 = *pT2 = 0.0f;
  63. // return vecSphereToRay.LengthSqr() <= flRadius * flRadius;
  64. // }
  65. float b = 2 * dot( vecSphereToRay, vecRayDelta );
  66. float c = dot( vecSphereToRay, vecSphereToRay ) - flRadius * flRadius;
  67. float flDiscrim = b * b - 4 * a * c;
  68. // if ( flDiscrim < 0.0f )
  69. // return 0.0f;
  70. float hack = flDiscrim;
  71. flDiscrim = sqrt( flDiscrim );
  72. float oo2a = 0.5f / a;
  73. //if( hack < 0.0f )
  74. //{
  75. // alpha = 0.0f;
  76. // return 0.0f;
  77. //}
  78. //else
  79. //{
  80. // alpha = 1.0f;
  81. // return abs( flDiscrim ) * 2 * oo2a;
  82. //}
  83. //replacing the if's above because if's in hlsl are bad.....
  84. float fHackGreaterThanZero = step( 0.0f, hack );
  85. alpha = fHackGreaterThanZero;
  86. return (fHackGreaterThanZero * (abs( flDiscrim ) * 2 * oo2a));
  87. // *pT1 = ( - b - flDiscrim ) * oo2a;
  88. // *pT2 = ( - b + flDiscrim ) * oo2a;
  89. // return true;
  90. }
  91. struct PS_INPUT
  92. {
  93. float2 vBumpTexCoord : TEXCOORD0; // dudvMapAndNormalMapTexCoord
  94. HALF3 vWorldVertToEyeVector : TEXCOORD1;
  95. HALF3x3 tangentSpaceTranspose : TEXCOORD2;
  96. float3 vRefractXYW : TEXCOORD5;
  97. float3 projNormal : TEXCOORD6;
  98. float4 worldPos_projPosZ : TEXCOORD7;
  99. };
  100. float4 main( PS_INPUT i ) : COLOR
  101. {
  102. HALF3 result = 0.0f;
  103. HALF blend = 1.0f;
  104. #if FLOWMAP
  105. // hack
  106. float3 g_SphereCenter = { 2688.0f, 12139.0f, 5170.0f };
  107. float g_SphereDiameter = 430.0f;
  108. float g_SphereRadius = g_SphereDiameter * 0.5f;
  109. float3 tmp = i.worldPos_projPosZ.xyz - g_SphereCenter;
  110. float hackRadius = 1.05f * sqrt( dot( tmp, tmp ) );
  111. float sphereAlpha;
  112. float lengthThroughSphere = LengthThroughSphere( g_EyePos, normalize( i.worldPos_projPosZ.xyz - g_EyePos ),
  113. g_SphereCenter, /*g_SphereRadius*/ hackRadius, sphereAlpha );
  114. float normalizedLengthThroughSphere = lengthThroughSphere / g_SphereDiameter;
  115. float3 hackWorldSpaceNormal = normalize( i.worldPos_projPosZ.xyz - g_SphereCenter );
  116. float3 realFuckingNormal = abs( hackWorldSpaceNormal );
  117. hackWorldSpaceNormal = 0.5f * ( hackWorldSpaceNormal + 1.0f );
  118. // hackWorldSpaceNormal = abs( hackWorldSpaceNormal );
  119. // return float4( hackWorldSpaceNormal.x, 0.0f, 0.0f, 1.0f );
  120. i.vBumpTexCoord.xy = 0.0f;
  121. i.vBumpTexCoord.xy = realFuckingNormal.z * tex2D( FlowmapSampler, hackWorldSpaceNormal.xy );
  122. i.vBumpTexCoord.xy += realFuckingNormal.y * tex2D( FlowmapSampler, hackWorldSpaceNormal.xz );
  123. i.vBumpTexCoord.xy += realFuckingNormal.x * tex2D( FlowmapSampler, hackWorldSpaceNormal.yz );
  124. i.vBumpTexCoord.xy += g_Time * g_FlowScrollRate;
  125. // return float4( i.vBumpTexCoord.xy, 0.0f, 0.0f );
  126. #endif
  127. // Load normal and expand range
  128. HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoord );
  129. // return vNormalSample;
  130. HALF3 tangentSpaceNormal = vNormalSample * 2.0 - 1.0;
  131. HALF3 refractTintColor = g_RefractTint;
  132. // Perform division by W only once
  133. float ooW = 1.0f / i.vRefractXYW.z;
  134. // Compute coordinates for sampling refraction
  135. float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW;
  136. float2 vRefractTexCoord = tangentSpaceNormal.xy;
  137. HALF scale = vNormalSample.a * g_RefractScale.x;
  138. #if FLOWMAP
  139. scale *= normalizedLengthThroughSphere;
  140. #endif
  141. vRefractTexCoord *= scale;
  142. #if FLOWMAP
  143. float2 hackOffset = vRefractTexCoord;
  144. #endif
  145. vRefractTexCoord += vRefractTexCoordNoWarp;
  146. float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy );
  147. float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy );
  148. colorWarp *= refractTintColor;
  149. #if REFRACT
  150. result = lerp( colorNoWarp, colorWarp, blend );
  151. // return float4( 1.0f, 0.0f, 0.0f, 1.0f );
  152. #endif
  153. #if CUBEMAP
  154. HALF specularFactor = vNormalSample.a;
  155. HALF3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal );
  156. HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vWorldVertToEyeVector );
  157. HALF3 specularLighting = texCUBE( EnvmapSampler, reflectVect );
  158. specularLighting *= specularFactor;
  159. specularLighting *= g_EnvmapTint;
  160. HALF3 specularLightingSquared = specularLighting * specularLighting;
  161. specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
  162. HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
  163. specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
  164. result += specularLighting;
  165. #endif
  166. #if CORECOLORTEXTURE && FLOWMAP
  167. float4 coreColorTexel = tex2D( CoreColorSampler, hackOffset + float2( normalizedLengthThroughSphere, g_CoreColorTexCoordOffset ) );
  168. HALF4 rgba = HALF4( lerp( result, coreColorTexel, coreColorTexel.a /*normalizedLengthThroughSphere*/ ), sphereAlpha );
  169. #else
  170. HALF4 rgba = HALF4( result, vNormalSample.a );
  171. #endif
  172. float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
  173. return FinalOutput( rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
  174. }