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.

291 lines
8.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include "BaseVSShader.h"
  7. #include "unlitgeneric_vs20.inc"
  8. #include "modulate_ps20.inc"
  9. #include "modulate_ps20b.inc"
  10. #include "cpp_shader_constant_register_map.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. #include "cloak_blended_pass_helper.h"
  14. DEFINE_FALLBACK_SHADER( Modulate, Modulate_DX9 )
  15. BEGIN_VS_SHADER( Modulate_DX9,
  16. "Help for Modulate" )
  17. BEGIN_SHADER_PARAMS
  18. SHADER_PARAM( WRITEZ, SHADER_PARAM_TYPE_BOOL, "0", "Forces z to be written if set" )
  19. SHADER_PARAM( MOD2X, SHADER_PARAM_TYPE_BOOL, "0", "forces a 2x modulate so that you can brighten and darken things" )
  20. // Cloak Pass
  21. SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" )
  22. SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
  23. SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" )
  24. SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
  25. END_SHADER_PARAMS
  26. SHADER_FALLBACK
  27. {
  28. if ( !(g_pHardwareConfig->SupportsPixelShaders_2_0() && g_pHardwareConfig->SupportsVertexShaders_2_0()) ||
  29. (g_pHardwareConfig->GetDXSupportLevel() < 90) )
  30. {
  31. return "Modulate_DX8";
  32. }
  33. return 0;
  34. }
  35. // Cloak Pass
  36. void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info )
  37. {
  38. info.m_nCloakFactor = CLOAKFACTOR;
  39. info.m_nCloakColorTint = CLOAKCOLORTINT;
  40. info.m_nRefractAmount = REFRACTAMOUNT;
  41. }
  42. bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
  43. {
  44. if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
  45. {
  46. if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time
  47. return true;
  48. else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
  49. return true;
  50. // else, not cloaking this frame, so check flag2 in case the base material still needs it
  51. }
  52. // Check flag2 if not drawing cloak pass
  53. return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
  54. }
  55. bool IsTranslucent( IMaterialVar **params ) const
  56. {
  57. if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
  58. {
  59. if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
  60. return true;
  61. // else, not cloaking this frame, so check flag in case the base material still needs it
  62. }
  63. // Check flag if not drawing cloak pass
  64. return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT );
  65. }
  66. SHADER_INIT_PARAMS()
  67. {
  68. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  69. // Cloak Pass
  70. if ( !params[CLOAKPASSENABLED]->IsDefined() )
  71. {
  72. params[CLOAKPASSENABLED]->SetIntValue( 0 );
  73. }
  74. else if ( params[CLOAKPASSENABLED]->GetIntValue() )
  75. {
  76. CloakBlendedPassVars_t info;
  77. SetupVarsCloakBlendedPass( info );
  78. InitParamsCloakBlendedPass( this, params, pMaterialName, info );
  79. }
  80. }
  81. SHADER_INIT
  82. {
  83. if (params[BASETEXTURE]->IsDefined())
  84. {
  85. LoadTexture( BASETEXTURE );
  86. }
  87. // Cloak Pass
  88. if ( params[CLOAKPASSENABLED]->GetIntValue() )
  89. {
  90. CloakBlendedPassVars_t info;
  91. SetupVarsCloakBlendedPass( info );
  92. InitCloakBlendedPass( this, params, info );
  93. }
  94. }
  95. SHADER_DRAW
  96. {
  97. // Skip the standard rendering if cloak pass is fully opaque
  98. bool bDrawStandardPass = true;
  99. if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting
  100. {
  101. CloakBlendedPassVars_t info;
  102. SetupVarsCloakBlendedPass( info );
  103. if ( CloakBlendedPassIsFullyOpaque( params, info ) )
  104. {
  105. bDrawStandardPass = false;
  106. }
  107. }
  108. // Standard rendering pass
  109. if ( bDrawStandardPass )
  110. {
  111. bool bMod2X = params[MOD2X]->IsDefined() && params[MOD2X]->GetIntValue();
  112. bool bVertexColorOrAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
  113. bool bWriteZ = params[WRITEZ]->GetIntValue() != 0;
  114. BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true );
  115. bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use
  116. SHADOW_STATE
  117. {
  118. if( bMod2X )
  119. {
  120. EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR );
  121. }
  122. else
  123. {
  124. EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO );
  125. }
  126. if ( bWriteZ )
  127. {
  128. // This overrides the disabling of depth writes performed in
  129. // EnableAlphaBlending
  130. pShaderShadow->EnableDepthWrites( true );
  131. }
  132. unsigned int flags = VERTEX_POSITION;
  133. int numTexCoords = 0;
  134. int userDataSize = 0;
  135. if( params[BASETEXTURE]->IsTexture() )
  136. {
  137. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  138. numTexCoords = 1;
  139. }
  140. if( bVertexColorOrAlpha )
  141. {
  142. flags |= VERTEX_COLOR;
  143. }
  144. // HACK: add 1 texcoord if these verts are too thin (to do with how we
  145. // bind stream 2 - see CShaderShadowDX8::VertexShaderVertexFormat)
  146. // FIXME: instead of this, don't add stream 2 elements to all vertex decls!
  147. if ( !( flags & VERTEX_COLOR ) && ( numTexCoords == 0 ) )
  148. {
  149. numTexCoords = 1;
  150. }
  151. // This shader supports compressed vertices, so OR in that flag:
  152. flags |= VERTEX_FORMAT_COMPRESSED;
  153. pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, NULL, userDataSize );
  154. DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 );
  155. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bVertexColorOrAlpha ? 1 : 0 );
  156. SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 );
  157. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  158. {
  159. DECLARE_STATIC_PIXEL_SHADER( modulate_ps20b );
  160. SET_STATIC_PIXEL_SHADER( modulate_ps20b );
  161. }
  162. else
  163. {
  164. DECLARE_STATIC_PIXEL_SHADER( modulate_ps20 );
  165. SET_STATIC_PIXEL_SHADER( modulate_ps20 );
  166. }
  167. // We need to fog to *white* regardless of overbrighting...
  168. if( bMod2X )
  169. {
  170. FogToGrey();
  171. }
  172. else
  173. {
  174. FogToOOOverbright();
  175. }
  176. pShaderShadow->EnableAlphaWrites( bWriteZ && bFullyOpaque );
  177. }
  178. DYNAMIC_STATE
  179. {
  180. if( params[BASETEXTURE]->IsTexture() )
  181. {
  182. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  183. SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
  184. }
  185. // set constant color for modulation
  186. SetModulationVertexShaderDynamicState();
  187. // We need to fog to *white* regardless of overbrighting...
  188. if( bMod2X )
  189. {
  190. float grey[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
  191. pShaderAPI->SetPixelShaderConstant( 0, grey );
  192. }
  193. else
  194. {
  195. float white[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
  196. pShaderAPI->SetPixelShaderConstant( 0, white );
  197. }
  198. pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
  199. float vEyePos_SpecExponent[4];
  200. pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
  201. vEyePos_SpecExponent[3] = 0.0f;
  202. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
  203. float vVertexColor[4] = { bVertexColorOrAlpha ? 1.0f : 0.0f, 0.0f, 0.0f, 0.0f };
  204. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 );
  205. DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 );
  206. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  207. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  208. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  209. SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 );
  210. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  211. {
  212. DECLARE_DYNAMIC_PIXEL_SHADER( modulate_ps20b );
  213. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  214. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  215. SET_DYNAMIC_PIXEL_SHADER( modulate_ps20b );
  216. }
  217. else
  218. {
  219. DECLARE_DYNAMIC_PIXEL_SHADER( modulate_ps20 );
  220. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  221. SET_DYNAMIC_PIXEL_SHADER( modulate_ps20 );
  222. }
  223. }
  224. Draw();
  225. }
  226. else
  227. {
  228. // Skip this pass!
  229. Draw( false );
  230. }
  231. // Cloak Pass
  232. if ( params[CLOAKPASSENABLED]->GetIntValue() )
  233. {
  234. // If ( snapshotting ) or ( we need to draw this frame )
  235. if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) )
  236. {
  237. CloakBlendedPassVars_t info;
  238. SetupVarsCloakBlendedPass( info );
  239. DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression );
  240. }
  241. else // We're not snapshotting and we don't need to draw this frame
  242. {
  243. // Skip this pass!
  244. Draw( false );
  245. }
  246. }
  247. }
  248. END_SHADER