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.

280 lines
8.5 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Depth of field material
  4. //
  5. //===========================================================================//
  6. #include "BaseVSShader.h"
  7. #include "depth_of_field_vs20.inc"
  8. #include "depth_of_field_ps20b.inc"
  9. #include "convar.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. ConVar mat_dof_max_blur_radius( "mat_dof_max_blur_radius", "10" );
  13. ConVar mat_dof_quality( "mat_dof_quality", "0" );
  14. // 8 samples
  15. static const float s_flPoissonConstsQuality0[16] = {
  16. 0.0, 0.0,
  17. 0.527837, -0.085868,
  18. -0.040088, 0.536087,
  19. -0.670445, -0.179949,
  20. -0.419418, -0.616039,
  21. 0.440453, -0.639399,
  22. -0.757088, 0.349334,
  23. 0.574619, 0.685879
  24. };
  25. // 16 samples
  26. static const float s_flPoissonConstsQuality1[32] = {
  27. 0.0747, -0.8341,
  28. -0.9138, 0.3251,
  29. 0.8667, -0.3029,
  30. -0.4642, 0.2187,
  31. -0.1505, 0.7320,
  32. 0.7310, -0.6786,
  33. 0.2859, -0.3254,
  34. -0.1311, -0.2292,
  35. 0.3518, 0.6470,
  36. -0.7485, -0.6307,
  37. 0.1687, 0.1873,
  38. -0.3604, -0.7483,
  39. -0.5658, -0.1521,
  40. 0.7102, 0.0536,
  41. -0.6056, 0.7747,
  42. 0.7793, 0.6194
  43. };
  44. // 32 samples
  45. static const float s_flPoissonConstsQuality2[64] = {
  46. 0.0854f, -0.0644f,
  47. 0.8744f, 0.1665f,
  48. 0.2329f, 0.3995f,
  49. -0.7804f, 0.5482f,
  50. -0.4577f, 0.7647f,
  51. -0.1936f, 0.5564f,
  52. 0.4205f, -0.5768f,
  53. -0.0304f, -0.9050f,
  54. -0.5215f, 0.1854f,
  55. 0.3161f, -0.2954f,
  56. 0.0666f, -0.5564f,
  57. -0.2137f, -0.0072f,
  58. -0.4112f, -0.3311f,
  59. 0.6438f, -0.2484f,
  60. -0.9055f, -0.0360f,
  61. 0.8323f, 0.5268f,
  62. 0.5592f, 0.3459f,
  63. -0.6797f, -0.5201f,
  64. -0.4325f, -0.8857f,
  65. 0.8768f, -0.4197f,
  66. 0.3090f, -0.8646f,
  67. 0.5034f, 0.8603f,
  68. 0.3752f, 0.0627f,
  69. -0.0161f, 0.2627f,
  70. 0.0969f, 0.7054f,
  71. -0.2291f, -0.6595f,
  72. -0.5887f, -0.1100f,
  73. 0.7048f, -0.6528f,
  74. -0.8438f, 0.2706f,
  75. -0.5061f, 0.4653f,
  76. -0.1245f, -0.3302f,
  77. -0.1801f, 0.8486f
  78. };
  79. DEFINE_FALLBACK_SHADER( DepthOfField, DepthOfField_dx9 )
  80. BEGIN_VS_SHADER_FLAGS( DepthOfField_dx9, "Depth of Field", SHADER_NOT_EDITABLE )
  81. BEGIN_SHADER_PARAMS
  82. SHADER_PARAM( SMALLFB, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallFB1", "Downsampled backbuffer" )
  83. SHADER_PARAM( NEARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Near plane depth" )
  84. SHADER_PARAM( FARPLANE, SHADER_PARAM_TYPE_FLOAT, "0", "Far plane depth" )
  85. SHADER_PARAM( NEARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near blur plane depth" )
  86. SHADER_PARAM( NEARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Near focus plane depth" )
  87. SHADER_PARAM( FARFOCUSDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far focus plane depth" )
  88. SHADER_PARAM( FARBLURDEPTH, SHADER_PARAM_TYPE_FLOAT, "0", "Far blur plane depth" )
  89. SHADER_PARAM( NEARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max near blur radius" )
  90. SHADER_PARAM( FARBLURRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Max far blur radius" )
  91. SHADER_PARAM( QUALITY, SHADER_PARAM_TYPE_INTEGER, "0", "Quality level. Selects different algorithms." )
  92. END_SHADER_PARAMS
  93. SHADER_INIT_PARAMS()
  94. {
  95. SET_PARAM_STRING_IF_NOT_DEFINED( SMALLFB, "_rt_SmallFB1" );
  96. SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARPLANE, 0.0f );
  97. SET_PARAM_FLOAT_IF_NOT_DEFINED( FARPLANE, 0.0f );
  98. SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURDEPTH, 0.0f );
  99. SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARFOCUSDEPTH, 0.0f );
  100. SET_PARAM_FLOAT_IF_NOT_DEFINED( FARFOCUSDEPTH, 0.0f );
  101. SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURDEPTH, 0.0f );
  102. SET_PARAM_FLOAT_IF_NOT_DEFINED( NEARBLURRADIUS, 0.0f );
  103. SET_PARAM_FLOAT_IF_NOT_DEFINED( FARBLURRADIUS, 0.0f );
  104. SET_PARAM_INT_IF_NOT_DEFINED( QUALITY, 0 );
  105. }
  106. SHADER_FALLBACK
  107. {
  108. if ( g_pHardwareConfig->GetDXSupportLevel() < 92 )
  109. {
  110. return "Wireframe";
  111. }
  112. return 0;
  113. }
  114. SHADER_INIT
  115. {
  116. if ( params[BASETEXTURE]->IsDefined() )
  117. {
  118. LoadTexture( BASETEXTURE );
  119. }
  120. if ( params[SMALLFB]->IsDefined() )
  121. {
  122. LoadTexture( SMALLFB );
  123. }
  124. }
  125. SHADER_DRAW
  126. {
  127. SHADOW_STATE
  128. {
  129. pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 );
  130. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  131. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
  132. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  133. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
  134. pShaderShadow->EnableSRGBWrite( false );
  135. DECLARE_STATIC_VERTEX_SHADER( depth_of_field_vs20 );
  136. SET_STATIC_VERTEX_SHADER( depth_of_field_vs20 );
  137. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  138. {
  139. DECLARE_STATIC_PIXEL_SHADER( depth_of_field_ps20b );
  140. SET_STATIC_PIXEL_SHADER( depth_of_field_ps20b );
  141. }
  142. else
  143. {
  144. Assert( !"No ps_2_b. This shouldn't be happening" );
  145. }
  146. pShaderShadow->EnableDepthWrites( false );
  147. pShaderShadow->EnableAlphaWrites( false );
  148. }
  149. DYNAMIC_STATE
  150. {
  151. DECLARE_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 );
  152. SET_DYNAMIC_VERTEX_SHADER( depth_of_field_vs20 );
  153. // Bind textures
  154. BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_NONE, BASETEXTURE );
  155. BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, SMALLFB );
  156. // near blur = blur of stuff in front of focus range
  157. // far blur = blur of stuff behind focus range
  158. // C0: set near/far blur and focus distances
  159. // x = near blur distance
  160. // y = near focus distance
  161. // z = far focus distance
  162. // w = far blur distance
  163. // C1:
  164. // x = blur radius for near blur (in pixels)
  165. // y = blur radius for far blur (in pixels)
  166. // TODO: Specifying this stuff in pixels makes blurs look smaller on high backbuffer resolutions.
  167. // This might be a problem for tweaking these values.
  168. float vConst[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
  169. vConst[0] = params[NEARBLURDEPTH]->GetFloatValue();
  170. vConst[1] = params[NEARFOCUSDEPTH]->GetFloatValue();
  171. vConst[2] = params[FARFOCUSDEPTH]->GetFloatValue();
  172. vConst[3] = params[FARBLURDEPTH]->GetFloatValue();;
  173. // max blur radius will need to be set based on qulity level and screen res
  174. vConst[4] = mat_dof_max_blur_radius.GetFloat();
  175. vConst[5] = MIN( params[NEARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4]; // near and far blur radius as fraction of max radius
  176. vConst[6] = MIN( params[FARBLURRADIUS]->GetFloatValue(), vConst[4] ) / vConst[4];
  177. vConst[8] = params[NEARPLANE]->GetFloatValue();
  178. vConst[9] = params[FARPLANE]->GetFloatValue();
  179. // 8192 is the magic number for HDR mode 3 (see FLOAT_RENDERPARM_DEST_ALPHA_DEPTH_SCALE in shaderapidx8.cpp)
  180. vConst[10] = 8192.0f * ( vConst[9] - vConst[8] ) / vConst[9];
  181. vConst[12] = vConst[10] / ( vConst[0] - vConst[1] );
  182. vConst[13] = ( vConst[8] - vConst[1] ) / ( vConst[0] - vConst[1] );
  183. vConst[14] = vConst[10] / ( vConst[3] - vConst[2] );
  184. vConst[15] = ( vConst[8] - vConst[2] ) / ( vConst[3] - vConst[2] );
  185. pShaderAPI->SetPixelShaderConstant( 0, vConst, 4 );
  186. // set up poisson sample location constants pre-divided by screen res
  187. int nNumPoissonSamples = 0;
  188. const float *pPoissonSrc = NULL;
  189. switch ( params[QUALITY]->GetIntValue() )
  190. {
  191. case 0:
  192. // NOTE: These must match the shader
  193. nNumPoissonSamples = 8;
  194. pPoissonSrc = s_flPoissonConstsQuality0;
  195. break;
  196. case 1:
  197. case 2:
  198. nNumPoissonSamples = 16;
  199. pPoissonSrc = s_flPoissonConstsQuality1;
  200. break;
  201. case 3:
  202. nNumPoissonSamples = 32;
  203. pPoissonSrc = s_flPoissonConstsQuality2;
  204. break;
  205. default:
  206. Warning( "Invalid mat_dof_quality value. Resetting to 0.\n" );
  207. mat_dof_quality.SetValue( 0 );
  208. nNumPoissonSamples = 8;
  209. pPoissonSrc = s_flPoissonConstsQuality0;
  210. break;
  211. }
  212. float vPoissonConst[64]; // temp table
  213. // Get texture dimensions
  214. ITexture *pTex = params[BASETEXTURE]->GetTextureValue();
  215. Assert( pTex );
  216. float flInvTexWidth = 1.0f / static_cast<float>( pTex->GetActualWidth() );
  217. float flInvTexHeight = 1.0f / static_cast<float>( pTex->GetActualHeight() );
  218. for ( int i = 0; i < nNumPoissonSamples; i++ )
  219. {
  220. vPoissonConst[ 2*i ] = pPoissonSrc[ 2*i ] * flInvTexWidth;
  221. vPoissonConst[ 2*i+1 ] = pPoissonSrc[ 2*i+1 ] * flInvTexHeight;
  222. }
  223. // swizzle every other 2-tuple so that I can use the free .wz swizzle in the shader
  224. for ( int i = 1; i < nNumPoissonSamples; i += 2)
  225. {
  226. float t = vPoissonConst[ 2*i ];
  227. vPoissonConst[ 2*i ] = vPoissonConst[ 2*i+1 ];
  228. vPoissonConst[ 2*i+1 ] = t;
  229. }
  230. pShaderAPI->SetPixelShaderConstant( 4, vPoissonConst, nNumPoissonSamples / 2 );
  231. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  232. {
  233. DECLARE_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b );
  234. SET_DYNAMIC_PIXEL_SHADER_COMBO( QUALITY, params[QUALITY]->GetIntValue() );
  235. SET_DYNAMIC_PIXEL_SHADER( depth_of_field_ps20b );
  236. }
  237. else
  238. {
  239. Assert( !"No ps_2_b. This shouldn't be happening" );
  240. }
  241. }
  242. Draw();
  243. }
  244. END_SHADER