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.

356 lines
11 KiB

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