Counter Strike : Global Offensive Source Code
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.

103 lines
4.8 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "BUMPMAP" "0..1"
  3. // Includes =======================================================================================
  4. #include "common_vertexlitgeneric_dx9.h"
  5. // Texture Samplers ===============================================================================
  6. sampler g_tRefractionSampler : register( s0 );
  7. #if BUMPMAP
  8. sampler g_tBumpSampler : register( s1 );
  9. #endif
  10. // Shaders Constants and Globals ==================================================================
  11. const float4 g_mViewProj0 : register( c0 ); // 1st row of matrix
  12. const float4 g_mViewProj1 : register( c1 ); // 2nd row of matrix
  13. const float4 g_vCameraPosition : register( c5 );
  14. const float4 g_vPackedConst6 : register( c6 );
  15. #define g_flCloakFactor g_vPackedConst6.x // Default = 1.0f
  16. #define g_flRefractAmount g_vPackedConst6.y // Default = 1.0f
  17. const float4 g_cCloakColorTint : register( c7 );
  18. // 8 2D Poisson offsets (designed to use .xy and .wz swizzles (not .zw)
  19. static const float4 g_vPoissonOffset[4] = { float4 (-0.0876f, 0.9703f, 0.5651f, 0.4802f ),
  20. float4 ( 0.1851f, 0.1580f, -0.0617f, -0.2616f ),
  21. float4 (-0.5477f, -0.6603f, 0.0711f, -0.5325f ),
  22. float4 (-0.0751f, -0.8954f, 0.4054f, 0.6384f ) };
  23. // Interpolated values ============================================================================
  24. struct PS_INPUT
  25. {
  26. float3 vWorldNormal : TEXCOORD0; // World-space normal
  27. float3 vProjPosForRefract : TEXCOORD1;
  28. float3 vWorldViewVector : TEXCOORD2;
  29. #if BUMPMAP
  30. float3x3 mTangentSpaceTranspose : TEXCOORD3;
  31. // second row : TEXCOORD4;
  32. // third row : TEXCOORD5;
  33. float2 vTexCoord0 : TEXCOORD6;
  34. #endif
  35. };
  36. // Main ===========================================================================================
  37. float4_color_return_type main( PS_INPUT i ) : COLOR
  38. {
  39. float3 vWorldNormal = normalize( i.vWorldNormal.xyz );
  40. #if BUMPMAP
  41. float4 vBumpTexel = tex2D( g_tBumpSampler, i.vTexCoord0.xy );
  42. float3 vTangentNormal = ( 2.0f * vBumpTexel.xyz ) - 1.0f;
  43. vWorldNormal.xyz = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz );
  44. #endif
  45. // Transform world space normal into clip space and project
  46. float3 vProjNormal;
  47. vProjNormal.x = dot( vWorldNormal.xyz, g_mViewProj0.xyz ); // 1st row
  48. vProjNormal.y = dot( vWorldNormal.xyz, g_mViewProj1.xyz ); // 2nd row
  49. // Compute coordinates for sampling refraction
  50. float2 vRefractTexCoordNoWarp = i.vProjPosForRefract.xy / i.vProjPosForRefract.z;
  51. float2 vRefractTexCoord = vProjNormal.xy;
  52. float scale = lerp( g_flRefractAmount, 0.0f, saturate( g_flCloakFactor ) );
  53. vRefractTexCoord.xy *= scale;
  54. vRefractTexCoord.xy += vRefractTexCoordNoWarp.xy;
  55. // Blur by scalable Poisson filter
  56. float flBlurAmount = lerp( 0.05f, 0.0f, saturate( g_flCloakFactor ) );
  57. float3 cRefract = tex2D( g_tRefractionSampler, vRefractTexCoord.xy ).rgb;
  58. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].xy * flBlurAmount ) ).rgb;
  59. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[0].wz * flBlurAmount ) ).rgb;
  60. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].xy * flBlurAmount ) ).rgb;
  61. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[1].wz * flBlurAmount ) ).rgb;
  62. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].xy * flBlurAmount ) ).rgb;
  63. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[2].wz * flBlurAmount ) ).rgb;
  64. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].xy * flBlurAmount ) ).rgb;
  65. cRefract += tex2D( g_tRefractionSampler, vRefractTexCoord.xy + ( g_vPoissonOffset[3].wz * flBlurAmount ) ).rgb;
  66. cRefract /= 9.0f;
  67. // 1-(N.V) for Fresnel term (NOTE: If this math changes, you need to update the C code that mimics this on the CPU)
  68. float flFresnel = 1.0f - saturate( dot( i.vWorldNormal.xyz, normalize( -i.vWorldViewVector.xyz ) ) );
  69. float flCloakLerpFactor = saturate( lerp( 1.0f, flFresnel - 1.35f, saturate( g_flCloakFactor ) ) );
  70. flCloakLerpFactor = 1.0f - smoothstep( 0.4f, 0.425f, flCloakLerpFactor );
  71. // Slightly dim the facing pixels and brighten the silhouette pixels
  72. cRefract.rgb *= lerp( flFresnel * 0.4 + 0.8, 1.0f, saturate( g_flCloakFactor ) * saturate( g_flCloakFactor ) ); // This gives a scalar in the range [0.8 1.2]
  73. // Refract color tint
  74. float fColorTintStrength = saturate( ( saturate( g_flCloakFactor ) - 0.75f ) * 4.0f );
  75. cRefract.rgb *= lerp( g_cCloakColorTint.rgb, 1.0f, fColorTintStrength );
  76. //===============//
  77. // Combine terms //
  78. //===============//
  79. float4 result;
  80. result.rgb = cRefract.rgb;
  81. // Set alpha to cloak mask
  82. result.a = flCloakLerpFactor;
  83. return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  84. }