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.

254 lines
7.7 KiB

  1. // STATIC: "ENVMAP_MASK" "0..1"
  2. // STATIC: "TANGENTSPACE" "0..1"
  3. // STATIC: "BUMPMAP" "0..1"
  4. // STATIC: "DIFFUSEBUMPMAP" "0..1"
  5. // STATIC: "VERTEXCOLOR" "0..1"
  6. // STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1"
  7. // STATIC: "RELIEF_MAPPING" "0..0"
  8. // STATIC: "SEAMLESS" "0..1"
  9. // STATIC: "BUMPMASK" "0..1"
  10. // STATIC: "FLASHLIGHT" "0..1" [XBOX]
  11. // DYNAMIC: "FASTPATH" "0..1"
  12. // DYNAMIC: "DOWATERFOG" "0..1"
  13. // DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC]
  14. // DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX]
  15. // This should not be a combo since I'm a moron with the tangent space and the flashlight.
  16. // SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP
  17. // SKIP: $SEAMLESS && $RELIEF_MAPPING
  18. // SKIP: $BUMPMASK && $RELIEF_MAPPING
  19. // SKIP: $BUMPMASK && $SEAMLESS
  20. #include "common_vs_fxc.h"
  21. static const int g_FogType = DOWATERFOG;
  22. static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK;
  23. static const bool g_bTangentSpace = TANGENTSPACE;
  24. static const bool g_bBumpmap = BUMPMAP;
  25. static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP;
  26. static const bool g_bVertexColor = VERTEXCOLOR;
  27. static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR;
  28. static const bool g_BumpMask = BUMPMASK;
  29. #if SEAMLESS
  30. const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 );
  31. #define SEAMLESS_SCALE (SeamlessScale.x)
  32. #else
  33. const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
  34. const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 );
  35. #endif
  36. // This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset.
  37. const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 );
  38. const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 );
  39. const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest!
  40. struct VS_INPUT
  41. {
  42. float3 vPos : POSITION;
  43. float4 vNormal : NORMAL;
  44. float2 vBaseTexCoord : TEXCOORD0;
  45. float2 vLightmapTexCoord : TEXCOORD1;
  46. float2 vLightmapTexCoordOffset : TEXCOORD2;
  47. float3 vTangentS : TANGENT;
  48. float3 vTangentT : BINORMAL;
  49. float4 vColor : COLOR0;
  50. };
  51. struct VS_OUTPUT
  52. {
  53. float4 projPos : POSITION;
  54. #if !defined( _X360 )
  55. float fog : FOG;
  56. #endif
  57. #if SEAMLESS
  58. float3 SeamlessTexCoord : TEXCOORD0; // x y z
  59. float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask
  60. #else
  61. float2 baseTexCoord : TEXCOORD0;
  62. // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords.
  63. #if RELIEF_MAPPING
  64. float3 TangentSpaceViewRay : TEXCOORD1;
  65. #else
  66. float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1;
  67. #endif
  68. #endif
  69. float4 lightmapTexCoord1And2 : TEXCOORD2;
  70. float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale
  71. float4 worldPos_projPosZ : TEXCOORD4;
  72. #if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 )
  73. float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7
  74. #endif
  75. float4 vertexColor : COLOR; // in seamless, r g b = blend weights
  76. float4 vertexBlendX_fogFactorW : COLOR1;
  77. // Extra iterators on 360, used in flashlight combo
  78. #if defined( _X360 )
  79. #if FLASHLIGHT
  80. float4 flashlightSpacePos : TEXCOORD8;
  81. float4 vProjPos : TEXCOORD9;
  82. #endif
  83. #endif
  84. };
  85. VS_OUTPUT main( const VS_INPUT v )
  86. {
  87. VS_OUTPUT o = ( VS_OUTPUT )0;
  88. float3 vObjNormal;
  89. DecompressVertex_Normal( v.vNormal, vObjNormal );
  90. float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] );
  91. float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj );
  92. o.projPos = vProjPos;
  93. vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ );
  94. o.worldPos_projPosZ = float4( worldPos, vProjPos.z );
  95. float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
  96. #if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 )
  97. float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] );
  98. float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] );
  99. #if SEAMLESS && BUMPMAP && defined( _X360 )
  100. float3 n = normalize( worldNormal );
  101. float3 n2 = n * n; // sums to 1.
  102. o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) );
  103. o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) );
  104. o.tangentSpaceTranspose[2] = worldNormal;
  105. #else
  106. o.tangentSpaceTranspose[0] = worldTangentS;
  107. o.tangentSpaceTranspose[1] = worldTangentT;
  108. o.tangentSpaceTranspose[2] = worldNormal;
  109. #endif
  110. #endif
  111. float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos);
  112. #if SEAMLESS
  113. {
  114. // we need to fill in the texture coordinate projections
  115. o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos;
  116. }
  117. #else
  118. {
  119. if (FASTPATH)
  120. {
  121. o.baseTexCoord.xy = v.vBaseTexCoord;
  122. }
  123. else
  124. {
  125. o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w;
  126. o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w;
  127. }
  128. #if ( RELIEF_MAPPING == 0 )
  129. {
  130. // calculate detailorbumptexcoord
  131. if ( FASTPATH )
  132. o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy;
  133. else
  134. {
  135. o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w;
  136. o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w;
  137. }
  138. }
  139. #endif
  140. }
  141. #endif
  142. if ( FASTPATH )
  143. {
  144. o.lightmapTexCoord3.zw = v.vBaseTexCoord;
  145. }
  146. else
  147. {
  148. o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w;
  149. o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w;
  150. }
  151. // compute lightmap coordinates
  152. if( g_bBumpmap && g_bBumpmapDiffuseLighting )
  153. {
  154. o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset;
  155. float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset;
  156. float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset;
  157. // reversed component order
  158. o.lightmapTexCoord1And2.w = lightmapTexCoord2.x;
  159. o.lightmapTexCoord1And2.z = lightmapTexCoord2.y;
  160. o.lightmapTexCoord3.xy = lightmapTexCoord3;
  161. }
  162. else
  163. {
  164. o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord;
  165. }
  166. #if ( RELIEF_MAPPING == 0)
  167. if( g_UseSeparateEnvmapMask || g_BumpMask )
  168. {
  169. // reversed component order
  170. # if FASTPATH
  171. o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy;
  172. # else
  173. o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w;
  174. o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w;
  175. # endif
  176. }
  177. #endif
  178. o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType );
  179. #if !defined( _X360 )
  180. o.fog = o.vertexBlendX_fogFactorW;
  181. #endif
  182. if (!g_bVertexColor)
  183. {
  184. o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a );
  185. }
  186. else
  187. {
  188. #if FASTPATH
  189. o.vertexColor = v.vColor;
  190. #else
  191. if ( g_bVertexAlphaTexBlendFactor )
  192. {
  193. o.vertexColor.rgb = v.vColor.rgb;
  194. o.vertexColor.a = cModulationColor.a;
  195. }
  196. else
  197. {
  198. o.vertexColor = v.vColor;
  199. o.vertexColor.a *= cModulationColor.a;
  200. }
  201. #endif
  202. }
  203. #if SEAMLESS
  204. // compute belnd weights in rgb
  205. float3 vNormal=normalize( worldNormal );
  206. o.vertexColor.xyz = vNormal * vNormal; // sums to 1.
  207. #endif
  208. // On 360, we have extra iterators and can fold the flashlight into this shader
  209. #if defined( _X360 )
  210. #if FLASHLIGHT
  211. o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture );
  212. o.vProjPos = vProjPos;
  213. #endif
  214. #endif
  215. if ( g_bVertexAlphaTexBlendFactor )
  216. {
  217. o.vertexBlendX_fogFactorW.r = v.vColor.a;
  218. }
  219. return o;
  220. }