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.

88 lines
3.2 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. #include "common_vs_fxc.h"
  3. #include "spline_fxc.h"
  4. const hlsl_float4x3 cModelView : register(SHADER_SPECIFIC_CONST_0);
  5. const float4x4 cProj : register(SHADER_SPECIFIC_CONST_3);
  6. const float g_MinPixelSize : register(SHADER_SPECIFIC_CONST_7);
  7. const float g_Const8 : register(SHADER_SPECIFIC_CONST_8);
  8. #define g_FlTilingMultiplier g_Const8.x
  9. struct VS_INPUT
  10. {
  11. // This is all of the stuff that we ever use.
  12. float4 vTint : COLOR;
  13. float4 vParms : POSITION; // T V side_id
  14. float4 vSplinePt0 : TEXCOORD0; // x y z rad
  15. float4 vSplinePt1 : TEXCOORD1; // x y z rad
  16. float4 vSplinePt2 : TEXCOORD2; // x y z rad
  17. float4 vSplinePt3 : TEXCOORD3; // x y z rad
  18. };
  19. // VS_OUTPUT in a common file.
  20. #include "common_splinerope_fxc.h"
  21. #define P0 (v.vSplinePt0)
  22. #define P1 (v.vSplinePt1)
  23. #define P2 (v.vSplinePt2)
  24. #define P3 (v.vSplinePt3)
  25. VS_OUTPUT main( const VS_INPUT v )
  26. {
  27. VS_OUTPUT o;
  28. // posrad.xyz is worldspace position and posrad.w is worldspace diameter.
  29. float4 posrad = CatmullRomSpline( P0, P1, P2, P3, v.vParms.x );
  30. // calculate projected position here so that we can figure out how much to bloat the diameter to avoid aliasing of the sort where you skip pixels in a segment.
  31. {
  32. // PERF FIXME!! This could be simplified quite a bit if this ever becomes a bottleneck. I feel dirty.
  33. // Get the view-space position for two points that are posrad.w units away from each other horizontally.
  34. float3 viewPos1 = mul4x3( float4( posrad.xyz, 1.0f ), cModelView );
  35. float3 viewPos2 = viewPos1 + float3( posrad.w, 0.0f, 0.0f );
  36. // Project both points.
  37. float4 projPos1 = mul( float4( viewPos1, 1.0f ), cProj );
  38. float4 projPos2 = mul( float4( viewPos2, 1.0f ), cProj );
  39. // Get the distance of the two points from each other in normalized screen space.
  40. float projectedDiameterInPixels = abs( ( projPos1.x / projPos1.w ) - ( projPos2.x / projPos2.w ) );
  41. // Compare the distance between the two points to the minimum allowed to keep from skipping pixels and causing aliasing.
  42. if ( projectedDiameterInPixels < g_MinPixelSize )
  43. {
  44. // Scale the radius in world space so that it is bigger than the required pixel size in screen space.
  45. posrad.w *= ( g_MinPixelSize / projectedDiameterInPixels );
  46. }
  47. }
  48. float3 v2p = float3( 0, 0, 1 );
  49. v2p = posrad.xyz - cEyePos; // screen aligned
  50. float3 tangent = DCatmullRomSpline3( P0, P1, P2, P3, v.vParms.x );
  51. float3 ofs = normalize( cross( v2p, normalize( tangent ) ) );
  52. posrad.xyz += ofs * ( posrad.w * ( v.vParms.z - .5 ) );
  53. o.projPos = mul( float4(posrad.xyz, 1.0f), cViewProj );
  54. #ifdef _PS3
  55. // Account for OpenGL's flipped y coordinate and expanded z range [-1,1] instead of [0,1]
  56. o.projPos.y = -o.projPos.y;
  57. o.projPos.z = 2.0f * o.projPos.z - o.projPos.w;
  58. #endif // _PS3
  59. o.worldPos_projPosZ.xyz = posrad.xyz;
  60. o.worldPos_projPosZ.w = o.projPos.z;
  61. o.texCoord.xy = float2( 1.0f - v.vParms.z, v.vParms.y );
  62. o.texCoord.y *= g_FlTilingMultiplier;
  63. o.argbcolor = float4( v.vTint.rgb, v.vTint.a );
  64. #if !defined( _X360 ) && !defined( SHADER_MODEL_VS_3_0 )
  65. {
  66. o.fog = CalcFixedFunctionFog( posrad.xyz, 0 );
  67. }
  68. #endif
  69. return o;
  70. }