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.

103 lines
3.3 KiB

  1. // DYNAMIC: "FOGTYPE" "0..1"
  2. #include "common_vs_fxc.h"
  3. static const int g_FogType = FOGTYPE;
  4. const float4 cCustomConstants[6] : register( SHADER_SPECIFIC_CONST_0 );
  5. const float4 g_vLightPosition : register( SHADER_SPECIFIC_CONST_0 );
  6. const float4 g_vLightColor : register( SHADER_SPECIFIC_CONST_1 ); // range 0-1
  7. const float g_flLightIntensity : register( SHADER_SPECIFIC_CONST_2 ); // scales g_vLightColor
  8. struct VS_INPUT
  9. {
  10. // If this is float4, and the input is float3, the w component default to one.
  11. float4 vPos : POSITION;
  12. float2 vBumpTexCoord : TEXCOORD0;
  13. float4 vAmbientColor : COLOR0;
  14. };
  15. struct VS_OUTPUT
  16. {
  17. float4 projPos : POSITION;
  18. #if !defined( _X360 )
  19. float fog : FOG;
  20. #endif
  21. float2 vBumpTexCoord : TEXCOORD0;
  22. float3 vTangentSpaceLightDir : TEXCOORD1;
  23. float3 vAmbientColor : TEXCOORD2;
  24. float4 vDirLightScale : COLOR0;
  25. };
  26. VS_OUTPUT main( const VS_INPUT v )
  27. {
  28. VS_OUTPUT o;
  29. // Transform the input position.
  30. float4 projPos = mul( v.vPos, cModelViewProj );
  31. o.projPos = projPos;
  32. #if !defined( _X360 )
  33. // Setup fog.
  34. o.fog = CalcFog( mul( v.vPos, cModel[0] ), projPos, g_FogType );
  35. #endif
  36. // Copy texcoords over.
  37. o.vBumpTexCoord = v.vBumpTexCoord;
  38. // Copy the vertex color over.
  39. o.vAmbientColor = v.vAmbientColor;
  40. // ------------------------------------------------------------------------------
  41. // Generate a tangent space and rotate L.
  42. // This can be thought of as rotating the normal map to face the viewer.
  43. //
  44. // This is useful when a particle is way off to the side of the screen.
  45. // You should be looking at the half-sphere with a normal pointing from the
  46. // particle to the viewer. Instead, you're looking at the half-sphere with
  47. // a normal along Z. This tangent space builder code fixes the problem.
  48. //
  49. // Note that since the model and view matrices are identity, the coordinate
  50. // system has X=right, Y=up, and Z=behind you (negative Z goes into the screen).
  51. // ------------------------------------------------------------------------------
  52. // This basis wants Z positive going into the screen so flip it here.
  53. float4 vForward = normalize( float4( v.vPos.x, v.vPos.y, -v.vPos.z, 1 ) );
  54. // This is the same as CrossProduct( vForward, Vector( 1, 0, 0 ) )
  55. float4 vUp = normalize( float4( 0, vForward.z, -vForward.y, vForward.w ) );
  56. // vRight = CrossProduct( vUp, vForward )
  57. float4 vRight = vUp.yzxw * vForward.zxyw;
  58. vRight += -vUp.zxyw * vForward.yzxw;
  59. // Put the light in tangent space.
  60. float4 vToLight = g_vLightPosition - v.vPos;
  61. float4 vTangentSpaceLight = vRight*vToLight.x + vUp*vToLight.y + vForward*vToLight.z;
  62. // Output texcoord 1 holds the normalized transformed light direction.
  63. o.vTangentSpaceLightDir = normalize( vTangentSpaceLight ) * 0.5 + 0.5; // make it 0-1 for the pixel shader
  64. // Handle oversaturation here. The shader code already scaled the light color so its max value is 1,
  65. // so if our intensity/distance scale is > 1, then all we need to do is use the light color.
  66. float flTransposedLenSqr = dot( vTangentSpaceLight, vTangentSpaceLight );
  67. float flScaledIntensity = g_flLightIntensity / flTransposedLenSqr;
  68. if ( flScaledIntensity > 1 )
  69. {
  70. o.vDirLightScale.xyz = g_vLightColor;
  71. }
  72. else
  73. {
  74. o.vDirLightScale.xyz = g_vLightColor * flScaledIntensity;
  75. }
  76. // Alpha comes right from the vertex color.
  77. o.vDirLightScale.a = v.vAmbientColor.a;
  78. return o;
  79. }