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.

235 lines
7.1 KiB

  1. //====== Copyright c 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. // STATIC: "NORMALMAP" "0..2"
  7. // STATIC: "NORMALMAP2" "0..1"
  8. // STATIC: "WORLDVERTEXTRANSITION" "0..1"
  9. // STATIC: "SEAMLESS" "0..1"
  10. // STATIC: "DETAILTEXTURE" "0..1"
  11. // STATIC: "DETAIL_BLEND_MODE" "0..1"
  12. // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC]
  13. // STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX]
  14. // DYNAMIC: "PIXELFOGTYPE" "0..1"
  15. // DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b]
  16. // SKIP: !$WORLDVERTEXTRANSITION && $NORMALMAP2
  17. // SKIP: !$NORMALMAP && $NORMALMAP2
  18. // SKIP: !$DETAILTEXTURE && ( $DETAIL_BLEND_MODE != 0 )
  19. #include "shader_constant_register_map.h"
  20. #include "common_flashlight_fxc.h"
  21. #include "common_lightmappedgeneric_fxc.h"
  22. const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS );
  23. const float4 g_FogParams : register( PSREG_FOG_PARAMS );
  24. const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT );
  25. const float4 g_FlashlightAttenuation : register( PSREG_FLASHLIGHT_ATTENUATION );
  26. const float4 g_DetailConstants : register( c0 );
  27. sampler SpotSampler : register( s0 );
  28. sampler BaseTextureSampler : register( s1 );
  29. sampler NormalizingCubemapSampler : register( s2 );
  30. // use a normalizing cube map here if we aren't normal mapping
  31. sampler BumpMapSampler : register( s3 );
  32. sampler BaseTextureSampler2 : register( s4 );
  33. #ifdef WORLDVERTEXTRANSITION
  34. sampler NormalMap2Sampler : register( s6 );
  35. #endif
  36. #if DETAILTEXTURE
  37. sampler DetailSampler : register( s8 );
  38. #endif
  39. #if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) )
  40. sampler RandomRotationSampler : register( s5 ); // Random rotation sampler
  41. sampler FlashlightDepthSampler : register( s7 );
  42. #endif
  43. struct PS_INPUT
  44. {
  45. float4 spotTexCoord : TEXCOORD0;
  46. #if SEAMLESS
  47. float3 SeamlessTexCoord : TEXCOORD1;
  48. #else
  49. float2 baseTexCoord : TEXCOORD1;
  50. #endif
  51. #if NORMALMAP
  52. float3 tangentPosToLightVector : TEXCOORD2;
  53. float2 normalMapTexCoord : TEXCOORD3;
  54. #else
  55. float3 worldPosToLightVector : TEXCOORD2;
  56. float3 normal : TEXCOORD3;
  57. #endif
  58. float2 detailCoords : TEXCOORD4;
  59. float4 worldPos_worldTransition : TEXCOORD5;
  60. float3 projPos : TEXCOORD6;
  61. float4 fogFactorW : TEXCOORD7;
  62. };
  63. float4 SampleNormal( sampler s, PS_INPUT i )
  64. {
  65. #if SEAMLESS
  66. float4 szy=tex2D( s, i.SeamlessTexCoord.zy );
  67. float4 sxz=tex2D( s, i.SeamlessTexCoord.xz );
  68. float4 syx=tex2D( s, i.SeamlessTexCoord.xy );
  69. return i.fogFactorW.r*szy + i.fogFactorW.g*sxz + i.fogFactorW.b*syx;
  70. #else
  71. #if NORMALMAP
  72. return tex2D( s, i.normalMapTexCoord.xy);
  73. #else
  74. return float4(0,0,1,1);
  75. #endif
  76. #endif
  77. }
  78. float4 main( PS_INPUT i ) : COLOR
  79. {
  80. bool bBase2 = WORLDVERTEXTRANSITION ? true : false;
  81. bool bBump = (NORMALMAP != 0) ? true : false;
  82. // Do spot stuff early since we can bail out
  83. float3 spotColor = float3(0,0,0);
  84. float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w;
  85. #if ( defined( _X360 ) )
  86. float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f );
  87. float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f );
  88. [branch]
  89. if ( dot(ltz + gto, float3(1,1,1)) > 0 )
  90. {
  91. clip (-1);
  92. return float4(0,0,0,0);
  93. }
  94. else
  95. {
  96. spotColor = tex2D( SpotSampler, vProjCoords );
  97. [branch]
  98. if ( dot(spotColor.xyz, float3(1,1,1)) <= 0 )
  99. {
  100. clip(-1);
  101. return float4(0,0,0,0);
  102. }
  103. else
  104. {
  105. #else
  106. spotColor = tex2D( SpotSampler, vProjCoords );
  107. #endif
  108. float4 baseColor = 0.0f;
  109. float4 baseColor2 = 0.0f;
  110. float4 vNormal = float4(0, 0, 1, 1);
  111. float3 baseTexCoords = float3(0,0,0);
  112. #if SEAMLESS
  113. baseTexCoords = i.SeamlessTexCoord.xyz;
  114. #else
  115. baseTexCoords.xy = i.baseTexCoord.xy;
  116. #endif
  117. GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpMapSampler, bBase2, bBump, baseTexCoords, i.fogFactorW.xyz, baseColor, baseColor2, vNormal );
  118. #if WORLDVERTEXTRANSITION
  119. float lerpAlpha = 1-i.worldPos_worldTransition.a;
  120. #endif
  121. #if ( NORMALMAP == 0 )
  122. vNormal.xyz = normalize( i.normal.xyz );
  123. #endif
  124. #if ( NORMALMAP == 1 )
  125. vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // signed
  126. # if NORMALMAP2
  127. float3 normal2 = SampleNormal( NormalMap2Sampler, i ) * 2.0f - 1.0f;
  128. vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha );
  129. # endif
  130. #endif
  131. // ssbump
  132. #if ( NORMALMAP == 2 )
  133. # if NORMALMAP2
  134. float3 normal2 = SampleNormal( NormalMap2Sampler, i );
  135. vNormal.xyz = lerp( normal2, vNormal.xyz, lerpAlpha );
  136. # endif
  137. #else
  138. // Normalize normal after all of the lerps above (including the tri/bilinear texel fetches)
  139. vNormal.xyz = normalize( vNormal.xyz );
  140. #endif
  141. spotColor.rgb *= cFlashlightColor.rgb;
  142. // Compute per-pixel distance attenuation
  143. float3 delta = g_EyePos.xyz - i.worldPos_worldTransition.xyz;
  144. float distSquared = dot( delta, delta );
  145. float dist = sqrt( distSquared );
  146. float farZ = g_FlashlightAttenuation.w;
  147. float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f );
  148. float flAtten = saturate(endFalloffFactor * dot( g_FlashlightAttenuation.xyz, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) );
  149. #if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) )
  150. float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, false );
  151. float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated
  152. flShadow = saturate(lerp( flAttenuated, flShadow, flAtten )); // Blend between shadow and above, according to light attenuation
  153. spotColor *= flShadow;
  154. #endif
  155. #if WORLDVERTEXTRANSITION
  156. baseColor.xyz = lerp( baseColor2.xyz, baseColor.xyz, lerpAlpha );
  157. #endif
  158. #if DETAILTEXTURE
  159. float4 detailColor = float4( g_DetailConstants.xyz, 1.0f ) * tex2D( DetailSampler, i.detailCoords );
  160. float4 vBase = TextureCombine( float4(baseColor.xyz, 1.0f), detailColor, DETAIL_BLEND_MODE, g_DetailConstants.w );
  161. baseColor.xyz = vBase.xyz;
  162. #endif
  163. #if NORMALMAP == 0
  164. float3 worldPosToLightVector = texCUBE( NormalizingCubemapSampler, i.worldPosToLightVector ) * 2.0f - 1.0f;
  165. float nDotL = dot( worldPosToLightVector, vNormal.xyz );
  166. #endif
  167. #if NORMALMAP == 1
  168. // flashlightfixme: wrap this!
  169. float3 tangentPosToLightVector = texCUBE( NormalizingCubemapSampler, i.tangentPosToLightVector ) * 2.0f - 1.0f;
  170. float nDotL = dot( tangentPosToLightVector, vNormal.xyz );
  171. #endif
  172. #if NORMALMAP == 2
  173. float3 tangentPosToLightVector = normalize( i.tangentPosToLightVector );
  174. float nDotL =
  175. vNormal.x*dot( tangentPosToLightVector, bumpBasis[0]) +
  176. vNormal.y*dot( tangentPosToLightVector, bumpBasis[1]) +
  177. vNormal.z*dot( tangentPosToLightVector, bumpBasis[2]);
  178. #endif
  179. float3 outColor;
  180. outColor = spotColor * baseColor.xyz * saturate( nDotL );
  181. outColor *= flAtten;
  182. float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_worldTransition.z, i.projPos.z );
  183. return FinalOutput( float4(outColor, baseColor.a) , fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR );
  184. // so we can jump over all of the above
  185. #if ( defined( _X360 ) )
  186. }
  187. }
  188. #endif
  189. }