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.

132 lines
4.2 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef FRUSTUM_H
  9. #define FRUSTUM_H
  10. #include "mathlib/camera.h"
  11. #include "mathlib/ssemath.h"
  12. #include "worldrenderer/bvhsupport.h"
  13. class CWorldRenderFrustum : public CFrustum
  14. {
  15. public:
  16. //
  17. // Slight modification of
  18. // http://appsrv.cse.cuhk.edu.hk/~fzhang/pssm_vrcia/shadow_vrcia.pdf
  19. //
  20. float CalculateSplitPlaneDistance( int nSplit, int nShadowSplits, float flMaxShadowDistance )
  21. {
  22. float fIM = (float)nSplit / (float)nShadowSplits;
  23. float f = MIN( flMaxShadowDistance, m_camera.m_flZFar );
  24. float n = m_camera.m_flZNear;
  25. float fBias = 0.1f;
  26. float flLog = n + ( n * powf( f / n, fIM ) );
  27. float flLinear = ( n + ( f - n ) * fIM );
  28. return ( flLog * 0.9f + flLinear * 0.10f ) + fBias;
  29. }
  30. void UpdateLightFrustumFromClippedVolume( float flNear, float flFar )
  31. {
  32. //VMatrix mLightProj = OrthoMatrixRH( m_fSplitXSize, m_fSplitZSize, MAX( m_camera.m_flZNear, flNear ), MIN( m_camera.m_flZFar, flFar ) );
  33. VMatrix mLightProj = OrthoMatrixRH( m_fSplitXSize, m_fSplitZSize, flNear, flFar );
  34. SetProj( mLightProj );
  35. CalcViewProj();
  36. }
  37. void SetSplitSizes( float flXSize, float flZSize ) { m_fSplitXSize = flXSize; m_fSplitZSize = flZSize; }
  38. void CalculateLightFrusta( CWorldRenderFrustum **ppOutFrustums, int nShadowSplits, Vector vLightDir, float flLightDistance, float flLightFarPlane, float flMaxShadowDistance )
  39. {
  40. float fPreviousSplit = m_camera.m_flZNear;
  41. Vector vEye = m_camera.m_origin;
  42. Vector vEyeDir = m_forward;
  43. vEyeDir.NormalizeInPlace();
  44. vLightDir.NormalizeInPlace();
  45. for( int i=0; i<nShadowSplits; i++ )
  46. {
  47. float fSplitPlane = CalculateSplitPlaneDistance( i + 1, nShadowSplits, flMaxShadowDistance );
  48. float fZDist = fSplitPlane - fPreviousSplit;
  49. float fCenterZ = ( fPreviousSplit + fSplitPlane ) * 0.5f;
  50. float fXSize = tanf( DEG2RAD(m_camera.m_flFOVX) * 0.5f ) * fSplitPlane * 2.0f;
  51. fXSize += ( nShadowSplits - i ) * 12.0f;
  52. fZDist *= 1.10f;
  53. #if ( SNAP_SHADOW_MAP == 1 )
  54. fXSize = max( fXSize, fZDist );
  55. fZDist = fXSize;
  56. #endif
  57. Vector vLightLookAt = vEye + vEyeDir * fCenterZ;
  58. Vector vLightPosition = vLightLookAt + vLightDir * flLightDistance;
  59. // Create the light frustum
  60. VMatrix mLightView;
  61. VMatrix mLightProj;
  62. #if ( SNAP_SHADOW_MAP == 1 )
  63. Vector vFrustumUp( 0,1,0 );
  64. #else
  65. Vector vFrustumUp = vEyeDir;
  66. #endif
  67. mLightView = ViewMatrixRH( vLightPosition, vLightLookAt, vFrustumUp );
  68. #if ( SNAP_SHADOW_MAP == 1 )
  69. // Clamp camera movement to full-pixels only
  70. float fUnitsPerTexel = fXSize / (float)g_ShadowDepthTextureSize;
  71. mLightView._41 = floorf( mLightView._41 / fUnitsPerTexel ) * fUnitsPerTexel;
  72. mLightView._42 = floorf( mLightView._42 / fUnitsPerTexel ) * fUnitsPerTexel;
  73. #endif
  74. CWorldRenderFrustum *pOutFrustum = (ppOutFrustums)[i];
  75. mLightProj = OrthoMatrixRH( fXSize, fZDist, m_camera.m_flZNear, flLightFarPlane );
  76. pOutFrustum->SetSplitSizes( fXSize, fZDist );
  77. pOutFrustum->SetView( mLightView );
  78. pOutFrustum->SetProj( mLightProj );
  79. pOutFrustum->CalcViewProj();
  80. pOutFrustum->SetCameraPosition( vLightPosition );
  81. Vector vLightForward;
  82. Vector vLightLeft;
  83. Vector vLightUp;
  84. VMatrix mView( pOutFrustum->GetView() );
  85. MatrixGetRow( mView, 0, &vLightLeft );
  86. MatrixGetRow( mView, 1, &vLightUp );
  87. MatrixGetRow( mView, 2, &vLightForward );
  88. Vector vLightRight = -vLightLeft;
  89. vLightForward = -vLightForward;
  90. pOutFrustum->SetNearFarPlanes( m_camera.m_flZNear, flLightFarPlane );
  91. pOutFrustum->SetForward( -vLightDir );
  92. Frustum_t lightFrustum;
  93. VPlane pSixPlanes[6];
  94. GenerateOrthoFrustum( vec3_origin, vLightForward, vLightRight, vLightUp,
  95. -fXSize/2.0f, fXSize/2.0f, -fZDist/2.0f, fZDist/2.0f,
  96. m_camera.m_flZNear, flLightFarPlane,
  97. pSixPlanes );
  98. lightFrustum.SetPlanes( pSixPlanes );
  99. pOutFrustum->SetFrustum( lightFrustum );
  100. fPreviousSplit = fSplitPlane;
  101. }
  102. }
  103. protected:
  104. float m_fSplitXSize;
  105. float m_fSplitZSize;
  106. };
  107. #endif