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.

176 lines
6.4 KiB

  1. //===== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "BaseVSShader.h"
  8. #include "sfm_ambientocclusion_vs30.inc"
  9. #include "sfm_ambientocclusion_ps30.inc"
  10. // NOTE: This has to be the last file included!
  11. #include "tier0/memdbgon.h"
  12. static bool s_bInited = false;
  13. #define NUM_SSAO_SAMPLES 9
  14. static Vector4D s_vSphereSamples[ NUM_SSAO_SAMPLES ];
  15. float RPercent()
  16. {
  17. return float( rand() - (VALVE_RAND_MAX/2) ) / (float)(VALVE_RAND_MAX/2);
  18. }
  19. float RPercentABS()
  20. {
  21. return float( rand() ) / (float)(VALVE_RAND_MAX);
  22. }
  23. BEGIN_VS_SHADER_FLAGS( sfm_ambientocclusion_shader, "Help for SFM ambient occlusion pass", SHADER_NOT_EDITABLE )
  24. BEGIN_SHADER_PARAMS
  25. SHADER_PARAM( FRONTNDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" )
  26. SHADER_PARAM( JITTERSEED, SHADER_PARAM_TYPE_VEC4, "", "" )
  27. SHADER_PARAM( EYEPOSZNEAR, SHADER_PARAM_TYPE_VEC4, "", "" )
  28. SHADER_PARAM( EYEDIR, SHADER_PARAM_TYPE_VEC4, "", "" ) // Eye direction over zFar
  29. SHADER_PARAM( FARZ, SHADER_PARAM_TYPE_FLOAT, "", "" )
  30. SHADER_PARAM( BIAS, SHADER_PARAM_TYPE_FLOAT, "", "" )
  31. SHADER_PARAM( STRENGTH, SHADER_PARAM_TYPE_FLOAT, "", "" )
  32. SHADER_PARAM( RADIUS, SHADER_PARAM_TYPE_FLOAT, "", "" )
  33. SHADER_PARAM( VIEWPROJ, SHADER_PARAM_TYPE_MATRIX, "", "" )
  34. SHADER_PARAM( AOMODE, SHADER_PARAM_TYPE_INTEGER, "", "" )
  35. END_SHADER_PARAMS
  36. SHADER_INIT
  37. {
  38. LoadTexture( FRONTNDTEXTURE );
  39. // LoadTexture( BACKNDTEXTURE );
  40. }
  41. SHADER_FALLBACK
  42. {
  43. return 0;
  44. }
  45. SHADER_DRAW
  46. {
  47. SHADOW_STATE
  48. {
  49. pShaderShadow->EnableDepthWrites( false );
  50. pShaderShadow->EnableDepthTest( false );
  51. pShaderShadow->EnableAlphaWrites( false );
  52. pShaderShadow->EnableBlending( false );
  53. pShaderShadow->EnableCulling( false );
  54. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Front ND buffer
  55. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Noise map
  56. int fmt = VERTEX_POSITION;
  57. int nTexCoordDimensions[3] = { 2, 3, 3 };
  58. // Two texture coordinates (first for 2D screen space, second for 3D world space far plane)
  59. pShaderShadow->VertexShaderVertexFormat( fmt, 3, nTexCoordDimensions, 0 );
  60. DECLARE_STATIC_VERTEX_SHADER( sfm_ambientocclusion_vs30 );
  61. SET_STATIC_VERTEX_SHADER( sfm_ambientocclusion_vs30 );
  62. DECLARE_STATIC_PIXEL_SHADER( sfm_ambientocclusion_ps30 );
  63. SET_STATIC_PIXEL_SHADER( sfm_ambientocclusion_ps30 );
  64. }
  65. DYNAMIC_STATE
  66. {
  67. // TODO: we could easily just roll these into the shader itself
  68. if ( !s_bInited )
  69. {
  70. int nSqrtNumSamples = (int)sqrtf( (float)NUM_SSAO_SAMPLES );
  71. int nNumSamples = nSqrtNumSamples * nSqrtNumSamples;
  72. Vector *pvDirections = new Vector[nNumSamples];
  73. Assert( pvDirections );
  74. int i = 0;
  75. float oneoverN = 1.0f / (float)nSqrtNumSamples;
  76. // Fill an N*N*2 array with uniformly distributed
  77. // samples across the sphere using jittered stratification
  78. for ( int a=0; a < nSqrtNumSamples; a++ )
  79. {
  80. for ( int b=0; b < nSqrtNumSamples; b++ )
  81. {
  82. // Generate unbiased distribution of spherical coords
  83. float x = ( a + fabs( RPercent() ) ) * oneoverN; // do not reuse results
  84. float y = ( b + fabs( RPercent() ) ) * oneoverN; // each sample must be random
  85. float theta = 2.0f * acosf( sqrtf(1.0f - x) );
  86. float phi = 2.0f * M_PI * y;
  87. // Convert spherical coords to unit vector
  88. Vector vec( sinf(theta)*cosf(phi), sinf(theta)*sinf(phi), cosf(theta) );
  89. pvDirections[i++] = vec;
  90. }
  91. }
  92. for ( int s=0; s<NUM_SSAO_SAMPLES; s++ )
  93. {
  94. Vector vSample = pvDirections[s] * RPercentABS();
  95. s_vSphereSamples[s].Init( vSample.x, vSample.y, vSample.z, 1 );
  96. }
  97. s_bInited = true;
  98. }
  99. float flFar = params[FARZ]->GetFloatValue();
  100. float flBias = params[BIAS]->GetFloatValue();//0.005f;
  101. float flStrenth = params[STRENGTH]->GetFloatValue();//2.0f;
  102. float flSampleRadius = params[RADIUS]->GetFloatValue();//16.0f;
  103. float vSampleRadiusNBias[4] = { flSampleRadius, flFar / ( flSampleRadius * flStrenth ), flFar, flBias * flFar };
  104. pShaderAPI->SetPixelShaderConstant( 10, vSampleRadiusNBias, 1 );
  105. pShaderAPI->SetPixelShaderConstant( 11, (float *) &s_vSphereSamples[0], NUM_SSAO_SAMPLES );
  106. // Set c5...c8 to contain ViewProj matrix
  107. const VMatrix &mViewProj = params[VIEWPROJ]->GetMatrixValue();
  108. Vector4D vMatrixRows[4];
  109. vMatrixRows[0].Init( mViewProj[0][0], mViewProj[1][0], mViewProj[2][0], mViewProj[3][0] );
  110. vMatrixRows[1].Init( mViewProj[0][1], mViewProj[1][1], mViewProj[2][1], mViewProj[3][1] );
  111. vMatrixRows[2].Init( mViewProj[0][2], mViewProj[1][2], mViewProj[2][2], mViewProj[3][2] );
  112. vMatrixRows[3].Init( mViewProj[0][3], mViewProj[1][3], mViewProj[2][3], mViewProj[3][3] );
  113. pShaderAPI->SetPixelShaderConstant( 5, vMatrixRows[0].Base(), 4 );
  114. int nScreenWidth, nScreenHeight;
  115. pShaderAPI->GetCurrentRenderTargetDimensions( nScreenWidth, nScreenHeight );
  116. float vScreenSize[4] = { 1.0f / (float) nScreenWidth, 1.0f / (float) nScreenHeight, 0.0f, 0.0f };
  117. pShaderAPI->SetPixelShaderConstant( 2, vScreenSize, 1 );
  118. float vEyePosZNear[4];
  119. params[EYEPOSZNEAR]->GetVecValue( vEyePosZNear, 4 );
  120. pShaderAPI->SetPixelShaderConstant( 3, vEyePosZNear, 1 );
  121. float vEyeDirection[4];
  122. params[EYEDIR]->GetVecValue( vEyeDirection, 4 ); // This is eye direction over zFar
  123. pShaderAPI->SetPixelShaderConstant( 4, vEyeDirection, 1 );
  124. BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_NONE, FRONTNDTEXTURE, -1 );
  125. pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, TEXTURE_SSAO_NOISE_2D );
  126. int nTexWidth, nTexHeight;
  127. pShaderAPI->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SSAO_NOISE_2D );
  128. float vRandSampleScale[4] = { 1.0f / (float)nTexWidth, 1.0f / (float)nTexHeight, 0.5f + ( 0.5f / (float)nScreenWidth ), 0.5f + ( 0.5f / (float)nScreenHeight ) };
  129. pShaderAPI->SetPixelShaderConstant( 9, vRandSampleScale, 1 );
  130. float vNoiseOffset[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  131. HashShadow2DJitter( params[JITTERSEED]->GetFloatValue(), vNoiseOffset, vNoiseOffset+1 );
  132. pShaderAPI->SetPixelShaderConstant( 1, vNoiseOffset, 1 );
  133. DECLARE_DYNAMIC_VERTEX_SHADER( sfm_ambientocclusion_vs30 );
  134. SET_DYNAMIC_VERTEX_SHADER( sfm_ambientocclusion_vs30 );
  135. DECLARE_DYNAMIC_PIXEL_SHADER( sfm_ambientocclusion_ps30 );
  136. SET_DYNAMIC_PIXEL_SHADER_COMBO( AO_MODE, params[AOMODE]->GetIntValue() );
  137. SET_DYNAMIC_PIXEL_SHADER( sfm_ambientocclusion_ps30 );
  138. }
  139. Draw();
  140. }
  141. END_SHADER