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.

182 lines
5.8 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "BASETEXTURE" "0..1"
  3. // STATIC: "REFLECT" "0..1"
  4. // STATIC: "REFRACT" "0..1"
  5. // STATIC: "ENVMAPMASK" "0..1"
  6. #include "common_fog_ps_fxc.h"
  7. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC]
  8. // DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [CONSOLE]
  9. #if defined( SHADER_MODEL_PS_2_0 )
  10. #define WRITE_DEPTH_TO_DESTALPHA 0
  11. #endif
  12. #include "common_ps_fxc.h"
  13. #include "shader_constant_register_map.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 float4 g_vRefractTint : register( c1 );
  25. const float g_flReflectance : register( c3 );
  26. const float4 g_vReflectTint : register( c4 );
  27. const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale
  28. const float4 g_PixelFogParams : register( PSREG_FOG_PARAMS );
  29. const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT );
  30. static const bool g_bReflect = REFLECT ? true : false;
  31. static const bool g_bRefract = REFRACT ? true : false;
  32. struct PS_INPUT
  33. {
  34. float4 vBumpTexCoordXY_vTexCoordXY : TEXCOORD0;
  35. float4 vPositionToCameraRayTs_projW : TEXCOORD1;
  36. float4 vReflectXY_vRefractYX : TEXCOORD2;
  37. float4 vProjPos : TEXCOORD4;
  38. float3 worldPos : TEXCOORD5;
  39. #if BASETEXTURE
  40. float4 lightmapTexCoord1And2 : TEXCOORD6_centroid;
  41. float4 lightmapTexCoord3 : TEXCOORD7_centroid;
  42. #endif
  43. };
  44. float4_color_return_type main( PS_INPUT i ) : COLOR
  45. {
  46. // Load normal and expand range
  47. float4 vNormalTexel = tex2D( NormalSampler, i.vBumpTexCoordXY_vTexCoordXY.xy );
  48. float3 vNormalTs = normalize( ( vNormalTexel.xyz * 2.0 ) - 1.0 );
  49. // Perform division by W only once
  50. float ooW = 1.0f / i.vPositionToCameraRayTs_projW.w;
  51. //float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW;
  52. // Vectorize the dependent UV calculations (reflect = .xy, refract = .wz)
  53. #ifdef NV3X
  54. float4 vDependentTexCoords = vNormalTs.xyxy * vNormalTexel.a * g_ReflectRefractScale.xyzw;
  55. #else
  56. float4 vN;
  57. vN.xy = vNormalTs.xy;
  58. vN.w = vNormalTs.x;
  59. vN.z = vNormalTs.y;
  60. float4 vDependentTexCoords = vN * vNormalTexel.a * g_ReflectRefractScale.xyzw;
  61. #endif
  62. vDependentTexCoords.xyzw += i.vReflectXY_vRefractYX.xyzw * ooW;
  63. float2 vReflectTexCoord = vDependentTexCoords.xy;
  64. float2 vRefractTexCoord = vDependentTexCoords.wz;
  65. // Sample reflection
  66. float3 vReflectColor = float3( 0.0f, 0.0f, 0.0f );
  67. #if ( REFLECT )
  68. {
  69. vReflectColor.rgb = tex2D( ReflectSampler, vReflectTexCoord ).rgb;
  70. vReflectColor.rgb *= g_vReflectTint.rgb;
  71. }
  72. #endif
  73. // Sample refraction
  74. float3 vRefractColor = float3( 0.0f, 0.0f, 0.0f );
  75. #if ( REFRACT )
  76. {
  77. vRefractColor = tex2D( RefractSampler, vRefractTexCoord ).rgb;
  78. vRefractColor.rgb *= g_vRefractTint.rgb;
  79. }
  80. #endif
  81. // Schlick Fresnel
  82. float3 vPositionToCameraDirTs = normalize( i.vPositionToCameraRayTs_projW.xyz );
  83. float flNdotV = saturate( dot( vPositionToCameraDirTs.xyz, vNormalTs.xyz ) );
  84. float flFresnel = g_flReflectance + ( ( 1.0f - g_flReflectance ) * pow( 1.0f - flNdotV, 5.0f ) );
  85. //flFresnel = 1.0f - flFresnel;
  86. //return flFresnel;
  87. float flRefractMask = 0.0f;
  88. #if BASETEXTURE
  89. float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoordXY_vTexCoordXY.zw );
  90. flRefractMask = baseSample.a;
  91. float2 bumpCoord1;
  92. float2 bumpCoord2;
  93. float2 bumpCoord3;
  94. ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy,
  95. bumpCoord1, bumpCoord2, bumpCoord3 );
  96. float4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 );
  97. float3 lightmapColor1 = lightmapSample1.rgb;
  98. float3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ).rgb;
  99. float3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ).rgb;
  100. float3 dp;
  101. dp.x = saturate( dot( vNormalTs, bumpBasis[0] ) );
  102. dp.y = saturate( dot( vNormalTs, bumpBasis[1] ) );
  103. dp.z = saturate( dot( vNormalTs, bumpBasis[2] ) );
  104. dp *= dp;
  105. float3 diffuseLighting = dp.x * lightmapColor1 +
  106. dp.y * lightmapColor2 +
  107. dp.z * lightmapColor3;
  108. float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) );
  109. diffuseLighting *= LIGHT_MAP_SCALE / sum;
  110. float3 diffuseComponent = baseSample.rgb * diffuseLighting;
  111. #endif
  112. // Mask
  113. float3 vSpecMask = float3( 1.0f, 1.0f, 1.0f );
  114. #if ( REFLECT && ENVMAPMASK )
  115. {
  116. vSpecMask.rgb = tex2D( EnvMapMaskSampler, i.vBumpTexCoordXY_vTexCoordXY.zw ).rgb;
  117. }
  118. #endif
  119. // NOTE: the BASETEXTURE path hasn't been tested (or really written for that matter, just copied from water)
  120. // What I think should happen is that the alpha of base texture should be its 'translucency'
  121. // which should indicate how much refraction to use.
  122. // We should add an envmapmask to deal with how much reflection to use
  123. // along with all the focus, etc. features
  124. float4 result = float4( 0.0f, 0.0f, 0.0f, 1.0f );
  125. #if ( REFLECT || REFRACT )
  126. {
  127. // Refraction
  128. result.rgb = vRefractColor.rgb * ( 1.0f - flFresnel );
  129. // Add in diffuse component applying fresnel to pixels with no spec mask
  130. #if ( BASETEXTURE )
  131. {
  132. result.rgb += lerp( diffuseComponent.rgb, diffuseComponent.rgb * ( 1.0f - flFresnel ), vSpecMask.rgb );
  133. }
  134. #endif
  135. // Add reflection
  136. result.rgb += ( vReflectColor.rgb * flFresnel ) * vSpecMask.rgb;
  137. }
  138. #else // No reflect or refract
  139. {
  140. #if ( BASETEXTURE )
  141. {
  142. result.rgba = float4( diffuseComponent.rgb, flRefractMask );
  143. }
  144. #endif
  145. }
  146. #endif
  147. float fogFactor = 0.0f;
  148. #if ( PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE )
  149. {
  150. fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_PixelFogParams, g_EyePos.xyz, i.worldPos.xyz, i.vProjPos.z );
  151. }
  152. #endif
  153. return FinalOutput( result.rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, ( WRITE_DEPTH_TO_DESTALPHA != 0 ), i.vProjPos.z );
  154. }