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.

184 lines
5.9 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. // STATIC: "NORMALMAP" "0..1"
  7. // STATIC: "WORLDVERTEXTRANSITION" "0..1"
  8. // STATIC: "SEAMLESS" "0..1"
  9. // STATIC: "DETAIL" "0..1"
  10. // DYNAMIC: "DOWATERFOG" "0..1"
  11. #include "common_vs_fxc.h"
  12. const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 );
  13. const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 );
  14. const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 );
  15. #if SEAMLESS
  16. const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_6 );
  17. #define SEAMLESS_SCALE (SeamlessScale.x)
  18. #endif
  19. const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 );
  20. const float4 cNormalMapOrDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 );
  21. static const int g_FogType = DOWATERFOG;
  22. struct VS_INPUT
  23. {
  24. float3 vPos : POSITION; //This HAS to match lightmappedgeneric_vs20.fxc's position input. Otherwise depth fighting errors occur on the 360
  25. float4 vNormal : NORMAL;
  26. float2 vBaseTexCoord : TEXCOORD0;
  27. #if WORLDVERTEXTRANSITION
  28. float2 vLightmapTexCoord : TEXCOORD1;
  29. float4 vColor : COLOR0;
  30. #endif
  31. #if NORMALMAP
  32. float3 vTangentS : TANGENT;
  33. float3 vTangentT : BINORMAL;
  34. #endif
  35. };
  36. struct VS_OUTPUT
  37. {
  38. float4 projPos : POSITION;
  39. #if !defined( _X360 )
  40. float fog : FOG;
  41. #endif
  42. float4 spotTexCoord : TEXCOORD0;
  43. #if SEAMLESS
  44. float3 SeamlessTexCoord : TEXCOORD1;
  45. #else
  46. float2 baseTexCoord : TEXCOORD1;
  47. #endif
  48. #if NORMALMAP
  49. float3 tangentPosToLightVector : TEXCOORD2;
  50. float2 normalMapTexCoord : TEXCOORD3;
  51. #else
  52. float3 worldPosToLightVector : TEXCOORD2;
  53. float3 normal : TEXCOORD3;
  54. #endif
  55. float2 detailCoords : TEXCOORD4;
  56. float4 worldPos_worldTransition : TEXCOORD5;
  57. float3 vProjPos : TEXCOORD6;
  58. float4 fogFactorW : TEXCOORD7;
  59. };
  60. float RemapValClamped( float val, float A, float B, float C, float D)
  61. {
  62. float cVal = (val - A) / (B - A);
  63. cVal = saturate( cVal );
  64. return C + (D - C) * cVal;
  65. }
  66. VS_OUTPUT main( const VS_INPUT v )
  67. {
  68. VS_OUTPUT o;
  69. float3 vObjNormal;
  70. DecompressVertex_Normal( v.vNormal, vObjNormal );
  71. float4 projPos;
  72. float3 worldPos;
  73. float3 worldNormal;
  74. float3 eyeVector;
  75. //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360
  76. projPos = mul( float4( v.vPos, 1 ), cModelViewProj );
  77. o.projPos = projPos;
  78. o.vProjPos.xyz = projPos.xyw;
  79. worldPos = mul( float4( v.vPos, 1 ), cModel[0] );
  80. worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
  81. o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f );
  82. o.fogFactorW = CalcFog( worldPos, projPos, g_FogType );
  83. #if !defined( _X360 )
  84. o.fog = o.fogFactorW.w;
  85. #endif
  86. #if NORMALMAP
  87. float3 worldTangentS = mul( v.vTangentS, cModel[0] );
  88. float3 worldTangentT = mul( v.vTangentT, cModel[0] );
  89. #endif
  90. #if SEAMLESS
  91. float3 vNormal=normalize( worldNormal );
  92. o.fogFactorW.xyz = vNormal * vNormal; // sums to 1.
  93. o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos;
  94. // Generate new tangent and binormal with seamless projection
  95. #if NORMALMAP
  96. // Brute-force for prototype - This must match the projection in the pixel shader!
  97. //float3 vVecX = { 1.0f, 0.0f, 0.0f };
  98. //float3 vVecY = { 0.0f, 1.0f, 0.0f };
  99. //float3 vVecZ = { 0.0f, 0.0f, 1.0f };
  100. //worldTangentS.xyz = normalize( ( o.fogFactorW.x * vVecZ.xyz ) + ( o.fogFactorW.y * vVecX.xyz ) + ( o.fogFactorW.z * vVecX.xyz ) );
  101. //worldTangentT.xyz = normalize( ( o.fogFactorW.x * vVecY.xyz ) + ( o.fogFactorW.y * vVecZ.xyz ) + ( o.fogFactorW.z * vVecY.xyz ) );
  102. // Optimized version - This must match the projection in the pixel shader!
  103. worldTangentS.xyz = normalize( float3( o.fogFactorW.y + o.fogFactorW.z, 0.0f, o.fogFactorW.x ) );
  104. worldTangentT.xyz = normalize( float3( 0.0f, o.fogFactorW.x + o.fogFactorW.z, o.fogFactorW.y ) );
  105. #endif
  106. #else
  107. #if (SEAMLESS == 0 )
  108. o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w;
  109. o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w;
  110. #endif
  111. #endif
  112. float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture );
  113. o.spotTexCoord = spotTexCoord.xyzw;
  114. float3 worldPosToLightVector = g_FlashlightPos - worldPos;
  115. #if NORMALMAP
  116. #if (DETAIL == 0)
  117. o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w;
  118. o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w;
  119. #else
  120. #if SEAMLESS
  121. o.normalMapTexCoord = v.vBaseTexCoord;
  122. #else
  123. o.normalMapTexCoord = o.baseTexCoord;
  124. #endif
  125. #endif
  126. o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS );
  127. o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT );
  128. o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal );
  129. #else
  130. o.worldPosToLightVector = worldPosToLightVector;
  131. o.normal = worldNormal;
  132. #endif
  133. #if DETAIL
  134. o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w;
  135. o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w;
  136. #else
  137. o.detailCoords = float2(0,0);
  138. #endif
  139. //float3 delta = worldPosToLightVector;
  140. //float distSquared = dot( delta, delta );
  141. //float dist = sqrt( distSquared );
  142. //float farZ = g_FlashlightAttenuationFactors.w;
  143. //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f );
  144. //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) );
  145. //o.projPos_atten.w = saturate( o.projPos_atten.w );
  146. #if WORLDVERTEXTRANSITION
  147. o.worldPos_worldTransition.w = v.vColor.w;
  148. #endif
  149. return o;
  150. }