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.

191 lines
6.8 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // ps2b cascaded shadow mapping
  3. // can be used for OSX in absence of GL3.x
  4. // 1 2 1
  5. // 2 4 2
  6. // 1 2 1
  7. float CSMSampleShadowBuffer( sampler DepthSampler, const float3 shadowMapPos )
  8. {
  9. float fTexelEpsilon = g_flInvCascadeResolution;
  10. float3 shadowMapCenter_objDepth = shadowMapPos.xyz;
  11. float3 shadowMapCenter = shadowMapCenter_objDepth.xyz; // Center of shadow filter
  12. float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
  13. float4 vUV0 = shadowMapCenter.xyzx + float4( fTexelEpsilon, fTexelEpsilon, 0.0f, -fTexelEpsilon );
  14. float4 vUV1 = shadowMapCenter.xyzx + float4( fTexelEpsilon, -fTexelEpsilon, 0.0f, -fTexelEpsilon );
  15. float4 vOneTaps;
  16. vOneTaps.x = tex2Dproj( DepthSampler, float4( vUV0.xyz, 1 ) ).x;
  17. vOneTaps.y = tex2Dproj( DepthSampler, float4( vUV0.wyz, 1 ) ).x;
  18. vOneTaps.z = tex2Dproj( DepthSampler, float4( vUV1.xyz, 1 ) ).x;
  19. vOneTaps.w = tex2Dproj( DepthSampler, float4( vUV1.wyz, 1 ) ).x;
  20. float flSum = dot( vOneTaps, 1.0f );
  21. float4 vUV2 = shadowMapCenter.xyzx + float4( fTexelEpsilon, 0.0f, 0.0f, -fTexelEpsilon );
  22. float4 vUV3 = shadowMapCenter.xyzy + float4( 0.0f, -fTexelEpsilon, 0.0f, fTexelEpsilon );
  23. float4 vTwoTaps;
  24. vTwoTaps.x = tex2Dproj( DepthSampler, float4( vUV2.xyz, 1 ) ).x;
  25. vTwoTaps.y = tex2Dproj( DepthSampler, float4( vUV2.wyz, 1 ) ).x;
  26. vTwoTaps.z = tex2Dproj( DepthSampler, float4( vUV3.xyz, 1 ) ).x;
  27. vTwoTaps.w = tex2Dproj( DepthSampler, float4( vUV3.xwz, 1 ) ).x;
  28. flSum += dot( vTwoTaps, 2.0f );
  29. flSum += tex2Dproj( DepthSampler, float4( shadowMapCenter, 1 ) ).x * 4.0f;
  30. // Sum all 9 Taps
  31. return flSum * ( 1.0f / 16.0f );
  32. }
  33. float CSMSampleShadowBuffer1Tap( float2 vPositionLs, float flComparisonDepth )
  34. {
  35. #if ( CSM_VIEWMODELQUALITY == 0 )
  36. return tex2Dproj( CSMDepthAtlasSampler, float4( vPositionLs.x, vPositionLs.y, flComparisonDepth.x, 1.0f) ).x;
  37. #else
  38. return CSMSampleShadowBuffer( CSMDepthAtlasSampler, float3( vPositionLs.x, vPositionLs.y, flComparisonDepth ) );
  39. #endif
  40. }
  41. float CSMSampleShadowBuffer( float2 vPositionLs, float flComparisonDepth )
  42. {
  43. return CSMSampleShadowBuffer1Tap( vPositionLs, flComparisonDepth );
  44. }
  45. int CSMRangeTestExpanded( float2 vCoords )
  46. {
  47. // Returns true if the coordinates are within [.02,.98] - purposely a little sloppy to prevent the shadow filter kernel from leaking outside the cascade's portion of the atlas.
  48. vCoords = vCoords * ( 1.0f / .96f ) - float2( .02f / .96f, .02f / .96f );
  49. return ( dot( saturate( vCoords.xy ) - vCoords.xy, float2( 1, 1 ) ) == 0.0f );
  50. }
  51. int CSMRangeTestNonExpanded( float2 vCoords )
  52. {
  53. return ( dot( saturate( vCoords.xy ) - vCoords.xy, float2( 1, 1 ) ) == 0.0f );
  54. }
  55. float4 CSMTransformLightToTexture( float4 pos, float4x4 mat )
  56. {
  57. #if defined(_PS3)
  58. return mul( mat, pos );
  59. #else
  60. return mul( pos, mat );
  61. #endif
  62. }
  63. float CSMTransformLightToTexture_Element( float4 pos, float4 matRow )
  64. {
  65. return mul( pos, matRow );
  66. }
  67. #if ( CASCADE_SIZE == 0 )
  68. float CSMComputeShadowing( float3 vPositionWs )
  69. {
  70. return 1.0f;
  71. }
  72. #elif ( CSM_MODE >= 1 )
  73. #error Invalid CSM_MODE
  74. #else
  75. // CSM shader quality level 0 (the only supported level on gameconsole or ps_2_b)
  76. #if defined( CSM_LIGHTMAPPEDGENERIC )
  77. float CSMComputeShadowing( float3 vPositionWs )
  78. {
  79. float flShadowScalar = 1.0f;
  80. float4 vPosition4Ws = float4( vPositionWs.xyz, 1.0f );
  81. // float3 vPositionToSampleLs = float3( 0.0f, 0.0f, CSMTransformLightToTexture( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices[0] ).z );
  82. float3 vPositionToSampleLs = float3( 0.0f, 0.0f, CSMTransformLightToTexture_Element( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices0z ) );
  83. // only consider cascade 1 and 2 for console/ps_2_b perf
  84. float2 cascadeAtlasUVScale = float2(0.5, 0.5);
  85. float2 cascadeAtlasUVOffset = float2(0.5, 0.0); // offset cascade 1
  86. vPositionToSampleLs.x = CSMTransformLightToTexture_Element( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices1x );
  87. vPositionToSampleLs.y = CSMTransformLightToTexture_Element( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices1y );
  88. if ( !CSMRangeTestExpanded( vPositionToSampleLs.xy ) )
  89. {
  90. // vPositionToSampleLs.xy = CSMTransformLightToTexture( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices[2] ).xy;
  91. vPositionToSampleLs.x = CSMTransformLightToTexture_Element( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices2x );
  92. vPositionToSampleLs.y = CSMTransformLightToTexture_Element( vPosition4Ws.xyzw, g_matWorldToShadowTexMatrices2y );
  93. // cascadeAtlasUVOffset = cascadeAtlasUVOffsets_2;
  94. cascadeAtlasUVOffset = float2(0.0, 0.5);
  95. }
  96. vPositionToSampleLs.xy = saturate( vPositionToSampleLs.xy ) * cascadeAtlasUVScale + cascadeAtlasUVOffset;
  97. float3 vCamDelta = vPositionWs - g_vCamPosition.xyz;
  98. float flZLerpFactor = saturate( dot( vCamDelta, vCamDelta ) * g_flSunShadowingZLerpFactorRange + g_flSunShadowingZLerpFactorBase );
  99. flShadowScalar = CSMSampleShadowBuffer( vPositionToSampleLs.xy, vPositionToSampleLs.z );
  100. flShadowScalar = lerp( flShadowScalar, 1.0f, flZLerpFactor );
  101. return flShadowScalar;
  102. }
  103. #elif defined( CSM_VERTEXLIT_AND_UNLIT_GENERIC ) || defined( CSM_VERTEXLIT_AND_UNLIT_GENERIC_BUMP ) || defined( CSM_PHONG ) || defined( CSM_CHARACTER )
  104. float CSMComputeShadowing( float3 vPositionWs, float2 lightToTextureXform0or1, float2 lightToTextureXform2, float lightToTextureXform0z )
  105. {
  106. float flShadowScalar = 1.0f;
  107. float4 vPosition4Ws = float4( vPositionWs.xyz, 1.0f );
  108. float3 vPositionToSampleLs = float3( 0.0f, 0.0f, lightToTextureXform0z );
  109. #if ( CSM_VIEWMODELQUALITY == 0 )
  110. // only consider cascade 1 and 2 for console/ps_2_b perf
  111. float2 cascadeAtlasUVScale = float2(0.5, 0.5);
  112. float2 cascadeAtlasUVOffset = float2(0.5, 0.0); // offset cascade 1
  113. vPositionToSampleLs.xy = lightToTextureXform0or1.xy;
  114. if ( !CSMRangeTestExpanded( vPositionToSampleLs.xy ) )
  115. {
  116. vPositionToSampleLs.xy = lightToTextureXform2.xy;
  117. cascadeAtlasUVOffset = float2(0.0, 0.5);
  118. }
  119. vPositionToSampleLs.xy = saturate( vPositionToSampleLs.xy ) * cascadeAtlasUVScale + cascadeAtlasUVOffset;
  120. float3 vCamDelta = vPositionWs - g_vCamPosition.xyz;
  121. float flZLerpFactor = saturate( dot( vCamDelta, vCamDelta ) * g_flSunShadowingZLerpFactorRange + g_flSunShadowingZLerpFactorBase );
  122. flShadowScalar = CSMSampleShadowBuffer( vPositionToSampleLs.xy, vPositionToSampleLs.z );
  123. flShadowScalar = lerp( flShadowScalar, 1.0f, flZLerpFactor );
  124. #else
  125. // Viewmodel shadowing
  126. // only use cascade 0 for viewmodel rendering
  127. vPositionToSampleLs.xy = lightToTextureXform0or1.xy;
  128. vPositionToSampleLs.xy = saturate( vPositionToSampleLs.xy ) * float2(0.5, 0.5) + float2(0.5, 0.5); // cascade 3 for viewmodel
  129. flShadowScalar = CSMSampleShadowBuffer( vPositionToSampleLs.xy, vPositionToSampleLs.z );
  130. #endif // CSM_VIEWMODELQUALITY == 0
  131. return flShadowScalar;
  132. }
  133. #else
  134. #error This shader does not support CSM
  135. #endif
  136. #endif // #if ( CSM_MODE == 0 )