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.

412 lines
16 KiB

  1. //===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. // This is what all vs/ps (dx8+) shaders inherit from.
  7. //===========================================================================//
  8. #ifndef BASEVSSHADER_H
  9. #define BASEVSSHADER_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "cpp_shader_constant_register_map.h"
  14. #include "shaderlib/cshader.h"
  15. #include "shaderlib/BaseShader.h"
  16. #include "shaderapifast.h"
  17. #include "convar.h"
  18. #include <renderparm.h>
  19. // Texture combining modes for combining base and detail/basetexture2
  20. // Matches what's in common_ps_fxc.h
  21. #define DETAIL_BLEND_MODE_RGB_EQUALS_BASE_x_DETAILx2 0 // Original mode (Mod2x)
  22. #define DETAIL_BLEND_MODE_RGB_ADDITIVE 1 // Base.rgb+detail.rgb*fblend
  23. #define DETAIL_BLEND_MODE_DETAIL_OVER_BASE 2
  24. #define DETAIL_BLEND_MODE_FADE 3 // Straight fade between base and detail.
  25. #define DETAIL_BLEND_MODE_BASE_OVER_DETAIL 4 // Use base alpha for blend over detail
  26. #define DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM 5 // Add detail color post lighting
  27. #define DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6
  28. #define DETAIL_BLEND_MODE_MOD2X_SELECT_TWO_PATTERNS 7 // Use alpha channel of base to select between mod2x channels in r+a of detail
  29. #define DETAIL_BLEND_MODE_MULTIPLY 8
  30. #define DETAIL_BLEND_MODE_MASK_BASE_BY_DETAIL_ALPHA 9 // Use alpha channel of detail to mask base
  31. #define DETAIL_BLEND_MODE_SSBUMP_BUMP 10 // Use detail to modulate lighting as an ssbump
  32. #define DETAIL_BLEND_MODE_SSBUMP_NOBUMP 11 // Detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11
  33. #define DETAIL_BLEND_MODE_NONE 12 // There is no detail texture
  34. // Texture combining modes for combining base and decal texture
  35. #define DECAL_BLEND_MODE_DECAL_ALPHA 0 // Original mode ( = decalRGB*decalA + baseRGB*(1-decalA))
  36. #define DECAL_BLEND_MODE_RGB_MOD1X 1 // baseRGB * decalRGB
  37. #define DECAL_BLEND_MODE_NONE 2 // There is no decal texture
  38. // We force aniso on certain textures for the consoles only
  39. #if defined( _GAMECONSOLE )
  40. #define ANISOTROPIC_OVERRIDE TEXTUREFLAGS_ANISOTROPIC
  41. #else
  42. #define ANISOTROPIC_OVERRIDE 0
  43. #endif
  44. //-----------------------------------------------------------------------------
  45. // Helper macro for vertex shaders
  46. //-----------------------------------------------------------------------------
  47. #define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags )
  48. #define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 )
  49. // useful parameter initialization macro
  50. #define INIT_FLOAT_PARM( parm, value ) \
  51. if ( !params[(parm)]->IsDefined() ) \
  52. { \
  53. params[(parm)]->SetFloatValue( (value) ); \
  54. }
  55. // useful pixel shader declaration macro for ps20/20b c++ code
  56. #define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
  57. if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
  58. { \
  59. DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \
  60. SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \
  61. } \
  62. else \
  63. { \
  64. DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \
  65. SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \
  66. }
  67. #define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
  68. if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
  69. { \
  70. DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
  71. SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
  72. } \
  73. else \
  74. { \
  75. DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
  76. SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Base class for shaders, contains helper methods.
  80. //-----------------------------------------------------------------------------
  81. class CBaseVSShader : public CBaseShader
  82. {
  83. public:
  84. // Loads bump lightmap coordinates into the pixel shader
  85. void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg );
  86. // Loads bump lightmap coordinates into the vertex shader
  87. void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg );
  88. // Pixel and vertex shader constants....
  89. void SetPixelShaderConstant( int pixelReg, int constantVar );
  90. // Pixel and vertex shader constants....
  91. void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar );
  92. // This version will put constantVar into x,y,z, and constantVar2 into the w
  93. void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 );
  94. void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 );
  95. // Helpers for setting constants that need to be converted to linear space (from gamma space).
  96. void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
  97. void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
  98. void SetVertexShaderConstant( int vertexReg, int constantVar );
  99. // set rgb components of constant from a color parm and give an explicit w value
  100. void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue );
  101. // GR - fix for const/lerp issues
  102. void SetPixelShaderConstantFudge( int pixelReg, int constantVar );
  103. // Sets vertex shader texture transforms
  104. void SetVertexShaderTextureTranslation( int vertexReg, int translationVar );
  105. void SetVertexShaderTextureScale( int vertexReg, int scaleVar );
  106. void SetVertexShaderTextureTransform( int vertexReg, int transformVar );
  107. void SetVertexShaderTextureScaledTransform( int vertexReg,
  108. int transformVar, int scaleVar );
  109. // Set pixel shader texture transforms
  110. void SetPixelShaderTextureTranslation( int pixelReg, int translationVar );
  111. void SetPixelShaderTextureScale( int pixelReg, int scaleVar );
  112. void SetPixelShaderTextureTransform( int pixelReg, int transformVar );
  113. void SetPixelShaderTextureScaledTransform( int pixelReg,
  114. int transformVar, int scaleVar );
  115. // Moves a matrix into vertex shader constants
  116. void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar );
  117. void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar );
  118. // Loads the view matrix into vertex shader constants
  119. void LoadViewMatrixIntoVertexShaderConstant( int vertexReg );
  120. // Loads the projection matrix into vertex shader constants
  121. void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg );
  122. // Loads the model->view matrix into vertex shader constants
  123. void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg );
  124. // Helpers for dealing with envmaptint
  125. void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false );
  126. // Helper methods for pixel shader overbrighting
  127. void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo );
  128. // Sets up hw morphing state for the vertex shader
  129. void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler );
  130. BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 );
  131. // Helper for setting up flashlight constants
  132. void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms );
  133. struct DrawFlashlight_dx90_Vars_t
  134. {
  135. DrawFlashlight_dx90_Vars_t()
  136. {
  137. // set all ints to -1
  138. memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) );
  139. // set all bools to a default value.
  140. m_bBump = false;
  141. m_bLightmappedGeneric = false;
  142. m_bWorldVertexTransition = false;
  143. m_bTeeth = false;
  144. m_bSSBump = false;
  145. m_fSeamlessScale = 0.0;
  146. }
  147. bool m_bBump;
  148. bool m_bLightmappedGeneric;
  149. bool m_bWorldVertexTransition;
  150. bool m_bTeeth;
  151. int m_nBumpmapVar;
  152. int m_nBumpmapFrame;
  153. int m_nBumpTransform;
  154. int m_nFlashlightTextureVar;
  155. int m_nFlashlightTextureFrameVar;
  156. int m_nBaseTexture2Var;
  157. int m_nBaseTexture2FrameVar;
  158. int m_nBumpmapVar2;
  159. int m_nBumpmapFrame2;
  160. int m_nBumpTransform2;
  161. int m_nDetailVar;
  162. int m_nDetailScale;
  163. int m_nDetailTextureCombineMode;
  164. int m_nDetailTextureBlendFactor;
  165. int m_nDetailTint;
  166. int m_nDetailVar2;
  167. int m_nDetailScale2;
  168. int m_nDetailTextureBlendFactor2;
  169. int m_nDetailTint2;
  170. int m_nTeethForwardVar;
  171. int m_nTeethIllumFactorVar;
  172. int m_nAlphaTestReference;
  173. bool m_bSSBump;
  174. float m_fSeamlessScale; // 0.0 = not seamless
  175. int m_nLayerTint1;
  176. int m_nLayerTint2;
  177. };
  178. void DrawFlashlight_dx90( IMaterialVar** params,
  179. IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars );
  180. void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV );
  181. //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth.
  182. //This pass fills in the areas that passed the alpha test with depth in dest alpha
  183. //by writing only equal depth pixels and only if we should be writing depth to dest alpha
  184. void DrawEqualDepthToDestAlpha( void );
  185. private:
  186. // Converts a color + alpha into a vector4
  187. void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color );
  188. };
  189. FORCEINLINE bool IsSRGBDetailTexture( int nMode )
  190. {
  191. return ( nMode == DETAIL_BLEND_MODE_DETAIL_OVER_BASE ) ||
  192. ( nMode == DETAIL_BLEND_MODE_FADE ) ||
  193. ( nMode == DETAIL_BLEND_MODE_BASE_OVER_DETAIL );
  194. }
  195. FORCEINLINE bool IsSRGBDecalTexture( int nMode )
  196. {
  197. return (nMode == DECAL_BLEND_MODE_DECAL_ALPHA);
  198. }
  199. FORCEINLINE char * GetFlashlightTextureFilename()
  200. {
  201. //if ( !IsX360() && ( g_pHardwareConfig->SupportsBorderColor() ) )
  202. //{
  203. // return "effects/flashlight001_border";
  204. //}
  205. //else
  206. {
  207. return "effects/flashlight001";
  208. }
  209. }
  210. extern ConVar r_flashlightbrightness;
  211. FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, bool bSinglePassFlashlight, int nPSRegister=28, bool bFlashlightNoLambert=false )
  212. {
  213. // Old code
  214. //float flToneMapScale = ( ShaderApiFast( pShaderAPI )->GetToneMappingScaleLinear() ).x;
  215. //float flFlashlightScale = 1.0f / flToneMapScale;
  216. // Fix to old code to keep flashlight from ever getting brighter than 1.0
  217. //float flToneMapScale = ( ShaderApiFast( pShaderAPI )->GetToneMappingScaleLinear() ).x;
  218. //if ( flToneMapScale < 1.0f )
  219. // flToneMapScale = 1.0f;
  220. //float flFlashlightScale = 1.0f / flToneMapScale;
  221. float flFlashlightScale = r_flashlightbrightness.GetFloat();
  222. if ( !g_pHardwareConfig->GetHDREnabled() )
  223. {
  224. // Non-HDR path requires 2.0 flashlight
  225. flFlashlightScale = 2.0f;
  226. }
  227. // DX10 hardware and single pass flashlight require a hack scalar since the flashlight is added in linear space
  228. if ( ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) || ( bSinglePassFlashlight ) )
  229. {
  230. flFlashlightScale *= 2.5f; // Magic number that works well on the 360 and NVIDIA 8800
  231. }
  232. flFlashlightScale *= state.m_fBrightnessScale;
  233. // Generate pixel shader constant
  234. float const *pFlashlightColor = state.m_Color;
  235. float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] };
  236. vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term
  237. // Red flashlight for testing
  238. //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f;
  239. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst );
  240. }
  241. FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state )
  242. {
  243. // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light
  244. if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
  245. return state.m_flShadowAtten * 0.1f; // magic number
  246. return state.m_flShadowAtten;
  247. }
  248. FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state )
  249. {
  250. // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that
  251. return state.m_flShadowFilterSize / 1024.0f;
  252. }
  253. FORCEINLINE void SetupUberlightFromState( IShaderDynamicAPI *pShaderAPI, FlashlightState_t const &state )
  254. {
  255. // Bail if we can't do ps30 or we don't even want an uberlight
  256. if ( !g_pHardwareConfig->HasFastVertexTextures() || !state.m_bUberlight || !pShaderAPI )
  257. return;
  258. UberlightState_t u = state.m_uberlightState;
  259. // Set uberlight shader parameters as function of user controls from UberlightState_t
  260. Vector4D vSmoothEdge0 = Vector4D( 0.0f, u.m_fCutOn - u.m_fNearEdge, u.m_fCutOff, 0.0f );
  261. Vector4D vSmoothEdge1 = Vector4D( 0.0f, u.m_fCutOn, u.m_fCutOff + u.m_fFarEdge, 0.0f );
  262. Vector4D vSmoothOneOverW = Vector4D( 0.0f, 1.0f / u.m_fNearEdge, 1.0f / u.m_fFarEdge, 0.0f );
  263. Vector4D vShearRound = Vector4D( u.m_fShearx, u.m_fSheary, 2.0f / u.m_fRoundness, -u.m_fRoundness / 2.0f );
  264. Vector4D vaAbB = Vector4D( u.m_fWidth, u.m_fWidth + u.m_fWedge, u.m_fHeight, u.m_fHeight + u.m_fHedge );
  265. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_0, vSmoothEdge0.Base(), 1 );
  266. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_1, vSmoothEdge1.Base(), 1 );
  267. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_OOW, vSmoothOneOverW.Base(), 1 );
  268. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_SHEAR_ROUND, vShearRound.Base(), 1 );
  269. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_AABB, vaAbB.Base(), 1 );
  270. QAngle angles;
  271. QuaternionAngles( state.m_quatOrientation, angles );
  272. // World to Light's View matrix
  273. matrix3x4_t viewMatrix, viewMatrixInverse;
  274. AngleMatrix( angles, state.m_vecLightOrigin, viewMatrixInverse );
  275. MatrixInvert( viewMatrixInverse, viewMatrix );
  276. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_UBERLIGHT_WORLD_TO_LIGHT, viewMatrix.Base(), 4 );
  277. }
  278. // convenient material variable access functions for helpers to use.
  279. FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params )
  280. {
  281. return ( nVar != -1 ) && ( params[nVar]->IsTexture() );
  282. }
  283. FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params )
  284. {
  285. return ( nVar != -1 ) && ( params[nVar]->GetIntValue() );
  286. }
  287. FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 )
  288. {
  289. return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue;
  290. }
  291. FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 )
  292. {
  293. return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue;
  294. }
  295. FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue )
  296. {
  297. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  298. {
  299. params[nIndex]->SetFloatValue( flValue );
  300. }
  301. }
  302. FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue )
  303. {
  304. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  305. {
  306. params[nIndex]->SetIntValue( nValue );
  307. }
  308. }
  309. FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y )
  310. {
  311. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  312. {
  313. params[nIndex]->SetVecValue( x, y );
  314. }
  315. }
  316. FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z )
  317. {
  318. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  319. {
  320. params[nIndex]->SetVecValue( x, y, z );
  321. }
  322. }
  323. FORCEINLINE void InitVecParam( int nIndex, IMaterialVar **params, float x, float y, float z, float w )
  324. {
  325. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  326. {
  327. params[nIndex]->SetVecValue( x, y, z, w );
  328. }
  329. }
  330. // Did we launch with -tools
  331. bool ToolsEnabled();
  332. class ConVar;
  333. #ifdef _DEBUG
  334. extern ConVar mat_envmaptintoverride;
  335. extern ConVar mat_envmaptintscale;
  336. #endif
  337. #endif // BASEVSSHADER_H