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.

404 lines
15 KiB

  1. //========= Copyright (c) Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "BaseVSShader.h"
  8. #include "refract_dx9_helper.h"
  9. #include "convar.h"
  10. #include "refract_vs20.inc"
  11. #include "refract_ps20.inc"
  12. #include "refract_ps20b.inc"
  13. #include "cpp_shader_constant_register_map.h"
  14. // NOTE: This has to be the last file included!
  15. #include "tier0/memdbgon.h"
  16. #define MAXBLUR 1
  17. // number of pixels to shrink the viewport by when handling mirroring of texcoords about the viewport edges. This deals with not stepping out of viewport due to blurring, etc.
  18. #define REFRACT_VIEWPORT_SHRINK_PIXELS ( 2 )
  19. // FIXME: doesn't support fresnel!
  20. void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Refract_DX9_Vars_t &info )
  21. {
  22. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  23. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  24. if( !params[info.m_nEnvmapTint]->IsDefined() )
  25. {
  26. params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  27. }
  28. if( !params[info.m_nEnvmapContrast]->IsDefined() )
  29. {
  30. params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f );
  31. }
  32. if( !params[info.m_nEnvmapSaturation]->IsDefined() )
  33. {
  34. params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f );
  35. }
  36. if( !params[info.m_nEnvmapFrame]->IsDefined() )
  37. {
  38. params[info.m_nEnvmapFrame]->SetIntValue( 0 );
  39. }
  40. if( !params[info.m_nFresnelReflection]->IsDefined() )
  41. {
  42. params[info.m_nFresnelReflection]->SetFloatValue( 1.0f );
  43. }
  44. if( !params[info.m_nMasked]->IsDefined() )
  45. {
  46. params[info.m_nMasked]->SetIntValue( 0 );
  47. }
  48. if( !params[info.m_nBlurAmount]->IsDefined() )
  49. {
  50. params[info.m_nBlurAmount]->SetIntValue( 0 );
  51. }
  52. if( !params[info.m_nFadeOutOnSilhouette]->IsDefined() )
  53. {
  54. params[info.m_nFadeOutOnSilhouette]->SetIntValue( 0 );
  55. }
  56. if( !params[info.m_nNoViewportFixup]->IsDefined() )
  57. {
  58. params[info.m_nNoViewportFixup]->SetIntValue( 0 );
  59. }
  60. if( !params[info.m_nMirrorAboutViewportEdges]->IsDefined() )
  61. {
  62. params[info.m_nMirrorAboutViewportEdges]->SetIntValue( 0 );
  63. }
  64. if ( !params[info.m_nMagnifyEnable]->IsDefined() )
  65. {
  66. params[info.m_nMagnifyEnable]->SetIntValue( 0 );
  67. }
  68. if ( !params[info.m_nMagnifyCenter]->IsDefined() )
  69. {
  70. params[info.m_nMagnifyCenter]->SetVecValue( 0, 0, 0, 0 );
  71. }
  72. if ( !params[info.m_nMagnifyScale]->IsDefined() )
  73. {
  74. params[info.m_nMagnifyScale]->SetIntValue( 0 );
  75. }
  76. if ( !params[info.m_nLocalRefract]->IsDefined() )
  77. {
  78. params[info.m_nLocalRefract]->SetIntValue( 0 );
  79. }
  80. if ( !params[info.m_nLocalRefractDepth]->IsDefined() )
  81. {
  82. params[info.m_nLocalRefractDepth]->SetFloatValue( 0.05f );
  83. }
  84. // Local refract doesn't need a copy of the frame buffer and doesn't require the translucent flag
  85. if ( params[info.m_nLocalRefract]->GetIntValue() == 0 )
  86. {
  87. SET_FLAGS( MATERIAL_VAR_TRANSLUCENT );
  88. SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
  89. }
  90. }
  91. void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info )
  92. {
  93. if (params[info.m_nBaseTexture]->IsDefined() )
  94. {
  95. pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  96. }
  97. if (params[info.m_nNormalMap]->IsDefined() )
  98. {
  99. pShader->LoadBumpMap( info.m_nNormalMap, ANISOTROPIC_OVERRIDE );
  100. }
  101. if (params[info.m_nNormalMap2]->IsDefined() )
  102. {
  103. pShader->LoadBumpMap( info.m_nNormalMap2, ANISOTROPIC_OVERRIDE );
  104. }
  105. if( params[info.m_nEnvmap]->IsDefined() )
  106. {
  107. pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  108. }
  109. if( params[info.m_nRefractTintTexture]->IsDefined() )
  110. {
  111. pShader->LoadTexture( info.m_nRefractTintTexture, TEXTUREFLAGS_SRGB );
  112. }
  113. }
  114. void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
  115. IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression )
  116. {
  117. bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL );
  118. bool bHasEnvmap = params[info.m_nEnvmap]->IsTexture();
  119. bool bRefractTintTexture = params[info.m_nRefractTintTexture]->IsTexture();
  120. bool bFadeOutOnSilhouette = params[info.m_nFadeOutOnSilhouette]->GetIntValue() != 0;
  121. int blurAmount = params[info.m_nBlurAmount]->GetIntValue();
  122. bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0);
  123. bool bSecondaryNormal = ( ( info.m_nNormalMap2 != -1 ) && ( params[info.m_nNormalMap2]->IsTexture() ) );
  124. bool bColorModulate = ( ( info.m_nVertexColorModulate != -1 ) && ( params[info.m_nVertexColorModulate]->GetIntValue() ) );
  125. bool bWriteZ = params[info.m_nNoWriteZ]->GetIntValue() == 0;
  126. bool bMirrorAboutViewportEdges = IsX360() && ( info.m_nMirrorAboutViewportEdges != -1 ) && ( params[info.m_nMirrorAboutViewportEdges]->GetIntValue() != 0 );
  127. bool bUseMagnification = params[info.m_nMagnifyEnable]->GetIntValue() != 0;
  128. if( blurAmount < 0 )
  129. {
  130. blurAmount = 0;
  131. }
  132. else if( blurAmount > MAXBLUR )
  133. {
  134. blurAmount = MAXBLUR;
  135. }
  136. BlendType_t nBlendType = pShader->EvaluateBlendRequirements( BASETEXTURE, true );
  137. bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use
  138. bFullyOpaque &= !bMasked;
  139. bool bTranslucentNormal = pShader->TextureIsTranslucent( info.m_nNormalMap, false );
  140. bFullyOpaque &= (! bTranslucentNormal );
  141. SHADOW_STATE
  142. {
  143. pShader->SetInitialShadowState( );
  144. pShaderShadow->EnableDepthWrites( bWriteZ );
  145. // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState
  146. pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
  147. // If envmap is not specified, the alpha channel is the translucency
  148. // (If envmap *is* specified, alpha channel is the reflection amount)
  149. if ( params[info.m_nNormalMap]->IsTexture() && !bHasEnvmap )
  150. {
  151. pShader->SetDefaultBlendingShadowState( info.m_nNormalMap, false );
  152. }
  153. // source render target that contains the image that we are warping.
  154. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  155. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, !IsX360() );
  156. // normal map
  157. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  158. if ( bSecondaryNormal )
  159. {
  160. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  161. }
  162. if( bHasEnvmap )
  163. {
  164. // envmap
  165. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
  166. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true );
  167. }
  168. if( bRefractTintTexture )
  169. {
  170. // refract tint texture
  171. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
  172. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true );
  173. }
  174. // Sampler for nvidia's stereo hackery
  175. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
  176. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false );
  177. pShaderShadow->EnableSRGBWrite( true );
  178. unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
  179. int userDataSize = 0;
  180. int nTexCoordCount = 1;
  181. if( bIsModel )
  182. {
  183. userDataSize = 4;
  184. }
  185. else
  186. {
  187. flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
  188. }
  189. if ( bColorModulate )
  190. {
  191. flags |= VERTEX_COLOR;
  192. }
  193. // This shader supports compressed vertices, so OR in that flag:
  194. flags |= VERTEX_FORMAT_COMPRESSED;
  195. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
  196. DECLARE_STATIC_VERTEX_SHADER( refract_vs20 );
  197. SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel );
  198. SET_STATIC_VERTEX_SHADER_COMBO( COLORMODULATE, bColorModulate );
  199. SET_STATIC_VERTEX_SHADER( refract_vs20 );
  200. // We have to do this in the shader on R500 or Leopard
  201. bool bShaderSRGBConvert = IsOSX() && ( g_pHardwareConfig->FakeSRGBWrite() || !g_pHardwareConfig->CanDoSRGBReadFromRTs() );
  202. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send OpenGL down the ps2b path
  203. {
  204. DECLARE_STATIC_PIXEL_SHADER( refract_ps20b );
  205. SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount );
  206. SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette );
  207. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  208. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture );
  209. SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked );
  210. SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate );
  211. SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal );
  212. SET_STATIC_PIXEL_SHADER_COMBO( MIRRORABOUTVIEWPORTEDGES, bMirrorAboutViewportEdges );
  213. SET_STATIC_PIXEL_SHADER_COMBO( MAGNIFY, bUseMagnification );
  214. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSRGBConvert );
  215. SET_STATIC_PIXEL_SHADER_COMBO( LOCALREFRACT, ( params[info.m_nLocalRefract]->GetIntValue() != 0 ) );
  216. SET_STATIC_PIXEL_SHADER( refract_ps20b );
  217. }
  218. else
  219. {
  220. DECLARE_STATIC_PIXEL_SHADER( refract_ps20 );
  221. SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount );
  222. SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette );
  223. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  224. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture );
  225. SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked );
  226. SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate );
  227. SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal );
  228. SET_STATIC_PIXEL_SHADER_COMBO( MIRRORABOUTVIEWPORTEDGES, bMirrorAboutViewportEdges );
  229. SET_STATIC_PIXEL_SHADER_COMBO( MAGNIFY, bUseMagnification );
  230. SET_STATIC_PIXEL_SHADER_COMBO( LOCALREFRACT, ( params[info.m_nLocalRefract]->GetIntValue() != 0 ) );
  231. SET_STATIC_PIXEL_SHADER( refract_ps20 );
  232. }
  233. pShader->DefaultFog();
  234. if( bMasked )
  235. {
  236. pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA );
  237. }
  238. pShaderShadow->EnableAlphaWrites( bFullyOpaque );
  239. }
  240. DYNAMIC_STATE
  241. {
  242. pShaderAPI->SetDefaultState();
  243. if ( params[info.m_nBaseTexture]->IsTexture() )
  244. {
  245. pShader->BindTexture( SHADER_SAMPLER2, IsX360() ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, info.m_nBaseTexture, info.m_nFrame );
  246. // Set refract texture dimensions
  247. ITexture *pTarget = params[info.m_nBaseTexture]->GetTextureValue();
  248. int nWidth = pTarget->GetActualWidth();
  249. int nHeight = pTarget->GetActualHeight();
  250. float c7[4] = { nHeight / nWidth, 1.0f, params[info.m_nLocalRefractDepth]->GetFloatValue(), 0.0f };
  251. pShaderAPI->SetPixelShaderConstant( 7, c7, 1 );
  252. }
  253. else
  254. {
  255. pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, IsX360() ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 );
  256. // Set refract texture dimensions
  257. int nWidth = 0;
  258. int nHeight = 0;
  259. pShaderAPI->GetStandardTextureDimensions( &nWidth, &nHeight, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 );
  260. float c7[4] = { nHeight / nWidth, 1.0f, params[info.m_nLocalRefractDepth]->GetFloatValue(), 0.0f };
  261. pShaderAPI->SetPixelShaderConstant( 7, c7, 1 );
  262. }
  263. pShader->BindTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, info.m_nNormalMap, info.m_nBumpFrame );
  264. if ( bSecondaryNormal )
  265. {
  266. pShader->BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, info.m_nNormalMap2, info.m_nBumpFrame2 );
  267. }
  268. if( bHasEnvmap )
  269. {
  270. pShader->BindTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_SRGBREAD, info.m_nEnvmap, info.m_nEnvmapFrame );
  271. }
  272. if( bRefractTintTexture )
  273. {
  274. pShader->BindTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_SRGBREAD, info.m_nRefractTintTexture, info.m_nRefractTintTextureFrame );
  275. }
  276. bool bNvidiaStereoActiveThisFrame = pShaderAPI->IsStereoActiveThisFrame();
  277. if ( bNvidiaStereoActiveThisFrame )
  278. {
  279. pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, TEXTURE_STEREO_PARAM_MAP );
  280. }
  281. DECLARE_DYNAMIC_VERTEX_SHADER( refract_vs20 );
  282. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  283. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  284. SET_DYNAMIC_VERTEX_SHADER( refract_vs20 );
  285. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send OpenGL down the ps2b path
  286. {
  287. DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20b );
  288. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  289. SET_DYNAMIC_PIXEL_SHADER_COMBO( D_NVIDIA_STEREO, bNvidiaStereoActiveThisFrame );
  290. SET_DYNAMIC_PIXEL_SHADER( refract_ps20b );
  291. }
  292. else
  293. {
  294. DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20 );
  295. SET_DYNAMIC_PIXEL_SHADER( refract_ps20 );
  296. }
  297. pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform ); // 1 & 2
  298. pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBumpTransform2 ); // 3 & 4
  299. pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
  300. float vEyePos_SpecExponent[4];
  301. pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
  302. vEyePos_SpecExponent[3] = 0.0f;
  303. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
  304. pShader->SetPixelShaderConstantGammaToLinear( 0, info.m_nEnvmapTint );
  305. pShader->SetPixelShaderConstantGammaToLinear( 1, info.m_nRefractTint );
  306. pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast );
  307. pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation );
  308. float c5[4] = { params[info.m_nRefractAmount]->GetFloatValue(),
  309. params[info.m_nRefractAmount]->GetFloatValue(), 0.0f, 0.0f };
  310. // Time % 1000
  311. c5[3] = pShaderAPI->CurrentTime();
  312. c5[3] -= (float)( (int)( c5[3] / 1000.0f ) ) * 1000.0f;
  313. pShaderAPI->SetPixelShaderConstant( 5, c5, 1 );
  314. float c6[4];
  315. params[info.m_nMagnifyCenter]->GetVecValue( c6, 2 );
  316. c6[2] = params[info.m_nMagnifyScale]->GetFloatValue();
  317. if ( c6[2] != 0 )
  318. {
  319. c6[2] = 1.0f / c6[2]; // Shader uses the inverse scale value
  320. }
  321. pShaderAPI->SetPixelShaderConstant( 6, c6, 1 );
  322. float cVs3[4] = { c5[3], 0.0f, 0.0f, 0.0f };
  323. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, cVs3, 1 );
  324. // Get viewport and render target dimensions and set shader constant to do a 2D mad and also deal with mirror on viewport edges.
  325. int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
  326. pShaderAPI->GetCurrentViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );
  327. int nRtWidth, nRtHeight;
  328. pShaderAPI->GetCurrentRenderTargetDimensions( nRtWidth, nRtHeight );
  329. float vViewportMad[4] = { 1.0f, 1.0f, 0.0f, 0.0f };
  330. if ( params[ info.m_nNoViewportFixup ]->GetIntValue() == 0 )
  331. {
  332. vViewportMad[0] = ( float )nViewportWidth / ( float )nRtWidth;
  333. vViewportMad[1] = ( float )nViewportHeight / ( float )nRtHeight;
  334. vViewportMad[2] = ( float )nViewportX / ( float )nRtWidth;
  335. vViewportMad[3] = ( float )nViewportY / ( float )nRtHeight;
  336. }
  337. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vViewportMad, 1 );
  338. if ( bMirrorAboutViewportEdges )
  339. {
  340. // Need the extents that we are allowed to sample from the refract texture to clamp by for splitscreen, etc.
  341. float vNormalizedViewportMinXYMaxWZ[4];
  342. vNormalizedViewportMinXYMaxWZ[0] = ( float )( nViewportX + REFRACT_VIEWPORT_SHRINK_PIXELS ) / ( float )nRtWidth;
  343. vNormalizedViewportMinXYMaxWZ[1] = ( float )( nViewportY + REFRACT_VIEWPORT_SHRINK_PIXELS ) / ( float )nRtHeight;
  344. vNormalizedViewportMinXYMaxWZ[3] = ( float )( nViewportX + nViewportWidth - REFRACT_VIEWPORT_SHRINK_PIXELS - 1 ) / ( float )nRtWidth;
  345. vNormalizedViewportMinXYMaxWZ[2] = ( float )( nViewportY + nViewportHeight - REFRACT_VIEWPORT_SHRINK_PIXELS - 1 ) / ( float )nRtHeight;
  346. pShaderAPI->SetPixelShaderConstant( 4, vNormalizedViewportMinXYMaxWZ, 1 );
  347. }
  348. }
  349. pShader->Draw();
  350. }