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.

199 lines
6.4 KiB

  1. //========== Copyright (c) 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. #include "common_fog_vs_supportsvertexfog_fxc.h"
  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 HARDWAREFOGBLEND
  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. #if HARDWAREFOGBLEND || DOPIXELFOG
  58. float3 projPos_fogFactorW : TEXCOORD6;
  59. #else
  60. float4 projPos_fogFactorW : TEXCOORD6;
  61. #endif
  62. float4 vNormalSqr : COLOR1;
  63. };
  64. float RemapValClamped( float val, float A, float B, float C, float D)
  65. {
  66. float cVal = (val - A) / (B - A);
  67. cVal = saturate( cVal );
  68. return C + (D - C) * cVal;
  69. }
  70. VS_OUTPUT main( const VS_INPUT v )
  71. {
  72. VS_OUTPUT o = (VS_OUTPUT)0;
  73. float3 vObjNormal;
  74. DecompressVertex_Normal( v.vNormal, vObjNormal );
  75. float4 projPos;
  76. float3 worldPos;
  77. float3 worldNormal;
  78. float3 eyeVector;
  79. //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360
  80. worldPos = mul4x3( float4( v.vPos, 1 ), cModel[0] );
  81. projPos = mul( float4( worldPos, 1 ), cViewProj );
  82. o.projPos = projPos;
  83. #ifdef _PS3
  84. // Account for OpenGL's flipped y coordinate and expanded z range [-1,1] instead of [0,1]
  85. o.projPos.y = -o.projPos.y;
  86. o.projPos.z = 2.0f * o.projPos.z - o.projPos.w;
  87. #endif // _PS3
  88. o.projPos_fogFactorW.xyz = projPos.xyw;
  89. worldNormal = mul3x3( vObjNormal, ( float3x3 )cModel[0] );
  90. o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f );
  91. #if HARDWAREFOGBLEND
  92. o.fog = CalcFixedFunctionFog( worldPos, g_FogType );
  93. #endif
  94. #if !DOPIXELFOG && !HARDWAREFOGBLEND
  95. o.projPos_fogFactorW.w = CalcNonFixedFunctionFog( worldPos, g_FogType );
  96. #endif
  97. #if NORMALMAP
  98. float3 worldTangentS = mul3x3( v.vTangentS, ( float3x3 )cModel[0] );
  99. float3 worldTangentT = mul3x3( v.vTangentT, ( float3x3 )cModel[0] );
  100. #endif
  101. #if SEAMLESS
  102. float3 vNormal=normalize( worldNormal );
  103. o.vNormalSqr.xyz = vNormal * vNormal; // sums to 1.
  104. o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos;
  105. // Generate new tangent and binormal with seamless projection
  106. #if NORMALMAP
  107. // Brute-force for prototype - This must match the projection in the pixel shader!
  108. //float3 vVecX = { 1.0f, 0.0f, 0.0f };
  109. //float3 vVecY = { 0.0f, 1.0f, 0.0f };
  110. //float3 vVecZ = { 0.0f, 0.0f, 1.0f };
  111. //worldTangentS.xyz = normalize( ( o.vNormalSqr.x * vVecZ.xyz ) + ( o.vNormalSqr.y * vVecX.xyz ) + ( o.vNormalSqr.z * vVecX.xyz ) );
  112. //worldTangentT.xyz = normalize( ( o.vNormalSqr.x * vVecY.xyz ) + ( o.vNormalSqr.y * vVecZ.xyz ) + ( o.vNormalSqr.z * vVecY.xyz ) );
  113. // Optimized version - This must match the projection in the pixel shader!
  114. worldTangentS.xyz = normalize( float3( o.vNormalSqr.y + o.vNormalSqr.z, 0.0f, o.vNormalSqr.x ) );
  115. worldTangentT.xyz = normalize( float3( 0.0f, o.vNormalSqr.x + o.vNormalSqr.z, o.vNormalSqr.y ) );
  116. #endif
  117. #else
  118. #if (SEAMLESS == 0 )
  119. o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0].xy ) + cBaseTexCoordTransform[0].w;
  120. o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1].xy ) + cBaseTexCoordTransform[1].w;
  121. #endif
  122. #endif
  123. float4 spotTexCoord = TransformFlashlightWorldToTexture( worldPos, g_FlashlightWorldToTexture );
  124. o.spotTexCoord = spotTexCoord.xyzw;
  125. float3 worldPosToLightVector = g_FlashlightPos - worldPos;
  126. #if NORMALMAP
  127. #if (DETAIL == 0)
  128. o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0].xy ) + cNormalMapOrDetailTexCoordTransform[0].w;
  129. o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1].xy ) + cNormalMapOrDetailTexCoordTransform[1].w;
  130. #else
  131. #if SEAMLESS
  132. o.normalMapTexCoord = v.vBaseTexCoord;
  133. #else
  134. o.normalMapTexCoord = o.baseTexCoord;
  135. #endif
  136. #endif
  137. o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS );
  138. o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT );
  139. o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal );
  140. #else
  141. o.worldPosToLightVector = worldPosToLightVector;
  142. o.normal = worldNormal;
  143. #endif
  144. #if DETAIL
  145. o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0].xy ) + cNormalMapOrDetailTexCoordTransform[0].w;
  146. o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1].xy ) + cNormalMapOrDetailTexCoordTransform[1].w;
  147. #else
  148. o.detailCoords = float2(0,0);
  149. #endif
  150. //float3 delta = worldPosToLightVector;
  151. //float distSquared = dot( delta, delta );
  152. //float dist = sqrt( distSquared );
  153. //float farZ = g_FlashlightAttenuationFactors.w;
  154. //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f );
  155. //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) );
  156. //o.projPos_atten.w = saturate( o.projPos_atten.w );
  157. #if WORLDVERTEXTRANSITION
  158. o.worldPos_worldTransition.w = v.vColor.w;
  159. #endif
  160. return o;
  161. }