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.

162 lines
6.9 KiB

  1. //========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
  2. // Includes =======================================================================================
  3. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  4. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  5. #include "common_vertexlitgeneric_dx9.h"
  6. // Texture Samplers ===============================================================================
  7. sampler g_tRefractionSampler : register( s0 );
  8. sampler g_tBumpSampler : register( s1 );
  9. // Shaders Constants and Globals ==================================================================
  10. const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix
  11. const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix
  12. const float4 g_vCameraPosition : register( c5 );
  13. const float4 g_vPackedConst6 : register( c6 );
  14. #define g_flBlurAmount g_vPackedConst6.x // 0.01f;
  15. #define g_flRefractAmount g_vPackedConst6.y // Default = 1.0f
  16. #define g_flTime g_vPackedConst6.w
  17. const float4 g_cColorTint : register( c7 );
  18. const float4 g_vPackedConst8 : register( c8 );
  19. #define g_cSilhouetteColor g_vPackedConst8 //= { 0.3, 0.3, 0.5 };
  20. #define g_flSilhouetteThickness g_vPackedConst8.w //= 0.2f;
  21. const float2 g_vGroundMinMax : register( c9 ); //= { -0.3, -0.1 };
  22. // 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw)
  23. static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ),
  24. float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ),
  25. float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ),
  26. float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) };
  27. // Interpolated values ============================================================================
  28. struct PS_INPUT
  29. {
  30. float3 vWorldNormal : TEXCOORD0; // World-space normal
  31. float3 vWorldTangent : TEXCOORD1;
  32. float3 vWorldBinormal : TEXCOORD2;
  33. float3 vProjPosForRefract : TEXCOORD3;
  34. float3 vWorldViewVector : TEXCOORD4;
  35. float4 vUv0 : TEXCOORD5; // uv.xy, uvScroll.xy
  36. float4 vUv1 : TEXCOORD6; // uv.xy, uvScroll.xy
  37. float2 vUvGroundNoise : TEXCOORD7;
  38. };
  39. // Main ===========================================================================================
  40. float4 main( PS_INPUT i ) : COLOR
  41. {
  42. /*
  43. // Bump layer 0
  44. float2 vUv0 = i.vUv0Uv1.xy;
  45. float2 vUv0Scroll = i.vUv0Uv1.xy * 3.0f;
  46. vUv0Scroll.y -= g_flTime * 0.1f;
  47. float4 vBumpTexel0 = tex2D( g_tBumpSampler, vUv0Scroll.xy );
  48. vBumpTexel0 = tex2D( g_tBumpSampler, vUv0.xy + (vBumpTexel0.xy*0.03) );
  49. // Bump layer 1
  50. float2 vUv1 = i.vUv0Uv1.xy * 10.0f;
  51. float2 vUv1Scroll = i.vUv0Uv1.xy * 32.0f;
  52. vUv1Scroll.y -= g_flTime * 0.1f;
  53. float4 vBumpTexel1 = tex2D( g_tBumpSampler, vUv1Scroll.xy );
  54. vBumpTexel1 = tex2D( g_tBumpSampler, vUv1.xy + (vBumpTexel1.xy*0.03) );
  55. //*/
  56. // Bump layer 0
  57. float4 vBumpTexel0 = tex2D( g_tBumpSampler, i.vUv0.wz );
  58. vBumpTexel0 = tex2D( g_tBumpSampler, i.vUv0.xy + ( vBumpTexel0.xy*0.03 ) );
  59. // Bump layer 1
  60. float4 vBumpTexel1 = tex2D( g_tBumpSampler, i.vUv1.wz );
  61. vBumpTexel1 = tex2D( g_tBumpSampler, i.vUv1.xy + ( vBumpTexel1.xy*0.03 ) );
  62. // Combine bump layers into tangetn normal
  63. float3 vTangentNormal = ( vBumpTexel0 * 2.0f ) - 1.0f;
  64. vTangentNormal.xyz += ( vBumpTexel1 * 2.0f - 1.0f ) * 0.5f; // * 0.5f;
  65. // Transform into world space
  66. float3 vWorldNormal = Vec3TangentToWorld( vTangentNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal );
  67. // Effect mask
  68. //float flEffectMask = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) * lerp( 2.0f, 1.0f, g_flSilhouetteThickness ) );
  69. float flEffectMask = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) * ( (2.0f - g_flSilhouetteThickness) ) );
  70. // Simulate ground intersection
  71. flEffectMask *= smoothstep( g_vGroundMinMax.x, g_vGroundMinMax.y, i.vWorldNormal.z );
  72. // Soften mask by squaring term
  73. flEffectMask *= flEffectMask;
  74. // Silhouette mask
  75. float flSilhouetteHighlightMask = saturate( flEffectMask * ( 1.0f - flEffectMask ) * 4.0f );
  76. flSilhouetteHighlightMask *= flSilhouetteHighlightMask * flSilhouetteHighlightMask;
  77. // Transform world space normal into clip space and project
  78. float3 vProjNormal;
  79. vProjNormal.x = dot( vWorldNormal.xyz, g_mViewProj0.xyz ); // 1st row
  80. vProjNormal.y = dot( vWorldNormal.xyz, g_mViewProj1.xyz ); // 2nd row
  81. // Compute coordinates for sampling refraction
  82. float2 vRefractTexCoordNoWarp = i.vProjPosForRefract.xy / i.vProjPosForRefract.z;
  83. float2 vRefractTexCoord = vProjNormal.xy;
  84. float scale = lerp( 0.0f, g_flRefractAmount, flEffectMask );// * flEffectMask * flEffectMask ); // Using flEffectMask^3
  85. vRefractTexCoord.xy *= scale;
  86. vRefractTexCoord.xy += vRefractTexCoordNoWarp.xy;
  87. // Blur by scalable Poisson filter
  88. float flBlurAmount = g_flBlurAmount * flEffectMask;
  89. float3 cRefract = tex2D( g_tRefractionSampler, vRefractTexCoord.xy );
  90. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].xy * flBlurAmount ) );
  91. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].wz * flBlurAmount ) );
  92. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].xy * flBlurAmount ) );
  93. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].wz * flBlurAmount ) );
  94. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].xy * flBlurAmount ) );
  95. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].wz * flBlurAmount ) );
  96. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].xy * flBlurAmount ) );
  97. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].wz * flBlurAmount ) );
  98. cRefract /= 9.0f;
  99. // Undo tone mapping
  100. cRefract /= LINEAR_LIGHT_SCALE;
  101. // Refract color tint
  102. float fColorTintStrength = 1.0f - flEffectMask;
  103. float3 cRefractColorTint = lerp( g_cColorTint, 1.0f, fColorTintStrength );
  104. // Ground noise
  105. //float flGroundNoise = tex2D( g_tBumpSampler, i.vUvGroundNoise.xy ).g;
  106. //flGroundNoise *= smoothstep( g_vGroundMinMax.y, g_vGroundMinMax.y+0.4, -i.vWorldNormal.z );
  107. //flGroundNoise = smoothstep( 0.2, 0.9, flGroundNoise );
  108. //===============//
  109. // Combine terms //
  110. //===============//
  111. float4 result;
  112. result.rgb = cRefract.rgb * cRefractColorTint.rgb;
  113. result.rgb += result.rgb * ( flSilhouetteHighlightMask * g_cSilhouetteColor.rgb );
  114. //result.rgb += flGroundNoise;
  115. //result.rgb = float3( 0.0, 0.0, 0.0 );
  116. //result.rg = vRefractTexCoord.xy;
  117. //result.rg = i.vUv0Uv1.xy;
  118. //result.rgb = vBumpTexel0.rgb;
  119. //result.rgb = vTangentNormal;
  120. //result.rgb = vWorldNormal;
  121. //result = flEffectMask;
  122. //result = flSilhouetteHighlightMask;
  123. //result = tex2D( g_tBumpSampler, i.vUvGroundNoise.xy ).y;
  124. //result.rgb = flGroundNoise;
  125. // Set alpha to...
  126. result.a = flEffectMask;
  127. return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit.
  128. }