Team Fortress 2 Source Code as on 22/4/2020
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.

440 lines
17 KiB

  1. //========= Copyright 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 "shaderlib/cshader.h"
  14. #include "shaderlib/BaseShader.h"
  15. #include "convar.h"
  16. #include <renderparm.h>
  17. #ifdef _X360
  18. #define SUPPORT_DX8 0
  19. #define SUPPORT_DX7 0
  20. #else
  21. #define SUPPORT_DX8 1
  22. #define SUPPORT_DX7 1
  23. #endif
  24. //-----------------------------------------------------------------------------
  25. // Helper macro for vertex shaders
  26. //-----------------------------------------------------------------------------
  27. #define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags )
  28. #define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 )
  29. // useful parameter initialization macro
  30. #define INIT_FLOAT_PARM( parm, value ) \
  31. if ( !params[(parm)]->IsDefined() ) \
  32. { \
  33. params[(parm)]->SetFloatValue( (value) ); \
  34. }
  35. // useful pixel shader declaration macro for ps20/20b c++ code
  36. #define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
  37. if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
  38. { \
  39. DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \
  40. SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \
  41. } \
  42. else \
  43. { \
  44. DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \
  45. SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \
  46. }
  47. #define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
  48. if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
  49. { \
  50. DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
  51. SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
  52. } \
  53. else \
  54. { \
  55. DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
  56. SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Base class for shaders, contains helper methods.
  60. //-----------------------------------------------------------------------------
  61. class CBaseVSShader : public CBaseShader
  62. {
  63. public:
  64. // Loads bump lightmap coordinates into the pixel shader
  65. void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg );
  66. // Loads bump lightmap coordinates into the vertex shader
  67. void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg );
  68. // Pixel and vertex shader constants....
  69. void SetPixelShaderConstant( int pixelReg, int constantVar );
  70. // Pixel and vertex shader constants....
  71. void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar );
  72. // This version will put constantVar into x,y,z, and constantVar2 into the w
  73. void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 );
  74. void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 );
  75. // Helpers for setting constants that need to be converted to linear space (from gamma space).
  76. void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
  77. void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
  78. void SetVertexShaderConstant( int vertexReg, int constantVar );
  79. // set rgb components of constant from a color parm and give an explicit w value
  80. void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue );
  81. // GR - fix for const/lerp issues
  82. void SetPixelShaderConstantFudge( int pixelReg, int constantVar );
  83. // Sets light direction for pixel shaders.
  84. void SetPixelShaderLightColors( int pixelReg );
  85. // Sets vertex shader texture transforms
  86. void SetVertexShaderTextureTranslation( int vertexReg, int translationVar );
  87. void SetVertexShaderTextureScale( int vertexReg, int scaleVar );
  88. void SetVertexShaderTextureTransform( int vertexReg, int transformVar );
  89. void SetVertexShaderTextureScaledTransform( int vertexReg,
  90. int transformVar, int scaleVar );
  91. // Set pixel shader texture transforms
  92. void SetPixelShaderTextureTranslation( int pixelReg, int translationVar );
  93. void SetPixelShaderTextureScale( int pixelReg, int scaleVar );
  94. void SetPixelShaderTextureTransform( int pixelReg, int transformVar );
  95. void SetPixelShaderTextureScaledTransform( int pixelReg,
  96. int transformVar, int scaleVar );
  97. // Moves a matrix into vertex shader constants
  98. void SetVertexShaderMatrix2x4( int vertexReg, int matrixVar );
  99. void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar );
  100. void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar );
  101. // Loads the view matrix into vertex shader constants
  102. void LoadViewMatrixIntoVertexShaderConstant( int vertexReg );
  103. // Loads the projection matrix into vertex shader constants
  104. void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg );
  105. // Loads the model->view matrix into vertex shader constants
  106. void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg );
  107. // Loads a scale/offset version of the viewport transform into the specified constant.
  108. void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg );
  109. // Sets up ambient light cube...
  110. void SetAmbientCubeDynamicStateVertexShader( );
  111. float GetAmbientLightCubeLuminance( );
  112. // Helpers for dealing with envmaptint
  113. void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false );
  114. // Helper methods for pixel shader overbrighting
  115. void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo );
  116. // Helper for dealing with modulation
  117. void SetModulationVertexShaderDynamicState();
  118. void SetModulationPixelShaderDynamicState( int modulationVar );
  119. void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar );
  120. void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale );
  121. // Sets a color + alpha into shader constants
  122. void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar );
  123. void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar );
  124. #ifndef GAME_SHADER_DLL
  125. //
  126. // Standard shader passes!
  127. //
  128. void InitParamsUnlitGeneric_DX8(
  129. int baseTextureVar,
  130. int detailScaleVar,
  131. int envmapOptionalVar,
  132. int envmapVar,
  133. int envmapTintVar,
  134. int envmapMaskScaleVar,
  135. int nDetailBlendMode );
  136. void InitUnlitGeneric_DX8(
  137. int baseTextureVar,
  138. int detailVar,
  139. int envmapVar,
  140. int envmapMaskVar );
  141. // Dx8 Unlit Generic pass
  142. void VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar,
  143. int baseTextureTransformVar,
  144. int detailVar, int detailTransform, bool bDetailTransformIsScale,
  145. int envmapVar, int envMapFrameVar, int envmapMaskVar,
  146. int envmapMaskFrameVar, int envmapMaskScaleVar, int envmapTintVar,
  147. int alphaTestReferenceVar,
  148. int nDetailBlendModeVar,
  149. int nOutlineVar,
  150. int nOutlineColorVar,
  151. int nOutlineStartVar,
  152. int nOutlineEndVar,
  153. int nSeparateDetailUVsVar
  154. );
  155. // Helpers for drawing world bump mapped stuff.
  156. void DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar,
  157. int envMapVar, int envMapVarFrame,
  158. int envMapTintVar, int alphaVar,
  159. int envMapContrastVar, int envMapSaturationVar,
  160. int bumpTransformVar,
  161. bool bBlendSpecular, bool bNoWriteZ = false );
  162. void DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar,
  163. int bumpFrameVar, int envmapFrameVar,
  164. int envmapTintVar, int alphaVar,
  165. int envmapContrastVar, int envmapSaturationVar,
  166. int bumpTransformVar, int fresnelReflectionVar,
  167. bool bBlend, bool bNoWriteZ = false );
  168. const char *UnlitGeneric_ComputeVertexShaderName( bool bMask,
  169. bool bEnvmap,
  170. bool bBaseTexture,
  171. bool bBaseAlphaEnvmapMask,
  172. bool bDetail,
  173. bool bVertexColor,
  174. bool bEnvmapCameraSpace,
  175. bool bEnvmapSphere );
  176. const char *UnlitGeneric_ComputePixelShaderName( bool bMask,
  177. bool bEnvmap,
  178. bool bBaseTexture,
  179. bool bBaseAlphaEnvmapMask,
  180. bool bDetail,
  181. bool bMultiplyDetail,
  182. bool bMaskBaseByDetailAlpha );
  183. void DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, int frameVar, int colorVar, int alphaVar );
  184. void DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar,
  185. int bumpTransformVar, bool bMultiply, bool bSSBump );
  186. void DrawWorldBumpedSpecularLighting( int envmapMaskVar, int envmapMaskFrame,
  187. int bumpmapVar, int envmapVar,
  188. int bumpFrameVar, int envmapFrameVar,
  189. int envmapTintVar, int alphaVar,
  190. int envmapContrastVar, int envmapSaturationVar,
  191. int bumpTransformVar, int fresnelReflectionVar,
  192. bool bBlend );
  193. void DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar,
  194. int baseTextureFrameVar,
  195. int baseTexture2Var, int baseTextureTransform2Var,
  196. int baseTextureFrame2Var, int colorVar, int alphaVar );
  197. void DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar,
  198. int bumpTransformVar, int baseTextureVar, int baseTextureTransformVar, int frameVar );
  199. void DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, int bumpTransformVar,
  200. int baseTextureVar, int baseTextureTransformVar, int baseTextureFrameVar,
  201. int baseTexture2Var, int baseTextureTransform2Var, int baseTextureFrame2Var);
  202. void DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar,
  203. int bumpmapVar, int bumpFrameVar,
  204. int bumpTransformVar,
  205. int envmapMaskVar, int envmapMaskFrame,
  206. int envmapVar,
  207. int envmapFrameVar,
  208. int envmapTintVar, int colorVar, int alphaVar,
  209. int envmapContrastVar, int envmapSaturationVar, int frameVar, int fresnelReflectionVar,
  210. bool doBaseTexture2,
  211. int baseTexture2Var,
  212. int baseTextureTransform2Var,
  213. int baseTextureFrame2Var,
  214. bool bSSBump
  215. );
  216. // Sets up hw morphing state for the vertex shader
  217. void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler );
  218. // Computes the shader index for vertex lit materials
  219. int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const;
  220. // Helper for setting up flashlight constants
  221. void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms );
  222. #if SUPPORT_DX8
  223. void DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
  224. bool bBump, int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar,
  225. int flashlightTextureFrameVar, bool bLightmappedGeneric, bool bWorldVertexTransition,
  226. int nWorldVertexTransitionPassID, int baseTexture2Var, int baseTexture2FrameVar,
  227. bool bTeeth=false, int nTeethForwardVar=0, int nTeethIllumFactorVar=0 );
  228. #endif
  229. struct DrawFlashlight_dx90_Vars_t
  230. {
  231. DrawFlashlight_dx90_Vars_t()
  232. {
  233. // set all ints to -1
  234. memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) );
  235. // set all bools to a default value.
  236. m_bBump = false;
  237. m_bLightmappedGeneric = false;
  238. m_bWorldVertexTransition = false;
  239. m_bTeeth = false;
  240. m_bSSBump = false;
  241. m_fSeamlessScale = 0.0;
  242. }
  243. bool m_bBump;
  244. bool m_bLightmappedGeneric;
  245. bool m_bWorldVertexTransition;
  246. bool m_bTeeth;
  247. int m_nBumpmapVar;
  248. int m_nBumpmapFrame;
  249. int m_nBumpTransform;
  250. int m_nFlashlightTextureVar;
  251. int m_nFlashlightTextureFrameVar;
  252. int m_nBaseTexture2Var;
  253. int m_nBaseTexture2FrameVar;
  254. int m_nBumpmap2Var;
  255. int m_nBumpmap2Frame;
  256. int m_nBump2Transform;
  257. int m_nDetailVar;
  258. int m_nDetailScale;
  259. int m_nDetailTextureCombineMode;
  260. int m_nDetailTextureBlendFactor;
  261. int m_nDetailTint;
  262. int m_nTeethForwardVar;
  263. int m_nTeethIllumFactorVar;
  264. int m_nAlphaTestReference;
  265. bool m_bSSBump;
  266. float m_fSeamlessScale; // 0.0 = not seamless
  267. };
  268. void DrawFlashlight_dx90( IMaterialVar** params,
  269. IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars );
  270. #endif // GAME_SHADER_DLL
  271. BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 );
  272. void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV );
  273. //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth.
  274. //This pass fills in the areas that passed the alpha test with depth in dest alpha
  275. //by writing only equal depth pixels and only if we should be writing depth to dest alpha
  276. void DrawEqualDepthToDestAlpha( void );
  277. private:
  278. // Helper methods for VertexLitGenericPass
  279. // void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin );
  280. void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar,
  281. int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar,
  282. int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar,
  283. int envmapMaskScaleVar, int envmapTintVar );
  284. // Converts a color + alpha into a vector4
  285. void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color );
  286. };
  287. FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false )
  288. {
  289. // Old code
  290. //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x;
  291. //float flFlashlightScale = 1.0f / flToneMapScale;
  292. // Fix to old code to keep flashlight from ever getting brighter than 1.0
  293. //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x;
  294. //if ( flToneMapScale < 1.0f )
  295. // flToneMapScale = 1.0f;
  296. //float flFlashlightScale = 1.0f / flToneMapScale;
  297. // Force flashlight to 25% bright always
  298. float flFlashlightScale = 0.25f;
  299. if ( !g_pHardwareConfig->GetHDREnabled() )
  300. {
  301. // Non-HDR path requires 2.0 flashlight
  302. flFlashlightScale = 2.0f;
  303. }
  304. // DX10 requires some hackery due to sRGB/blend ordering change from DX9
  305. if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
  306. {
  307. flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800
  308. }
  309. // Generate pixel shader constant
  310. float const *pFlashlightColor = state.m_Color;
  311. float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] };
  312. vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term
  313. // Red flashlight for testing
  314. //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f;
  315. pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst );
  316. }
  317. FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state )
  318. {
  319. // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light
  320. if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
  321. return state.m_flShadowAtten * 0.1f; // magic number
  322. return state.m_flShadowAtten;
  323. }
  324. FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state )
  325. {
  326. // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that
  327. return state.m_flShadowFilterSize / 1024.0f;
  328. }
  329. // convenient material variable access functions for helpers to use.
  330. FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params )
  331. {
  332. return ( nVar != -1 ) && ( params[nVar]->IsTexture() );
  333. }
  334. FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params )
  335. {
  336. return ( nVar != -1 ) && ( params[nVar]->GetIntValue() );
  337. }
  338. FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 )
  339. {
  340. return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue;
  341. }
  342. FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 )
  343. {
  344. return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue;
  345. }
  346. FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue )
  347. {
  348. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  349. {
  350. params[nIndex]->SetFloatValue( flValue );
  351. }
  352. }
  353. FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue )
  354. {
  355. if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
  356. {
  357. params[nIndex]->SetIntValue( nValue );
  358. }
  359. }
  360. class ConVar;
  361. #ifdef _DEBUG
  362. extern ConVar mat_envmaptintoverride;
  363. extern ConVar mat_envmaptintscale;
  364. #endif
  365. #endif // BASEVSSHADER_H