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.

2407 lines
102 KiB

  1. //====== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. =====//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "BaseVSShader.h"
  9. #include "vertexlitgeneric_dx9_helper.h"
  10. #include "phong_dx9_helper.h"
  11. #include "vertexlit_and_unlit_generic_vs20.inc"
  12. #include "vertexlit_and_unlit_generic_bump_vs20.inc"
  13. #include "vertexlit_and_unlit_generic_ps20.inc"
  14. #include "vertexlit_and_unlit_generic_ps20b.inc"
  15. #include "vertexlit_and_unlit_generic_bump_ps20.inc"
  16. #include "vertexlit_and_unlit_generic_bump_ps20b.inc"
  17. #if !defined( _GAMECONSOLE )
  18. #include "vertexlit_and_unlit_generic_vs30.inc"
  19. #include "vertexlit_and_unlit_generic_ps30.inc"
  20. #include "vertexlit_and_unlit_generic_bump_vs30.inc"
  21. #include "vertexlit_and_unlit_generic_bump_ps30.inc"
  22. #endif
  23. #include "shaderapifast.h"
  24. #include "shaderlib/commandbuilder.h"
  25. #include "convar.h"
  26. #include "tier0/vprof.h"
  27. // memdbgon must be the last include file in a .cpp file!!!
  28. #include "tier0/memdbgon.h"
  29. static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT );
  30. static ConVar mat_phong( "mat_phong", "1" );
  31. static ConVar mat_displacementmap( "mat_displacementmap", "1", FCVAR_CHEAT );
  32. extern ConVar lm_test;
  33. static ConVar mat_force_vertexfog( "mat_force_vertexfog", "0", FCVAR_DEVELOPMENTONLY );
  34. #if defined( CSTRIKE15 ) && defined( _X360 )
  35. static ConVar r_shader_srgbread( "r_shader_srgbread", "1", 0, "1 = use shader srgb texture reads, 0 = use HW" );
  36. #else
  37. static ConVar r_shader_srgbread( "r_shader_srgbread", "0", 0, "1 = use shader srgb texture reads, 0 = use HW" );
  38. #endif
  39. // r_staticlight_streams
  40. // defines format of lighting for static props.
  41. // "1" = lighting comes as 4 bytes per vertex and is lighting with regard to vertex normal
  42. // "3" = lighting comes as 12 bytes per vertex and is lighting with regard to hl2-basis
  43. ConVar r_staticlight_streams( "r_staticlight_streams", "1", FCVAR_HIDDEN );
  44. // r_staticlight_streams_indirect_only
  45. // defines format of lighting for static props using vertexlitgeneric_bump shader
  46. // "0" = lighting stream colors have sunlight baked in
  47. // "1" = lighting stream colors store indirect only
  48. // Prequisite: 3 lighting streams enabled
  49. ConVar r_staticlight_streams_indirect_only( "r_staticlight_streams_indirect_only", "-", FCVAR_HIDDEN );
  50. static void r_staticlight_mode_changed( IConVar *var, const char *pOldValue, float flOldValue )
  51. {
  52. g_pMaterialSystem->ReloadMaterials( NULL );
  53. }
  54. ConVar r_staticlight_mode( "r_staticlight_mode", "0", FCVAR_DEVELOPMENTONLY, "0 - support three color streams, 1 - use avg of three streams, 2 - single color stream", r_staticlight_mode_changed );
  55. static inline bool WantsPhongShaderInternal( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info )
  56. {
  57. if ( info.m_nPhong == -1) // Don't use without Phong flag
  58. return false;
  59. if ( params[info.m_nPhong]->GetIntValue() == 0 ) // Don't use without Phong flag set to 1
  60. return false;
  61. if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture() ) // If there's Phong flag and diffuse warp do Phong
  62. return true;
  63. if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 1 )
  64. {
  65. if ( info.m_nBumpmap == -1 ) // Don't use without a bump map
  66. return false;
  67. if ( !params[info.m_nBumpmap]->IsDefined() ) // Don't use if the texture isn't specified
  68. return false;
  69. }
  70. return true;
  71. }
  72. static inline bool WantsPhongShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info )
  73. {
  74. if ( !mat_phong.GetBool() )
  75. {
  76. // If mat_phong is disabled (because the GPU level is too low), check to see if the material uses Phong and wants to force Phong on anyway.
  77. if ( ( info.m_nForcePhong != -1 ) && ( params[ info.m_nForcePhong ]->GetIntValue() ) )
  78. {
  79. if ( WantsPhongShaderInternal( params, info ) )
  80. {
  81. return true;
  82. }
  83. }
  84. return false;
  85. }
  86. return WantsPhongShaderInternal( params, info );
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Initialize shader parameters
  90. //-----------------------------------------------------------------------------
  91. void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info )
  92. {
  93. InitIntParam( info.m_nBlendWithSmokeGrenade, params, 0 );
  94. if ( info.m_nBlendWithSmokeGrenadePosEntity != -1 && !params[info.m_nBlendWithSmokeGrenadePosEntity]->IsDefined() )
  95. params[info.m_nBlendWithSmokeGrenadePosEntity]->SetVecValue( 0, 0, 0 );
  96. if ( info.m_nBlendWithSmokeGrenadePosSmoke != -1 && !params[info.m_nBlendWithSmokeGrenadePosSmoke]->IsDefined() )
  97. params[info.m_nBlendWithSmokeGrenadePosSmoke]->SetVecValue( 0, 0, 0 );
  98. #if defined ( CSTRIKE15 )
  99. InitIntParam( info.m_nShaderSrgbRead360, params, 1 );
  100. #else
  101. InitIntParam( info.m_nShaderSrgbRead360, params, 0 );
  102. #endif
  103. InitIntParam( info.m_nPhong, params, 0 );
  104. InitIntParam( info.m_nAllowFenceRenderStateHack, params, 0 );
  105. InitFloatParam( info.m_nAlphaTestReference, params, 0.0f );
  106. InitIntParam( info.m_nVertexAlphaTest, params, 0 );
  107. InitIntParam( info.m_nFlashlightNoLambert, params, 0 );
  108. InitIntParam( info.m_nLowQualityFlashlightShadows, params, 0 );
  109. InitIntParam( info.m_nDisableCSMLookup, params, 0 );
  110. if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() )
  111. {
  112. params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  113. }
  114. if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() )
  115. {
  116. params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  117. }
  118. InitIntParam( info.m_nEnvmapFrame, params, 0 );
  119. InitIntParam( info.m_nBumpFrame, params, 0 );
  120. InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 );
  121. InitIntParam( info.m_nReceiveFlashlight, params, 0 );
  122. InitFloatParam( info.m_nDetailScale, params, 4.0f );
  123. if ( (info.m_nSelfIllumTint != -1) && (!params[info.m_nSelfIllumTint]->IsDefined()) )
  124. {
  125. params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  126. }
  127. // Set the selfillummask flag2
  128. if ( ( info.m_nSelfIllumMask != -1 ) && ( params[info.m_nSelfIllumMask]->IsDefined() ) )
  129. {
  130. SET_FLAGS2( MATERIAL_VAR2_SELFILLUMMASK );
  131. }
  132. InitFloatParam( info.m_nSelfIllumMaskScale, params, 1.0f );
  133. // Override vertex fog via the global setting if it isn't enabled/disabled in the material file.
  134. if ( !IS_FLAG_DEFINED( MATERIAL_VAR_VERTEXFOG ) && mat_force_vertexfog.GetBool() )
  135. {
  136. SET_FLAGS( MATERIAL_VAR_VERTEXFOG );
  137. }
  138. if ( WantsPhongShader( params, info ) )
  139. {
  140. if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() )
  141. {
  142. params[info.m_nPhong]->SetIntValue( 0 );
  143. }
  144. else
  145. {
  146. InitParamsPhong_DX9( pShader, params, pMaterialName, info );
  147. return;
  148. }
  149. }
  150. // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture
  151. if ( info.m_nFlashlightTexture != -1 )
  152. {
  153. params[FLASHLIGHTTEXTURE]->SetStringValue( GetFlashlightTextureFilename() );
  154. }
  155. // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping.
  156. if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() &&
  157. params[info.m_nBaseTexture]->IsDefined() )
  158. {
  159. params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() );
  160. }
  161. // This shader can be used with hw skinning
  162. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  163. if ( bVertexLitGeneric )
  164. {
  165. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
  166. }
  167. else
  168. {
  169. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  170. }
  171. InitIntParam( info.m_nEnvmapMaskFrame, params, 0 );
  172. InitFloatParam( info.m_nEnvmapContrast, params, 0.0 );
  173. InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f );
  174. if ( info.m_nEnvMapLightScale != -1 )
  175. InitFloatParam( info.m_nEnvMapLightScale, params, 0.0f );
  176. if ( info.m_nEnvMapLightScaleMinMax != -1 )
  177. InitVecParam( info.m_nEnvMapLightScaleMinMax, params, 0.0f, 1.0f );
  178. InitFloatParam( info.m_nSeamlessScale, params, 0.0 );
  179. // handle line art parms
  180. InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 );
  181. InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 );
  182. InitFloatParam( info.m_nGlowAlpha, params, 1.0 );
  183. InitFloatParam( info.m_nOutlineAlpha, params, 1.0 );
  184. // No texture means no self-illum or env mask in base alpha
  185. if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() )
  186. {
  187. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  188. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  189. }
  190. // If in decal mode, no debug override...
  191. if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
  192. {
  193. SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  194. }
  195. if( ( (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() )
  196. // we don't need a tangent space if we have envmap without bumpmap
  197. // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() )
  198. )
  199. {
  200. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  201. }
  202. else if ( bVertexLitGeneric && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) // diffuse warp goes down bump path...
  203. {
  204. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  205. }
  206. else // no tangent space needed
  207. {
  208. CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
  209. }
  210. bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
  211. if ( hasNormalMapAlphaEnvmapMask )
  212. {
  213. params[info.m_nEnvmapMask]->SetUndefined();
  214. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  215. }
  216. if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 &&
  217. params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask )
  218. {
  219. DevWarning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName );
  220. params[info.m_nEnvmap]->SetUndefined();
  221. }
  222. if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() )
  223. {
  224. params[info.m_nEnvmapMask]->SetUndefined();
  225. if ( !hasNormalMapAlphaEnvmapMask )
  226. {
  227. DevWarning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName );
  228. params[info.m_nEnvmap]->SetUndefined();
  229. }
  230. }
  231. // If mat_specular 0, then get rid of envmap
  232. if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() )
  233. {
  234. params[info.m_nEnvmap]->SetUndefined();
  235. }
  236. InitFloatParam( info.m_nHDRColorScale, params, 1.0f );
  237. InitIntParam( info.m_nLinearWrite, params, 0 );
  238. InitIntParam( info.m_nGammaColorRead, params, 0 );
  239. InitIntParam( info.m_nAllowDiffuseModulation, params, 1 );
  240. if ( ( info.m_nEnvMapFresnelMinMaxExp != -1 ) && !params[info.m_nEnvMapFresnelMinMaxExp]->IsDefined() )
  241. {
  242. params[info.m_nEnvMapFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 2.0f, 0.0f );
  243. }
  244. if ( ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 ) && !params[info.m_nBaseAlphaEnvMapMaskMinMaxExp]->IsDefined() )
  245. {
  246. // Default to min: 1 max: 0 exp: 1 so that we default to the legacy behavior for basealphaenvmapmask, which is 1-baseColor.a
  247. // These default values translate to a scale of -1, bias of 1 and exponent 1 in the shader.
  248. params[info.m_nBaseAlphaEnvMapMaskMinMaxExp]->SetVecValue( 1.0f, 0.0f, 1.0f, 0.0f );
  249. }
  250. InitIntParam( info.m_nTreeSway, params, 0 );
  251. InitFloatParam( info.m_nTreeSwayHeight, params, 1000.0f );
  252. InitFloatParam( info.m_nTreeSwayStartHeight, params, 0.1f );
  253. InitFloatParam( info.m_nTreeSwayRadius, params, 300.0f );
  254. InitFloatParam( info.m_nTreeSwayStartRadius, params, 0.2f );
  255. InitFloatParam( info.m_nTreeSwaySpeed, params, 1.0f );
  256. InitFloatParam( info.m_nTreeSwaySpeedHighWindMultiplier, params, 2.0f );
  257. InitFloatParam( info.m_nTreeSwayStrength, params, 10.0f );
  258. InitFloatParam( info.m_nTreeSwayScrumbleSpeed, params, 5.0f );
  259. InitFloatParam( info.m_nTreeSwayScrumbleStrength, params, 10.0f );
  260. InitFloatParam( info.m_nTreeSwayScrumbleFrequency, params, 12.0f );
  261. InitFloatParam( info.m_nTreeSwayFalloffExp, params, 1.5f );
  262. InitFloatParam( info.m_nTreeSwayScrumbleFalloffExp, params, 1.0f );
  263. InitFloatParam( info.m_nTreeSwaySpeedLerpStart, params, 3.0f );
  264. InitFloatParam( info.m_nTreeSwaySpeedLerpEnd, params, 6.0f );
  265. InitIntParam( info.m_nTreeSwayStatic, params, 0 );
  266. InitIntParam( info.m_nModelDecalIgnoreZ, params, 0 );
  267. }
  268. //-----------------------------------------------------------------------------
  269. // Initialize shader
  270. //-----------------------------------------------------------------------------
  271. void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info )
  272. {
  273. // both detailed and bumped = needs Phong shader (for now)
  274. bool bNeedsPhongBecauseOfDetail = false;
  275. //bool bHasBump = ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsTexture();
  276. //if ( bHasBump )
  277. //{
  278. // if ( ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsDefined() )
  279. // bNeedsPhongBecauseOfDetail = true;
  280. //}
  281. if ( bNeedsPhongBecauseOfDetail ||
  282. ( info.m_nPhong != -1 &&
  283. params[info.m_nPhong]->GetIntValue() ) &&
  284. g_pHardwareConfig->SupportsPixelShaders_2_b() )
  285. {
  286. bool bPhongEnabled = mat_phong.GetBool();
  287. // If mat_phong is disabled (because the GPU level is too low), check to see if the material uses Phong and wants to force Phong on anyway.
  288. if ( !bPhongEnabled )
  289. {
  290. if ( ( info.m_nForcePhong != -1 ) && ( params[info.m_nForcePhong]->GetIntValue() ) )
  291. {
  292. bPhongEnabled = true;
  293. }
  294. }
  295. if ( bPhongEnabled )
  296. {
  297. InitPhong_DX9( pShader, params, info );
  298. return;
  299. }
  300. }
  301. if ( info.m_nFlashlightTexture != -1 )
  302. {
  303. pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB );
  304. }
  305. bool bIsBaseTextureTranslucent = false;
  306. if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() )
  307. {
  308. pShader->LoadTexture( info.m_nBaseTexture, ( ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ) ? 0 : TEXTUREFLAGS_SRGB ) | ANISOTROPIC_OVERRIDE );
  309. if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() )
  310. {
  311. bIsBaseTextureTranslucent = true;
  312. }
  313. }
  314. bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined();
  315. // No alpha channel in any of the textures? No self illum or envmapmask
  316. if ( !bIsBaseTextureTranslucent )
  317. {
  318. bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 );
  319. // Can still be self illum with no base alpha if using one of these alternate modes
  320. if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask )
  321. {
  322. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  323. }
  324. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  325. }
  326. if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() )
  327. {
  328. int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue();
  329. pShader->LoadTexture( info.m_nDetail, IsSRGBDetailTexture( nDetailBlendMode ) ? TEXTUREFLAGS_SRGB : 0 );
  330. }
  331. if ( g_pConfig->UseBumpmapping() )
  332. {
  333. if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() )
  334. {
  335. pShader->LoadBumpMap( info.m_nBumpmap, ANISOTROPIC_OVERRIDE );
  336. SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL );
  337. }
  338. else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() )
  339. {
  340. SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL );
  341. }
  342. }
  343. // Don't alpha test if the alpha channel is used for other purposes
  344. if ( ( IS_FLAG_SET( MATERIAL_VAR_SELFILLUM) && !IS_FLAG2_SET( MATERIAL_VAR2_SELFILLUMMASK ) ) || IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) )
  345. {
  346. CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
  347. }
  348. if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() )
  349. {
  350. pShader->LoadCubeMap( info.m_nEnvmap, ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ) | ANISOTROPIC_OVERRIDE );
  351. }
  352. if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() )
  353. {
  354. pShader->LoadTexture( info.m_nEnvmapMask );
  355. }
  356. if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() )
  357. {
  358. pShader->LoadTexture( info.m_nDiffuseWarpTexture );
  359. }
  360. if ( bHasSelfIllumMask )
  361. {
  362. pShader->LoadTexture( info.m_nSelfIllumMask );
  363. }
  364. if ( ( info.m_nDisplacementMap != -1 ) && params[info.m_nDisplacementMap]->IsDefined() )
  365. {
  366. pShader->LoadTexture( info.m_nDisplacementMap );
  367. }
  368. if ( ( info.m_nDecalTexture != -1 ) && params[info.m_nDecalTexture]->IsDefined() )
  369. {
  370. int nDecalBlendMode = (info.m_nDecalTextureCombineMode == -1) ? 0 : params[info.m_nDecalTextureCombineMode]->GetIntValue();
  371. pShader->LoadTexture( info.m_nDecalTexture, IsSRGBDecalTexture( nDecalBlendMode ) ? TEXTUREFLAGS_SRGB : 0 );
  372. }
  373. if ( (info.m_nTintMaskTexture != -1) && params[info.m_nTintMaskTexture]->IsDefined() )
  374. {
  375. pShader->LoadTexture( info.m_nTintMaskTexture, TEXTUREFLAGS_SRGB );
  376. }
  377. }
  378. // FIXME:
  379. // From revision #18 of this file in staging:
  380. // "Quick fix to keep Phong shader from being run if the mat_bumpmap convar is set to zero."
  381. // This change caused shader problems in HLMV (use ep2/Hunter model as an example) and I was told to fix it. -Jeep
  382. //
  383. //extern ConVar mat_bumpmap( "mat_bumpmap", "1" );
  384. class CVertexLitGeneric_DX9_Context : public CBasePerMaterialContextData
  385. {
  386. public:
  387. CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut;
  388. #ifdef _PS3
  389. CCommandBufferBuilder< CFixedCommandStorageBuffer< 256 > > m_flashlightECB;
  390. #endif
  391. };
  392. //-----------------------------------------------------------------------------
  393. // Draws the shader
  394. //-----------------------------------------------------------------------------
  395. static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params,
  396. IShaderDynamicAPI * pShaderAPI,
  397. IShaderShadow* pShaderShadow,
  398. bool bVertexLitGeneric, bool bHasFlashlight, bool bSinglePassFlashlight,
  399. VertexLitGeneric_DX9_Vars_t &info,
  400. VertexCompressionType_t vertexCompression,
  401. CBasePerMaterialContextData **pContextDataPtr )
  402. {
  403. CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr );
  404. bool bAvgStaticLightStreams = r_staticlight_mode.GetInt() == 1;
  405. bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow() && ( !bAvgStaticLightStreams );
  406. bool bSupportsSM3 = g_pHardwareConfig->SupportsPixelShaders_3_0() && ( !bAvgStaticLightStreams );
  407. bool bSFM = ( ToolsEnabled() && IsPlatformWindowsPC() && bSupportsSM3 ) ? true : false;
  408. bool bHasBump = IsTextureSet( info.m_nBumpmap, params );
  409. #if !defined( _GAMECONSOLE )
  410. bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL );
  411. #endif
  412. float fSinglePassFlashlight = bSinglePassFlashlight ? 1.0f : 0.0f;
  413. bool hasDiffuseLighting = bVertexLitGeneric;
  414. #if defined( CSTRIKE15 )
  415. bool bShaderSrgbRead = ( IsX360() && r_shader_srgbread.GetBool() );
  416. #else
  417. bool bShaderSrgbRead = ( IsX360() && IS_PARAM_DEFINED( info.m_nShaderSrgbRead360 ) && ( params[info.m_nShaderSrgbRead360]->GetIntValue() ) );
  418. #endif
  419. bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0;
  420. bool bHasDiffuseWarp = (!bHasFlashlight || bSinglePassFlashlight) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture();
  421. bool bHasDecalTexture = IsTextureSet( info.m_nDecalTexture, params );
  422. bool bHasTintMaskTexture = IsTextureSet( info.m_nTintMaskTexture, params );
  423. //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL );
  424. bool bFlashlightNoLambert = false;
  425. if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() )
  426. {
  427. bFlashlightNoLambert = true;
  428. }
  429. bool bLowQualityFlashlightShadows = false;
  430. if ( IsGameConsole() )
  431. {
  432. // Low quality shadows, useful on dense folliage.
  433. if ( ( info.m_nLowQualityFlashlightShadows != -1 ) && params[info.m_nLowQualityFlashlightShadows]->GetIntValue() )
  434. {
  435. bLowQualityFlashlightShadows = true;
  436. }
  437. }
  438. bool bDisableCSMLookup = false;
  439. if ( ( ( info.m_nDisableCSMLookup != -1 ) && params[info.m_nDisableCSMLookup]->GetIntValue() ) || g_pConfig->nFullbright == 1 )
  440. {
  441. // disable CSM lookup/filtering, useful on dense foliage
  442. bDisableCSMLookup = true;
  443. }
  444. bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params );
  445. // Hack
  446. int nDetailBlendMode= GetIntParam( info.m_nDetailTextureCombineMode, params );
  447. int nDecalBlendMode = GetIntParam( info.m_nDecalTextureCombineMode, params );
  448. if ( ( nDetailBlendMode == DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE ) && ( !g_pHardwareConfig->SupportsPixelShaders_2_b() ) )
  449. {
  450. nDetailBlendMode = DETAIL_BLEND_MODE_RGB_ADDITIVE_SELFILLUM; // skip fancy threshold blending if ps2.0
  451. }
  452. BlendType_t nBlendType;
  453. int nDetailTranslucencyTexture = -1;
  454. float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 );
  455. bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params );
  456. if ( bHasDetailTexture && ( fBlendFactor > 0.0 ) )
  457. {
  458. if ( ( nDetailBlendMode == DETAIL_BLEND_MODE_FADE ) ||
  459. ( nDetailBlendMode == DETAIL_BLEND_MODE_MULTIPLY ) ||
  460. ( nDetailBlendMode == DETAIL_BLEND_MODE_MASK_BASE_BY_DETAIL_ALPHA ) )
  461. {
  462. nDetailTranslucencyTexture = info.m_nDetail;
  463. }
  464. }
  465. bool bHasDisplacement = (info.m_nDisplacementMap != -1) && params[info.m_nDisplacementMap]->IsTexture() && bSFM;
  466. bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params );
  467. if ( bHasBaseTexture )
  468. {
  469. nBlendType = pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true, nDetailTranslucencyTexture );
  470. }
  471. else
  472. {
  473. nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false );
  474. }
  475. bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && (!bHasFlashlight || bSinglePassFlashlight); //dest alpha is free for special use
  476. bool bHasEnvmap = (!bHasFlashlight || bSinglePassFlashlight) && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture();
  477. if ( IsPC() && bHasFlashlight && bHasEnvmap && bSinglePassFlashlight )
  478. {
  479. Warning( "VertexLitGeneric_Dx9: Unsupported combo! Can't use envmap + flashlight + singlepass flashlight!\n" );
  480. }
  481. bool bSRGBWrite = true;
  482. if ( ( info.m_nLinearWrite != -1 ) && ( params[info.m_nLinearWrite]->GetIntValue() == 1 ) )
  483. {
  484. bSRGBWrite = false;
  485. }
  486. bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
  487. bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
  488. bool bTreeSway = ( GetIntParam( info.m_nTreeSway, params, 0 ) != 0 );
  489. int nTreeSwayMode = GetIntParam( info.m_nTreeSway, params, 0 );
  490. nTreeSwayMode = clamp( nTreeSwayMode, 0, 2 );
  491. #if !defined( _GAMECONSOLE )
  492. bool bMorphing = ( !pShaderAPI || pShaderAPI->IsHWMorphingEnabled() ) && !bTreeSway && bSFM && g_pHardwareConfig->HasFastVertexTextures();
  493. #endif
  494. if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) )
  495. {
  496. bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ) && !bTreeSway;
  497. bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ) && !bTreeSway;
  498. bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params );
  499. bool bHasSelfIllum = (!bHasFlashlight || bSinglePassFlashlight) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM );
  500. bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params );
  501. bool bHasSelfIllumInEnvMapMask =
  502. ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) &&
  503. ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ;
  504. bool bDesaturateWithBaseAlpha = !bHasSelfIllum && !bHasSelfIllumMask && GetFloatParam( info.m_nDesaturateWithBaseAlpha, params ) > 0.0f;
  505. if ( pShader->IsSnapshotting() )
  506. {
  507. // Per-instance state
  508. #if 0
  509. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  510. #else
  511. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 );
  512. #endif
  513. pShader->PI_BeginCommandBuffer();
  514. if ( bVertexLitGeneric )
  515. {
  516. if ( bHasBump || bHasDiffuseWarp )
  517. {
  518. pShader->PI_SetPixelShaderAmbientLightCube( 5 );
  519. pShader->PI_SetPixelShaderLocalLighting( 13 );
  520. }
  521. pShader->PI_SetVertexShaderAmbientLightCube();
  522. }
  523. // material can choose to support per-instance modulation via $allowdiffusemodulation
  524. bool bAllowDiffuseModulation = ( info.m_nAllowDiffuseModulation == -1 ) ? true : ( params[info.m_nAllowDiffuseModulation]->GetIntValue() != 0 );
  525. if ( bAllowDiffuseModulation )
  526. {
  527. if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() )
  528. {
  529. if ( bSRGBWrite )
  530. pShader->PI_SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() );
  531. else
  532. pShader->PI_SetModulationPixelShaderDynamicState_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() );
  533. }
  534. else
  535. {
  536. if ( bSRGBWrite )
  537. pShader->PI_SetModulationPixelShaderDynamicState_LinearColorSpace( 1 );
  538. else
  539. pShader->PI_SetModulationPixelShaderDynamicState( 1 );
  540. }
  541. }
  542. else
  543. {
  544. pShader->PI_SetModulationPixelShaderDynamicState_Identity( 1 );
  545. }
  546. pShader->PI_EndCommandBuffer();
  547. bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  548. bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
  549. if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 )
  550. {
  551. bHasVertexAlpha = true;
  552. }
  553. // look at color and alphamod stuff.
  554. // Unlit generic never uses the flashlight
  555. bool bHasSelfIllumFresnel = ( !bHasDetailTexture ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 );
  556. if ( bHasSelfIllumFresnel )
  557. {
  558. CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
  559. hasNormalMapAlphaEnvmapMask = false;
  560. }
  561. bool bHasEnvmap = (!bHasFlashlight || bSinglePassFlashlight) && ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsTexture();
  562. bool bHasEnvmapMask = (!bHasFlashlight || bSinglePassFlashlight) && ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture() );
  563. bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail;
  564. if ( IsPC() )
  565. {
  566. // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models)
  567. bHasNormal = true;
  568. }
  569. bool bHasEnvMapFresnel = bHasEnvmap && IsBoolSet( info.m_nEnvmapFresnel, params );
  570. //bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT );
  571. // Disabling half-lambert for CSGO (not compatible with CSM's, causes bad shadow aliasing).
  572. bool bHalfLambert = false;
  573. bool bSetBlendingShadowStateCalled = false;
  574. ShadowFilterMode_t nShadowFilterMode = SHADOWFILTERMODE_DEFAULT;
  575. if ( bHasFlashlight )
  576. {
  577. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  578. {
  579. nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode( bLowQualityFlashlightShadows /* bForceLowQuality */, bSupportsSM3 && !IsGameConsole() /* bPS30 */ ); // Based upon vendor and device dependent formats
  580. }
  581. if ( bSinglePassFlashlight )
  582. {
  583. pShader->SetBlendingShadowState( nBlendType );
  584. bSetBlendingShadowStateCalled = true;
  585. }
  586. else
  587. {
  588. //doing the flashlight as a second additive pass
  589. if (params[info.m_nBaseTexture]->IsTexture())
  590. {
  591. pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true );
  592. }
  593. else
  594. {
  595. pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false );
  596. }
  597. if ( bIsAlphaTested )
  598. {
  599. // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to
  600. // be the same on both the regular pass and the flashlight pass.
  601. pShaderShadow->EnableAlphaTest( false );
  602. pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
  603. }
  604. // Be sure not to write to dest alpha
  605. pShaderShadow->EnableAlphaWrites( false );
  606. pShaderShadow->EnableBlending( true );
  607. pShaderShadow->EnableDepthWrites( false );
  608. }
  609. }
  610. else
  611. {
  612. pShader->SetBlendingShadowState( nBlendType );
  613. bSetBlendingShadowStateCalled = true;
  614. }
  615. // Fence render state override
  616. if ( bSetBlendingShadowStateCalled )
  617. {
  618. if ( ( info.m_nAllowFenceRenderStateHack != -1 ) && params[info.m_nAllowFenceRenderStateHack]->GetIntValue() )
  619. {
  620. pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  621. pShaderShadow->EnableDepthWrites( true );
  622. }
  623. }
  624. bool bModelDecalIgnoreZ = IsBoolSet( info.m_nModelDecalIgnoreZ, params );
  625. if ( bModelDecalIgnoreZ && !pShader->UsingEditor( params ) /* <-- don't ignorez in hammer, hammer may render entities in wrong order making this mesh 'invisible' behind something that renders subsequently */ )
  626. {
  627. pShaderShadow->EnableDepthWrites( false );
  628. }
  629. // Alpha test
  630. pShaderShadow->EnableAlphaTest( bIsAlphaTested );
  631. if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
  632. {
  633. pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() );
  634. }
  635. unsigned int flags = VERTEX_POSITION;
  636. if ( bHasNormal )
  637. {
  638. flags |= VERTEX_NORMAL;
  639. }
  640. int userDataSize = 0;
  641. bool bSRGBInputAdapter = false;
  642. // basetexture
  643. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  644. if ( bHasBaseTexture )
  645. {
  646. if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) )
  647. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false );
  648. else
  649. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, !bShaderSrgbRead );
  650. }
  651. bool bSampler0SrgbRead = false;
  652. if ( bHasBaseTexture )
  653. {
  654. if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) )
  655. bSampler0SrgbRead = false;
  656. else
  657. bSampler0SrgbRead = !bShaderSrgbRead;
  658. }
  659. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bSampler0SrgbRead );
  660. if ( bHasEnvmap )
  661. {
  662. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  663. if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
  664. {
  665. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
  666. }
  667. }
  668. if ( bHasFlashlight )
  669. {
  670. pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture
  671. //pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 );
  672. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map
  673. pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie
  674. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true );
  675. }
  676. if ( bHasDetailTexture )
  677. {
  678. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  679. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, IsSRGBDetailTexture( nDetailBlendMode ) );
  680. }
  681. if ( bHasBump || bHasDiffuseWarp )
  682. {
  683. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  684. userDataSize = 4; // tangent S
  685. // Normalizing cube map
  686. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
  687. }
  688. if ( bHasEnvmapMask )
  689. {
  690. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
  691. }
  692. if ( ( bHasVertexColor || bHasVertexAlpha ) || ( bIsDecal && !IS_FLAG_SET( MATERIAL_VAR_WIREFRAME ) ) )
  693. {
  694. flags |= VERTEX_COLOR;
  695. }
  696. else if ( !bHasDiffuseWarp )
  697. {
  698. flags |= VERTEX_COLOR_STREAM_1;
  699. }
  700. if( bHasDiffuseWarp && (!bHasFlashlight || bSinglePassFlashlight) && !bHasSelfIllumFresnel )
  701. {
  702. pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Diffuse warp texture
  703. }
  704. if( bHasSelfIllum )
  705. {
  706. pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask
  707. }
  708. if ( bHasDisplacement && IsPC() && g_pHardwareConfig->HasFastVertexTextures() )
  709. {
  710. pShaderShadow->EnableVertexTexture( SHADER_VERTEXTEXTURE_SAMPLER2, true );
  711. }
  712. if ( bHasDecalTexture )
  713. {
  714. pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // decal overlay
  715. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, IsSRGBDecalTexture( nDecalBlendMode ) );
  716. }
  717. if ( bHasTintMaskTexture )
  718. {
  719. pShaderShadow->EnableTexture( SHADER_SAMPLER13, true );
  720. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true );
  721. }
  722. pShaderShadow->EnableSRGBWrite( bSRGBWrite );
  723. // texcoord0 : base texcoord
  724. int pTexCoordDim[3] = { 2, 2, 3 };
  725. int nTexCoordCount = 1;
  726. if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) )
  727. {
  728. ++nTexCoordCount;
  729. }
  730. else
  731. {
  732. pTexCoordDim[1] = 0;
  733. }
  734. #ifndef _GAMECONSOLE
  735. // Special morphed decal information
  736. if ( bIsDecal && bMorphing )
  737. {
  738. nTexCoordCount = 3;
  739. }
  740. #endif
  741. // This shader supports compressed vertices, so OR in that flag:
  742. flags |= VERTEX_FORMAT_COMPRESSED;
  743. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize );
  744. if ( bHasBump || bHasDiffuseWarp )
  745. {
  746. #ifndef _GAMECONSOLE
  747. if ( !bSupportsSM3 )
  748. #endif
  749. {
  750. DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 );
  751. SET_STATIC_VERTEX_SHADER_COMBO( SFM, bSFM );
  752. SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert);
  753. SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, g_pHardwareConfig->SupportsPixelShaders_2_b() );
  754. #ifdef _GAMECONSOLE
  755. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  756. #endif
  757. SET_STATIC_VERTEX_SHADER_COMBO( WORLD_NORMAL, 0 );
  758. SET_STATIC_VERTEX_SHADER_COMBO( FLATTEN_STATIC_CONTROL_FLOW, !bUseStaticControlFlow );
  759. bool bCSMEnabled_ps2b = false;
  760. SET_STATIC_VERTEX_SHADER_COMBO( CASCADED_SHADOW_MAPPING, bCSMEnabled_ps2b );
  761. SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 );
  762. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send OpenGL this way
  763. {
  764. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b );
  765. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  766. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  767. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  768. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel && !bHasFlashlight );
  769. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum );
  770. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel );
  771. SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask );
  772. SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert);
  773. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  774. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  775. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 7 );
  776. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  777. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 1 );
  778. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? nDecalBlendMode : 2 );
  779. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, bHasTintMaskTexture );
  780. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  781. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  782. SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, 0 );
  783. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup );
  784. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, 0 );
  785. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b );
  786. }
  787. else // ps_2_0
  788. {
  789. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 );
  790. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  791. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  792. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  793. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel );
  794. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum );
  795. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel );
  796. SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask );
  797. SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert);
  798. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  799. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  800. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 7 );
  801. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  802. // Decal blend mode 2 is mod2x. It's implemented not as a combo but rather remapped to the
  803. // Multiply blend mode (1), we also plumb in a 2.0 scalar into a shader constant below.
  804. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 2 );
  805. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? Min( nDecalBlendMode, 1 ) : 2 );
  806. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, 0 );
  807. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  808. SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, 0 );
  809. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, 0 );
  810. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, 0 );
  811. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 );
  812. }
  813. }
  814. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  815. else
  816. {
  817. // The vertex shader uses the vertex id stream
  818. if ( bSFM )
  819. {
  820. SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
  821. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_TESSELLATION );
  822. }
  823. int nCSMQualityComboValue = g_pHardwareConfig->GetCSMShaderMode( materials->GetCurrentConfigForVideoCard().GetCSMQualityMode() );
  824. DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  825. SET_STATIC_VERTEX_SHADER_COMBO( SFM, bSFM );
  826. SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert);
  827. SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, true );
  828. SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal );
  829. SET_STATIC_VERTEX_SHADER_COMBO( WORLD_NORMAL, nLightingPreviewMode == 3 );
  830. SET_STATIC_VERTEX_SHADER_COMBO( CASCADED_SHADOW_MAPPING, 0 );
  831. SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  832. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 );
  833. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  834. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  835. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  836. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel );
  837. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); // Careful here if we do single-pass flashlight on PC
  838. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel );
  839. SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask );
  840. SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert );
  841. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  842. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  843. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 7 );
  844. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  845. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 2 );
  846. // Decal blend mode 2 is mod2x. It's implemented not as a combo but rather remapped to the
  847. // Multiply blend mode (1), we also plumb in a 2.0 scalar into a shader constant below.
  848. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? Min( nDecalBlendMode, 1 ) : 2 );
  849. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, bHasTintMaskTexture );
  850. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  851. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  852. SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, nLightingPreviewMode == 3 );
  853. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup );
  854. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, ( g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup ) ? nCSMQualityComboValue : 0 );
  855. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 );
  856. }
  857. #endif
  858. }
  859. else // !(bHasBump || bHasDiffuseWarp)
  860. {
  861. #if 0
  862. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  863. #else
  864. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 );
  865. #endif
  866. bool bDistanceAlphaFromDetail = false;
  867. bool bSoftMask = false;
  868. bool bGlow = false;
  869. bool bOutline = false;
  870. bHasSelfIllumInEnvMapMask = bHasSelfIllumInEnvMapMask && bHasEnvmapMask;
  871. if ( bDistanceAlpha )
  872. {
  873. bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params );
  874. bSoftMask = IsBoolSet( info.m_nSoftEdges, params );
  875. bGlow = IsBoolSet( info.m_nGlow, params );
  876. bOutline = IsBoolSet( info.m_nOutline, params );
  877. }
  878. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  879. if ( !bSupportsSM3 )
  880. #endif
  881. {
  882. DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 );
  883. SET_STATIC_VERTEX_SHADER_COMBO( SFM, bSFM );
  884. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha );
  885. SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  886. SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert );
  887. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  888. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase );
  889. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail );
  890. SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) );
  891. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  892. SET_STATIC_VERTEX_SHADER_COMBO( TREESWAY, bTreeSway ? nTreeSwayMode : 0 );
  893. SET_STATIC_VERTEX_SHADER_COMBO( FLATTEN_STATIC_CONTROL_FLOW, !bUseStaticControlFlow );
  894. SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal );
  895. bool bCSMEnabled_ps2b = false;
  896. bool bCSMBlending = g_pHardwareConfig->GetCSMAccurateBlending();
  897. SET_STATIC_VERTEX_SHADER_COMBO( CASCADED_SHADOW_MAPPING, bCSMEnabled_ps2b );
  898. SET_STATIC_VERTEX_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  899. SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 );
  900. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send OpenGL this way
  901. {
  902. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b );
  903. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  904. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, bHasSelfIllumInEnvMapMask );
  905. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  906. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  907. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  908. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask && ( bHasEnvmap || bHasSelfIllumInEnvMapMask ) );
  909. SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask && bHasEnvmap );
  910. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPFRESNEL, bHasEnvMapFresnel && bHasEnvmap );
  911. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum );
  912. SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor );
  913. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  914. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 9 );
  915. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  916. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 1 );
  917. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? nDecalBlendMode : 2 );
  918. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, bHasTintMaskTexture );
  919. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase );
  920. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail );
  921. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha );
  922. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail );
  923. SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask );
  924. SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline );
  925. SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow );
  926. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  927. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  928. SET_STATIC_PIXEL_SHADER_COMBO( DESATURATEWITHBASEALPHA, bDesaturateWithBaseAlpha );
  929. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, 0 /*nLightingPreviewMode*/ );
  930. SET_STATIC_PIXEL_SHADER_COMBO( SRGB_INPUT_ADAPTER, bSRGBInputAdapter ? 1 : 0 );
  931. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup );
  932. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, 0 );
  933. SET_STATIC_PIXEL_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  934. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b );
  935. }
  936. else // ps_2_0
  937. {
  938. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 );
  939. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  940. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, bHasSelfIllumInEnvMapMask );
  941. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  942. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  943. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  944. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask && ( bHasEnvmap || bHasSelfIllumInEnvMapMask ) );
  945. SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask && bHasEnvmap );
  946. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPFRESNEL, bHasEnvMapFresnel && bHasEnvmap );
  947. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum );
  948. SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor );
  949. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  950. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 9 );
  951. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  952. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 1 );
  953. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? nDecalBlendMode : 2 );
  954. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, 0 );
  955. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase );
  956. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail );
  957. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha );
  958. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail );
  959. SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask );
  960. SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline );
  961. SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow );
  962. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  963. SET_STATIC_PIXEL_SHADER_COMBO( DESATURATEWITHBASEALPHA, bDesaturateWithBaseAlpha );
  964. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, 0 /*nLightingPreviewMode*/ );
  965. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, 0 );
  966. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, 0 );
  967. SET_STATIC_PIXEL_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  968. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 );
  969. }
  970. }
  971. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  972. else
  973. {
  974. // The vertex shader uses the vertex id stream
  975. if ( bSFM )
  976. {
  977. SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
  978. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_TESSELLATION );
  979. }
  980. int nCSMQualityComboValue = g_pHardwareConfig->GetCSMShaderMode( materials->GetCurrentConfigForVideoCard().GetCSMQualityMode() );
  981. bool bCSMBlending = g_pHardwareConfig->GetCSMAccurateBlending();
  982. DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 );
  983. SET_STATIC_VERTEX_SHADER_COMBO( SFM, bSFM );
  984. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha );
  985. SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  986. SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert );
  987. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  988. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase );
  989. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail );
  990. SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) );
  991. SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal );
  992. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  993. SET_STATIC_VERTEX_SHADER_COMBO( TREESWAY, bTreeSway ? nTreeSwayMode : 0 );
  994. SET_STATIC_VERTEX_SHADER_COMBO( CASCADED_SHADOW_MAPPING, 0 );
  995. SET_STATIC_VERTEX_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  996. SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 );
  997. DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 );
  998. SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
  999. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, bHasSelfIllumInEnvMapMask && !bHasFlashlight );
  1000. SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture );
  1001. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap );
  1002. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting );
  1003. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask && !bHasFlashlight && ( bHasEnvmap || bHasSelfIllumInEnvMapMask ) ); // Careful here if we do single-pass flashlight on PC someday
  1004. SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask && bHasEnvmap );
  1005. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPFRESNEL, bHasEnvMapFresnel && bHasEnvmap );
  1006. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum );
  1007. SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor );
  1008. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  1009. ClampDetailBlendModeAndWarn( nDetailBlendMode, 0, 9 );
  1010. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  1011. ClampDecalBlendModeAndWarn( nDecalBlendMode, 0, 1 );
  1012. SET_STATIC_PIXEL_SHADER_COMBO( DECAL_BLEND_MODE, bHasDecalTexture ? nDecalBlendMode : 2 );
  1013. SET_STATIC_PIXEL_SHADER_COMBO( TINTMASKTEXTURE, bHasTintMaskTexture );
  1014. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase );
  1015. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail );
  1016. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha );
  1017. SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail );
  1018. SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask );
  1019. SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline );
  1020. SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow );
  1021. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  1022. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  1023. SET_STATIC_PIXEL_SHADER_COMBO( DESATURATEWITHBASEALPHA, bDesaturateWithBaseAlpha );
  1024. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, 0 /*nLightingPreviewMode*/ );
  1025. SET_STATIC_PIXEL_SHADER_COMBO( CASCADED_SHADOW_MAPPING, g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup );
  1026. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, ( g_pHardwareConfig->SupportsCascadedShadowMapping() && !bSFM && !bHasFlashlight && !bDisableCSMLookup ) ? nCSMQualityComboValue : 0 );
  1027. SET_STATIC_PIXEL_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  1028. SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 );
  1029. }
  1030. #endif
  1031. }
  1032. if ( bHasFlashlight && !bSinglePassFlashlight )
  1033. {
  1034. pShader->FogToBlack();
  1035. }
  1036. else
  1037. {
  1038. pShader->DefaultFog();
  1039. }
  1040. // HACK HACK HACK - enable alpha writes all the time so that we have them for
  1041. // underwater stuff
  1042. pShaderShadow->EnableAlphaWrites( bFullyOpaque );
  1043. if ( IS_FLAG_SET( MATERIAL_VAR_MULTIPLY ) )
  1044. {
  1045. pShader->EnableAlphaBlending( SHADER_BLEND_ZERO, SHADER_BLEND_SRC_COLOR );
  1046. }
  1047. }
  1048. if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) )
  1049. {
  1050. if ( !pContextData ) // make sure allocated
  1051. {
  1052. pContextData = new CVertexLitGeneric_DX9_Context;
  1053. *pContextDataPtr = pContextData;
  1054. }
  1055. pContextData->m_bMaterialVarsChanged = false;
  1056. pContextData->m_SemiStaticCmdsOut.Reset();
  1057. #ifndef _PS3
  1058. pContextData->m_SemiStaticCmdsOut.SetPixelShaderFogParams( 21 );
  1059. #endif
  1060. #ifdef _PS3
  1061. pContextData->m_flashlightECB.Reset();
  1062. #endif
  1063. bool bSampler0SrgbRead = false;
  1064. if ( bHasBaseTexture )
  1065. {
  1066. if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) )
  1067. bSampler0SrgbRead = false;
  1068. else
  1069. bSampler0SrgbRead = !bShaderSrgbRead;
  1070. }
  1071. if ( bHasBaseTexture )
  1072. {
  1073. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, bSampler0SrgbRead ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, info.m_nBaseTexture, info.m_nBaseTextureFrame );
  1074. }
  1075. else
  1076. {
  1077. if( bHasEnvmap )
  1078. {
  1079. // if we only have an envmap (no basetexture), then we want the albedo to be black.
  1080. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_NONE, TEXTURE_BLACK );
  1081. }
  1082. else
  1083. {
  1084. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_NONE, TEXTURE_WHITE );
  1085. }
  1086. }
  1087. if ( bHasDetailTexture )
  1088. {
  1089. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, IsSRGBDetailTexture( nDetailBlendMode ) ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, info.m_nDetail, info.m_nDetailFrame );
  1090. }
  1091. if ( bHasSelfIllum )
  1092. {
  1093. if ( bHasSelfIllumMask ) // Separate texture for self illum?
  1094. {
  1095. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, TEXTURE_BINDFLAGS_NONE, info.m_nSelfIllumMask, -1 ); // Bind it
  1096. }
  1097. else // else
  1098. {
  1099. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, TEXTURE_BINDFLAGS_NONE, TEXTURE_BLACK ); // Bind dummy
  1100. }
  1101. }
  1102. if ( bHasDecalTexture )
  1103. {
  1104. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, IsSRGBDecalTexture( nDetailBlendMode ) ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, info.m_nDecalTexture );
  1105. }
  1106. if ( bHasTintMaskTexture )
  1107. {
  1108. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER13, TEXTURE_BINDFLAGS_SRGBREAD, info.m_nTintMaskTexture );
  1109. }
  1110. if ( bSeamlessDetail || bSeamlessBase )
  1111. {
  1112. float flSeamlessData[4] = { params[info.m_nSeamlessScale]->GetFloatValue(), 0, 0, 0 };
  1113. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, flSeamlessData );
  1114. }
  1115. if ( bTreeSway )
  1116. {
  1117. float flParams[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1118. flParams[0] = GetFloatParam( info.m_nTreeSwaySpeedHighWindMultiplier, params, 2.0f );
  1119. flParams[1] = GetFloatParam( info.m_nTreeSwayScrumbleFalloffExp, params, 1.0f );
  1120. flParams[2] = GetFloatParam( info.m_nTreeSwayFalloffExp, params, 1.0f );
  1121. flParams[3] = GetFloatParam( info.m_nTreeSwayScrumbleSpeed, params, 3.0f );
  1122. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, flParams );
  1123. }
  1124. if ( info.m_nBaseTextureTransform != -1 )
  1125. {
  1126. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
  1127. }
  1128. if ( bHasBump && ( info.m_nBumpTransform != -1 ) )
  1129. {
  1130. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform );
  1131. }
  1132. int nLightingPreviewMode = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
  1133. nLightingPreviewMode = clamp( nLightingPreviewMode, 0, 1 );
  1134. if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() )
  1135. {
  1136. float vEyeDir[4];
  1137. ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraDirection( vEyeDir );
  1138. float flFarZ = ShaderApiFast( pShaderAPI )->GetFarZ();
  1139. vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm
  1140. vEyeDir[1] /= flFarZ;
  1141. vEyeDir[2] /= flFarZ;
  1142. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( 26, vEyeDir ); // Needed for SSAO
  1143. }
  1144. if ( bHasDetailTexture )
  1145. {
  1146. if ( !bTreeSway )
  1147. {
  1148. if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) )
  1149. {
  1150. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nDetailTextureTransform, info.m_nDetailScale );
  1151. }
  1152. else
  1153. {
  1154. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBaseTextureTransform, info.m_nDetailScale );
  1155. }
  1156. }
  1157. //Assert( !bHasBump );
  1158. if ( info.m_nDetailTint != -1 )
  1159. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint );
  1160. else
  1161. {
  1162. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 10, 1, 1, 1, 1 );
  1163. }
  1164. }
  1165. if ( bTreeSway )
  1166. {
  1167. float32 flParams[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1168. flParams[0] = GetFloatParam( info.m_nTreeSwaySpeedLerpStart, params, 3.0f );
  1169. flParams[1] = GetFloatParam( info.m_nTreeSwaySpeedLerpEnd, params, 6.0f );
  1170. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flParams );
  1171. }
  1172. if ( bDistanceAlpha )
  1173. {
  1174. float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params );
  1175. float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params );
  1176. // set all line art shader parms
  1177. bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params );
  1178. bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params );
  1179. float flResScale = 1.0;
  1180. float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params );
  1181. float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params );
  1182. float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params );
  1183. float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params );
  1184. if ( bScaleEdges || bScaleOutline )
  1185. {
  1186. int nWidth, nHeight;
  1187. ShaderApiFast( pShaderAPI )->GetBackBufferDimensions( nWidth, nHeight );
  1188. flResScale=MAX( 0.5, MAX( 1024.0/nWidth, 768/nHeight ) );
  1189. if ( bScaleEdges )
  1190. {
  1191. float flMid = 0.5 * ( flSoftStart + flSoftEnd );
  1192. flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 );
  1193. flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 );
  1194. }
  1195. if ( bScaleOutline )
  1196. {
  1197. // shrink the soft part of the outline, enlarging hard part
  1198. float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 );
  1199. flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 );
  1200. float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 );
  1201. flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 );
  1202. }
  1203. }
  1204. float flConsts[]={
  1205. // c5 - glow values
  1206. GetFloatParam( info.m_nGlowX, params ),
  1207. GetFloatParam( info.m_nGlowY, params ),
  1208. GetFloatParam( info.m_nGlowStart, params ),
  1209. GetFloatParam( info.m_nGlowEnd, params ),
  1210. // c6 - glow color
  1211. 0,0,0, // will be filled in
  1212. GetFloatParam( info.m_nGlowAlpha, params ),
  1213. // c7 - mask range parms and basealphaenvmapmask scale and bias
  1214. flSoftStart,
  1215. flSoftEnd,
  1216. 0,0, // filled in below
  1217. // c8 - outline color
  1218. 0,0,0,
  1219. GetFloatParam( info.m_nOutlineAlpha, params ),
  1220. // c9 - outline parms
  1221. flOutlineStart0,
  1222. flOutlineStart1,
  1223. flOutlineEnd0,
  1224. flOutlineEnd1,
  1225. };
  1226. if ( info.m_nGlowColor != -1 )
  1227. {
  1228. params[info.m_nGlowColor]->GetVecValue( flConsts+4, 3 );
  1229. }
  1230. if ( info.m_nOutlineColor != -1 )
  1231. {
  1232. params[info.m_nOutlineColor]->GetVecValue( flConsts+12, 3 );
  1233. }
  1234. if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 )
  1235. {
  1236. flConsts[10] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[0];
  1237. flConsts[11] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[1] - flConsts[10];
  1238. }
  1239. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, flConsts, 5 );
  1240. }
  1241. else if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 )
  1242. {
  1243. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1244. flConsts[2] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[0];
  1245. flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[1] - flConsts[2];
  1246. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, flConsts, 1 );
  1247. }
  1248. if ( !g_pConfig->m_bFastNoBump )
  1249. {
  1250. if ( bHasBump )
  1251. {
  1252. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, info.m_nBumpmap, info.m_nBumpFrame );
  1253. }
  1254. else if ( bHasDiffuseWarp )
  1255. {
  1256. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  1257. }
  1258. }
  1259. else
  1260. {
  1261. if ( bHasBump )
  1262. {
  1263. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  1264. }
  1265. }
  1266. // Setting w to 1 means use separate selfillummask
  1267. float vEnvMapSaturation_SelfIllumMask[4] = {1.0f, 1.0f, 1.0f, 0.0f};
  1268. if ( info.m_nEnvmapSaturation != -1 )
  1269. params[info.m_nEnvmapSaturation]->GetVecValue( vEnvMapSaturation_SelfIllumMask, 3 );
  1270. vEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f;
  1271. if ( bHasBump )
  1272. {
  1273. // Bump version of the shader doesn't use self illum mask. Use w to store decal texture multiplier instead to support mod2x decal texture blending.
  1274. vEnvMapSaturation_SelfIllumMask[ 3 ] = ( nDecalBlendMode == 2 ) ? 2.0f : 1.0f;
  1275. }
  1276. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, vEnvMapSaturation_SelfIllumMask, 1 );
  1277. if ( bHasEnvmap )
  1278. {
  1279. pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, info.m_nEnvmapTint, fSinglePassFlashlight );
  1280. }
  1281. else
  1282. {
  1283. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 0, 0.0f, 0.0f, 0.0f, fSinglePassFlashlight );
  1284. }
  1285. bool bHasEnvmapMask = (!bHasFlashlight || bSinglePassFlashlight ) && ( info.m_nEnvmapMask != -1 ) && params[info.m_nEnvmapMask]->IsTexture();
  1286. if ( bHasEnvmapMask )
  1287. {
  1288. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame );
  1289. }
  1290. bool bHasEnvMapFresnel = bHasEnvmap && IsBoolSet( info.m_nEnvmapFresnel, params );
  1291. if ( bHasEnvMapFresnel )
  1292. {
  1293. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1294. params[ info.m_nEnvMapFresnelMinMaxExp ]->GetVecValue( flConsts, 3 );
  1295. flConsts[1] -= flConsts[0]; // convert max fresnel into scale factor
  1296. if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 )
  1297. {
  1298. flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[2]; // basealphaenvmapmask exponent in w
  1299. }
  1300. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 13, flConsts, 1 );
  1301. }
  1302. else if ( info.m_nBaseAlphaEnvMapMaskMinMaxExp != -1 )
  1303. {
  1304. // still need to set exponent for basealphaenvmapmask
  1305. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1306. flConsts[3] = params[ info.m_nBaseAlphaEnvMapMaskMinMaxExp ]->GetVecValue()[2]; // basealphaenvmapmask exponent in w
  1307. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 13, flConsts, 1 );
  1308. }
  1309. bool bHasSelfIllumFresnel = ( !bHasDetailTexture ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 );
  1310. if ( bHasSelfIllumFresnel && (!bHasFlashlight || bSinglePassFlashlight) )
  1311. {
  1312. float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
  1313. float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f;
  1314. float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f;
  1315. float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f;
  1316. vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias
  1317. vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale
  1318. vConstScaleBiasExp[2] = flExp; // Exp
  1319. vConstScaleBiasExp[3] = flMax; // Brightness
  1320. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vConstScaleBiasExp );
  1321. }
  1322. else
  1323. {
  1324. float vSelfIllumScale[4];
  1325. vSelfIllumScale[0] = IS_PARAM_DEFINED( info.m_nSelfIllumMaskScale ) ? params[info.m_nSelfIllumMaskScale]->GetFloatValue() : 1.0f;
  1326. vSelfIllumScale[ 1 ] = bIsDecal ? 1.0f : 0.0f;
  1327. vSelfIllumScale[2] = vSelfIllumScale[3] = 0.0f;
  1328. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vSelfIllumScale );
  1329. }
  1330. // store eye pos in shader constant 20
  1331. float flEyeW = pShader->TextureIsTranslucent( BASETEXTURE, true ) ? 1.0f : 0.0f;
  1332. pContextData->m_SemiStaticCmdsOut.StoreEyePosInPixelShaderConstant( 20, flEyeW );
  1333. if( bHasDiffuseWarp && (!bHasFlashlight || bSinglePassFlashlight) && !bHasSelfIllumFresnel )
  1334. {
  1335. if ( r_lightwarpidentity.GetBool() )
  1336. {
  1337. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, TEXTURE_IDENTITY_LIGHTWARP );
  1338. }
  1339. else
  1340. {
  1341. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, info.m_nDiffuseWarpTexture, -1 );
  1342. }
  1343. }
  1344. if ( bHasFlashlight )
  1345. {
  1346. #ifdef _PS3
  1347. {
  1348. pContextData->m_flashlightECB.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 );
  1349. }
  1350. #endif
  1351. if( IsX360() || !bHasBump )
  1352. {
  1353. pContextData->m_SemiStaticCmdsOut.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 );
  1354. }
  1355. CBCmdSetPixelShaderFlashlightState_t state;
  1356. state.m_LightSampler = SHADER_SAMPLER7;
  1357. state.m_DepthSampler = SHADER_SAMPLER8;
  1358. state.m_ShadowNoiseSampler = SHADER_SAMPLER6;
  1359. state.m_nColorConstant = 28;
  1360. state.m_nAttenConstant = 22;
  1361. state.m_nOriginConstant = 23;
  1362. state.m_nDepthTweakConstant = 2;
  1363. state.m_nScreenScaleConstant = 31;
  1364. state.m_nWorldToTextureConstant = ( IsX360() || IsPS3() ) ? -1 : 24;
  1365. state.m_bFlashlightNoLambert = bFlashlightNoLambert;
  1366. state.m_bSinglePassFlashlight = bSinglePassFlashlight;
  1367. #ifdef _PS3
  1368. {
  1369. pContextData->m_flashlightECB.SetPixelShaderFlashlightState( state );
  1370. pContextData->m_flashlightECB.End();
  1371. }
  1372. #else
  1373. {
  1374. pContextData->m_SemiStaticCmdsOut.SetPixelShaderFlashlightState( state );
  1375. }
  1376. #endif
  1377. if ( !( IsX360() || IsPS3() ) && ( g_pHardwareConfig->GetDXSupportLevel() > 92 ) )
  1378. {
  1379. pContextData->m_SemiStaticCmdsOut.SetPixelShaderUberLightState(
  1380. PSREG_UBERLIGHT_SMOOTH_EDGE_0, PSREG_UBERLIGHT_SMOOTH_EDGE_1,
  1381. PSREG_UBERLIGHT_SMOOTH_EDGE_OOW, PSREG_UBERLIGHT_SHEAR_ROUND,
  1382. PSREG_UBERLIGHT_AABB, PSREG_UBERLIGHT_WORLD_TO_LIGHT );
  1383. }
  1384. }
  1385. if ( bHasEnvmap && ( !bHasFlashlight || IsGameConsole() ) )
  1386. {
  1387. // This was shader reg 2, but this was conflicting with the flashlight state and we somehow never noticed it.
  1388. // fvEnvmapParams are contrast, lightscale, lightscale min, lightscale max
  1389. // If contrast is less than 0 it's invalid, but the shader is expecting something, so just set 1.0 (specular squared, the darkest).
  1390. float envMapParams[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
  1391. if ( info.m_nEnvmapContrast > 0 )
  1392. {
  1393. // The shader is expecting something, so just set 1.0 (specular squared, the darkest).
  1394. envMapParams[0] = GetFloatParam( info.m_nEnvmapContrast, params );
  1395. }
  1396. /* The following (envmapparmas[1,2,3] are no longer used (c19.yzw) in the bump shader so we're hijacking them for the CSM light color
  1397. They're the only free constants for OSX/ps2b in that PS */
  1398. if ( info.m_nEnvMapLightScale != -1 )
  1399. {
  1400. envMapParams[1] = GetFloatParam( info.m_nEnvMapLightScale, params );
  1401. }
  1402. if ( info.m_nEnvMapLightScaleMinMax != -1 )
  1403. {
  1404. float lightScaleMinMax[2] = { 0.0, 0.0 };
  1405. params[info.m_nEnvMapLightScaleMinMax]->GetVecValue( lightScaleMinMax, 2 );
  1406. envMapParams[2] = lightScaleMinMax[0];
  1407. envMapParams[3] = lightScaleMinMax[1] + lightScaleMinMax[0];
  1408. }
  1409. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 19, envMapParams );
  1410. }
  1411. // mat_fullbright 2 handling
  1412. bool bLightingOnly = bVertexLitGeneric && g_pConfig->nFullbright == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  1413. if( bLightingOnly )
  1414. {
  1415. if ( bHasBaseTexture )
  1416. {
  1417. if( ( bHasSelfIllum && !bHasSelfIllumInEnvMapMask ) )
  1418. {
  1419. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, bSampler0SrgbRead ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, TEXTURE_GREY_ALPHA_ZERO );
  1420. }
  1421. else
  1422. {
  1423. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, bSampler0SrgbRead ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, TEXTURE_GREY );
  1424. }
  1425. }
  1426. if ( bHasDetailTexture )
  1427. {
  1428. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, IsSRGBDetailTexture( nDetailBlendMode ) ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, TEXTURE_GREY );
  1429. }
  1430. if ( bHasDecalTexture )
  1431. {
  1432. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, IsSRGBDecalTexture( nDecalBlendMode ) ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, TEXTURE_GREY );
  1433. }
  1434. if ( bHasTintMaskTexture )
  1435. {
  1436. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER13, TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_GREY );
  1437. }
  1438. }
  1439. if ( bHasBump || bHasDiffuseWarp )
  1440. {
  1441. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
  1442. }
  1443. if ( bTreeSway )
  1444. {
  1445. float flParams[4];
  1446. flParams[0] = GetFloatParam( info.m_nTreeSwayHeight, params, 1000.0f );
  1447. flParams[1] = GetFloatParam( info.m_nTreeSwayStartHeight, params, 0.1f );
  1448. flParams[2] = GetFloatParam( info.m_nTreeSwayRadius, params, 300.0f );
  1449. flParams[3] = GetFloatParam( info.m_nTreeSwayStartRadius, params, 0.2f );
  1450. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, flParams );
  1451. flParams[0] = GetFloatParam( info.m_nTreeSwaySpeed, params, 1.0f );
  1452. flParams[1] = GetFloatParam( info.m_nTreeSwayStrength, params, 10.0f );
  1453. flParams[2] = GetFloatParam( info.m_nTreeSwayScrumbleFrequency, params, 12.0f );
  1454. flParams[3] = GetFloatParam( info.m_nTreeSwayScrumbleStrength, params, 10.0f );
  1455. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, flParams );
  1456. }
  1457. if ( bVertexLitGeneric )
  1458. {
  1459. if ( bDesaturateWithBaseAlpha )
  1460. {
  1461. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nDesaturateWithBaseAlpha, fBlendFactor );
  1462. }
  1463. else
  1464. {
  1465. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nSelfIllumTint, fBlendFactor );
  1466. }
  1467. }
  1468. else
  1469. {
  1470. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 4, 1.0f, 1.0f, 1.0f, fBlendFactor );
  1471. }
  1472. pContextData->m_SemiStaticCmdsOut.End();
  1473. }
  1474. }
  1475. if ( pShaderAPI )
  1476. {
  1477. #ifdef _PS3
  1478. CCommandBufferBuilder< CDynamicCommandStorageBuffer > DynamicCmdsOut;
  1479. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_SemiStaticCmdsOut.Base() );
  1480. if (bHasFlashlight) ShaderApiFast( pShaderAPI )->ExecuteCommandBufferPPU( pContextData->m_flashlightECB.Base() );
  1481. #else
  1482. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  1483. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  1484. #endif
  1485. if ( bHasEnvmap )
  1486. {
  1487. bool bHdr = ( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE );
  1488. DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER1, bHdr ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, info.m_nEnvmap, info.m_nEnvmapFrame );
  1489. }
  1490. bool bFlashlightShadows = false;
  1491. bool bUberlight = false;
  1492. if ( bHasFlashlight )
  1493. {
  1494. ShaderApiFast( pShaderAPI )->GetFlashlightShaderInfo( &bFlashlightShadows, &bUberlight );
  1495. if ( g_pHardwareConfig->GetDXSupportLevel() <= 92 )
  1496. {
  1497. bUberlight = false;
  1498. }
  1499. }
  1500. // Set up light combo state
  1501. LightState_t lightState = {0, false, false};
  1502. if ( bVertexLitGeneric && (!bHasFlashlight || bSinglePassFlashlight) )
  1503. {
  1504. ShaderApiFast( pShaderAPI )->GetDX9LightState( &lightState );
  1505. }
  1506. MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
  1507. int numBones = ShaderApiFast( pShaderAPI )->GetCurrentNumBones();
  1508. bool bWriteDepthToAlpha;
  1509. bool bWriteWaterFogToAlpha;
  1510. if( bFullyOpaque )
  1511. {
  1512. bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
  1513. bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
  1514. AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
  1515. }
  1516. else
  1517. {
  1518. //can't write a special value to dest alpha if we're actually using as-intended alpha
  1519. bWriteDepthToAlpha = false;
  1520. bWriteWaterFogToAlpha = false;
  1521. }
  1522. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  1523. bool bWorldNormal = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH;
  1524. TessellationMode_t nTessellationMode = ( bSFM && g_pHardwareConfig->HasFastVertexTextures() ) ? ShaderApiFast( pShaderAPI )->GetTessellationMode() : TESSELLATION_MODE_DISABLED;
  1525. if ( nTessellationMode != TESSELLATION_MODE_DISABLED )
  1526. {
  1527. ShaderApiFast( pShaderAPI )->BindStandardVertexTexture( SHADER_VERTEXTEXTURE_SAMPLER1, TEXTURE_SUBDIVISION_PATCHES );
  1528. float vSubDDimensions[4] = { 1.0f/ShaderApiFast( pShaderAPI )->GetSubDHeight(), bHasDisplacement && mat_displacementmap.GetBool() ? 1.0f : 0.0f, 0.0f, 0.0f };
  1529. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vSubDDimensions );
  1530. if( bHasDisplacement )
  1531. {
  1532. pShader->BindVertexTexture( SHADER_VERTEXTEXTURE_SAMPLER2, info.m_nDisplacementMap );
  1533. }
  1534. else
  1535. {
  1536. ShaderApiFast( pShaderAPI )->BindStandardVertexTexture( SHADER_VERTEXTEXTURE_SAMPLER2, TEXTURE_BLACK );
  1537. }
  1538. // Currently, tessellation is mutually exclusive with any kind of GPU-side skinning, morphing or vertex compression
  1539. Assert( !ShaderApiFast( pShaderAPI )->IsHWMorphingEnabled() );
  1540. Assert( numBones == 0 );
  1541. Assert( vertexCompression == 0);
  1542. // Also mutually exclusive with these in the non-bump case:
  1543. //$STATICLIGHT3 || $VERTEXCOLOR || $SEAMLESS_BASE || $SEAMLESS_DETAIL || $SEPARATE_DETAIL_UVS
  1544. }
  1545. #endif
  1546. int nLightingPreviewMode = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
  1547. nLightingPreviewMode = clamp( nLightingPreviewMode, 0, 1 );
  1548. if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() )
  1549. {
  1550. float vEyeDir[4];
  1551. ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraDirection( vEyeDir );
  1552. float flFarZ = ShaderApiFast( pShaderAPI )->GetFarZ();
  1553. vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm
  1554. vEyeDir[1] /= flFarZ;
  1555. vEyeDir[2] /= flFarZ;
  1556. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( 26, vEyeDir );
  1557. }
  1558. else if ( !bHasBump )
  1559. {
  1560. ITexture *pDepthTextureAtlas = NULL;
  1561. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1562. float vConst[ 4 ] = { lightState.m_bStaticLight ? 1.0f : 0.0f, cascadeState.m_vLightColor.x, cascadeState.m_vLightColor.y, cascadeState.m_vLightColor.z };
  1563. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vConst );
  1564. }
  1565. bool bBlendWithSmokeGrenade = IsBoolSet( info.m_nBlendWithSmokeGrenade, params );
  1566. if ( bBlendWithSmokeGrenade )
  1567. {
  1568. //float vSmokeGrenadePosEntity[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1569. //params[ info.m_nBlendWithSmokeGrenadePosEntity ]->GetVecValue( vSmokeGrenadePosEntity, 3 );
  1570. float vSmokeGrenadePosSmoke[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1571. params[ info.m_nBlendWithSmokeGrenadePosSmoke ]->GetVecValue( vSmokeGrenadePosSmoke, 3 );
  1572. if ( vSmokeGrenadePosSmoke[0] == 0 && vSmokeGrenadePosSmoke[1] == 0 && vSmokeGrenadePosSmoke[2] == 0 )
  1573. {
  1574. bBlendWithSmokeGrenade = false;
  1575. }
  1576. else
  1577. {
  1578. DynamicCmdsOut.SetPixelShaderConstant( 6, vSmokeGrenadePosSmoke, 1 );
  1579. }
  1580. //float vSmokeDistanceRelativeToEntity[4] = {
  1581. // vSmokeGrenadePosEntity[0] - vSmokeGrenadePosSmoke[0],
  1582. // vSmokeGrenadePosEntity[1] - vSmokeGrenadePosSmoke[1],
  1583. // vSmokeGrenadePosEntity[2] - vSmokeGrenadePosSmoke[2],
  1584. // 0 };
  1585. //DynamicCmdsOut.SetPixelShaderConstant( 13, vSmokeDistanceRelativeToEntity, 1 ); //bashing g_FresnelConstants?
  1586. }
  1587. bool bStaticLight3Streams = (r_staticlight_streams.GetInt() == 3) && (!(bHasVertexColor || bHasVertexAlpha));
  1588. if ( bHasBump || bHasDiffuseWarp )
  1589. {
  1590. bool bCSMEnabled = pShaderAPI->IsCascadedShadowMapping() && !bHasFlashlight && !bSFM && !bDisableCSMLookup;
  1591. if ( ( !( IsGameConsole() ) ) &&
  1592. ( !bSupportsSM3 || ToolsEnabled() ) )
  1593. {
  1594. bCSMEnabled = false;
  1595. }
  1596. bool bStaticLight3 = lightState.m_bStaticLight && bStaticLight3Streams;
  1597. int32 nStaticLightVsCombo = bStaticLight3 ? ( !r_staticlight_streams_indirect_only.GetBool() ? 2 : 1 ) : 0;
  1598. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  1599. if ( !bSupportsSM3 )
  1600. #endif
  1601. {
  1602. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 );
  1603. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
  1604. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  1605. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, 0 );
  1606. SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : ( lightState.m_nNumLights ) );
  1607. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, nStaticLightVsCombo );
  1608. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_vs20 );
  1609. // Bind ps_2_b shader so we can get shadow mapping...
  1610. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send OpenGL this way
  1611. {
  1612. if ( bCSMEnabled )
  1613. {
  1614. ITexture *pDepthTextureAtlas = NULL;
  1615. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1616. if ( pDepthTextureAtlas )
  1617. {
  1618. //DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1619. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1620. }
  1621. else
  1622. {
  1623. bCSMEnabled = 0;
  1624. }
  1625. }
  1626. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b );
  1627. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, ( IsPS3() ) ? MIN( 2, lightState.m_nNumLights ) : lightState.m_nNumLights );
  1628. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight && !bStaticLight3 );
  1629. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  1630. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1631. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, ( IsGameConsole() ) ? ( bCSMEnabled ? 1 : 0 ) : 0 );
  1632. SET_DYNAMIC_PIXEL_SHADER_COMBO( STATICLIGHT3, bStaticLight3 );
  1633. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20b );
  1634. }
  1635. else
  1636. {
  1637. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 );
  1638. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  1639. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight && !bStaticLight3 );
  1640. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1641. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, 0 );
  1642. SET_DYNAMIC_PIXEL_SHADER_COMBO( STATICLIGHT3, bStaticLight3 );
  1643. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20 );
  1644. }
  1645. }
  1646. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  1647. else
  1648. {
  1649. if ( bMorphing )
  1650. {
  1651. pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 );
  1652. }
  1653. if ( bCSMEnabled )
  1654. {
  1655. ITexture *pDepthTextureAtlas = NULL;
  1656. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1657. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1658. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1659. }
  1660. BOOL bCSMEnabledBool = bCSMEnabled;
  1661. pShaderAPI->SetBooleanPixelShaderConstant( 0, &bCSMEnabledBool, 1 );
  1662. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  1663. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, ( numBones > 0 ) && ( nTessellationMode == TESSELLATION_MODE_DISABLED ) );
  1664. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression && ( nTessellationMode == TESSELLATION_MODE_DISABLED ) );
  1665. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, nTessellationMode );
  1666. //SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, bMorphing );
  1667. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, nStaticLightVsCombo );
  1668. SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  1669. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 );
  1670. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, bWorldNormal ? 0 : lightState.m_nNumLights );
  1671. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, bWorldNormal ? false : ( lightState.m_bAmbientLight && !bStaticLight3 ) );
  1672. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bWorldNormal ? 0 : bFlashlightShadows );
  1673. SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, bUberlight && bSFM );
  1674. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1675. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, 0 );
  1676. SET_DYNAMIC_PIXEL_SHADER_COMBO( STATICLIGHT3, bStaticLight3 );
  1677. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps30 );
  1678. bool bUnusedTexCoords[3] = { false, false, !ShaderApiFast( pShaderAPI )->IsHWMorphingEnabled() || !bIsDecal };
  1679. ShaderApiFast( pShaderAPI )->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords );
  1680. }
  1681. #endif
  1682. }
  1683. else // !( bHasBump || bHasDiffuseWarp )
  1684. {
  1685. if ( bAmbientOnly ) // Override selected light combo to be ambient only
  1686. {
  1687. lightState.m_bAmbientLight = true;
  1688. lightState.m_bStaticLight = false;
  1689. lightState.m_nNumLights = 0;
  1690. }
  1691. bool bCSMEnabled = pShaderAPI->IsCascadedShadowMapping() && !bHasFlashlight && !bSFM && !bDisableCSMLookup;
  1692. if ( ( !( IsGameConsole() ) ) &&
  1693. ( !bSupportsSM3 || ToolsEnabled() ) )
  1694. {
  1695. bCSMEnabled = false;
  1696. }
  1697. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  1698. if ( !bSupportsSM3 )
  1699. #endif
  1700. {
  1701. int staticLight3VSCombo = (lightState.m_bStaticLight && bStaticLight3Streams) ? ( ( lightState.m_bStaticLightIndirectOnly )? 2 : 1) : 0;
  1702. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 );
  1703. SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
  1704. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, staticLight3VSCombo );
  1705. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
  1706. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  1707. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, 0 );
  1708. SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights );
  1709. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs20 );
  1710. // Bind ps_2_b shader so we can get shadow mapping
  1711. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send OpenGL this way
  1712. {
  1713. if ( bCSMEnabled )
  1714. {
  1715. ITexture *pDepthTextureAtlas = NULL;
  1716. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1717. if (pDepthTextureAtlas)
  1718. {
  1719. //DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1720. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1721. }
  1722. else
  1723. {
  1724. bCSMEnabled = 0;
  1725. }
  1726. }
  1727. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b );
  1728. SET_DYNAMIC_PIXEL_SHADER_COMBO( SMOKEGRENADEBLEND, bBlendWithSmokeGrenade );
  1729. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  1730. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1731. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, ( IsGameConsole() ) ? ( bCSMEnabled ? 1 : 0 ) : 0 );
  1732. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20b );
  1733. }
  1734. else
  1735. {
  1736. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 );
  1737. SET_DYNAMIC_PIXEL_SHADER_COMBO( SMOKEGRENADEBLEND, bBlendWithSmokeGrenade );
  1738. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1739. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, 0 );
  1740. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20 );
  1741. }
  1742. }
  1743. #if !defined( _GAMECONSOLE ) && !defined( _PS3 )
  1744. else
  1745. {
  1746. if ( bMorphing )
  1747. {
  1748. pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 );
  1749. }
  1750. if ( bWorldNormal && IsPC() )
  1751. {
  1752. float vEyeDir[4];
  1753. ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraDirection( vEyeDir );
  1754. float flFarZ = ShaderApiFast( pShaderAPI )->GetFarZ();
  1755. vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm
  1756. vEyeDir[1] /= flFarZ;
  1757. vEyeDir[2] /= flFarZ;
  1758. DynamicCmdsOut.SetVertexShaderConstant( 26, vEyeDir );
  1759. }
  1760. if ( bCSMEnabled )
  1761. {
  1762. ITexture *pDepthTextureAtlas = NULL;
  1763. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1764. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1765. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1766. }
  1767. if ( !( IsGameConsole() ) )
  1768. {
  1769. BOOL bCSMEnabledBool = bCSMEnabled;
  1770. pShaderAPI->SetBooleanPixelShaderConstant( 0, &bCSMEnabledBool, 1 );
  1771. }
  1772. int staticLight3VSCombo = ( lightState.m_bStaticLight && bStaticLight3Streams ) ? ( ( lightState.m_bStaticLightIndirectOnly ) ? 2 : 1 ) : 0;
  1773. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 );
  1774. SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
  1775. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, staticLight3VSCombo );
  1776. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, ( numBones > 0 ) && ( nTessellationMode == TESSELLATION_MODE_DISABLED ) );
  1777. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression && ( nTessellationMode == TESSELLATION_MODE_DISABLED ) );
  1778. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, nTessellationMode );
  1779. //SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, bMorphing );
  1780. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs30 );
  1781. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 );
  1782. SET_DYNAMIC_PIXEL_SHADER_COMBO( SMOKEGRENADEBLEND, bBlendWithSmokeGrenade );
  1783. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bWorldNormal ? 0 : bFlashlightShadows );
  1784. SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, bUberlight && bSFM );
  1785. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1786. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, IsGameConsole() ? ( bCSMEnabled ? 1 : 0 ) : 0 );
  1787. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps30 );
  1788. bool bUnusedTexCoords[3] = { false, false, !bMorphing || !bIsDecal };
  1789. ShaderApiFast( pShaderAPI )->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords );
  1790. }
  1791. #endif
  1792. }
  1793. if ( bHasBump || bHasDiffuseWarp )
  1794. {
  1795. ITexture *pDepthTextureAtlas = NULL;
  1796. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1797. DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, &cascadeState.m_vLightColor.x );
  1798. }
  1799. if ( !bHasBump || bTreeSway )
  1800. {
  1801. float fTempConst[4];
  1802. fTempConst[0] = fSinglePassFlashlight;
  1803. fTempConst[1] = ShaderApiFast( pShaderAPI )->CurrentTime();
  1804. Vector windDir = IsBoolSet( info.m_nTreeSwayStatic, params ) ? Vector(0.5f,0.5f,0) : pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_WIND_DIRECTION );
  1805. fTempConst[2] = windDir.x;
  1806. fTempConst[3] = windDir.y;
  1807. DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, fTempConst );
  1808. }
  1809. float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1.0f : 0.0f;
  1810. float fWriteWaterFogToDestAlpha = bWriteWaterFogToAlpha ? 1.0f : 0.0f;
  1811. float fVertexAlpha = bHasVertexAlpha ? 1.0f : 0.0f;
  1812. float fBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) ? 1.0f : 0.0f;
  1813. fBlendTintByBaseAlpha = bHasTintMaskTexture ? 1.0f : fBlendTintByBaseAlpha; // This is needed to make the shader math work out in the tint texture case
  1814. // Controls for lerp-style paths through shader code (used by bump and non-bump)
  1815. float vShaderControls[4] = { IsBoolSet( info.m_nNoTint, params ) ? -1.0f : ( 1.0f - fBlendTintByBaseAlpha ), fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha };
  1816. if ( bHasBump )
  1817. {
  1818. // Bump shader doesn't use vertex alpha
  1819. vShaderControls[ 3 ] = GetIntParam( info.m_nEnvMapMaskInTintMaskTexture, params, 0 ) ? 1.0f : 0.0f;
  1820. }
  1821. else
  1822. {
  1823. // Nonbump shader doesn't use water fog dest alpha thing.
  1824. vShaderControls[ 2 ] = GetIntParam( info.m_nEnvMapMaskInTintMaskTexture, params, 0 ) ? 1.0f : 0.0f;
  1825. }
  1826. DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 );
  1827. /* Time - used for debugging
  1828. float vTimeConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1829. float flTime = pShaderAPI->CurrentTime();
  1830. vTimeConst[0] = flTime;
  1831. DynamicCmdsOut.SetPixelShaderConstant( 25, vTimeConst, 1 );
  1832. //*/
  1833. DynamicCmdsOut.End();
  1834. #ifdef _PS3
  1835. ShaderApiFast( pShaderAPI )->SetPixelShaderFogParams( 21 );
  1836. #endif
  1837. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  1838. }
  1839. pShader->Draw();
  1840. }
  1841. void DrawVertexLitGeneric_DX9_Internal_ExecuteFastPath( int *vsDynIndex, int *psDynIndex,
  1842. CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI * pShaderAPI,
  1843. VertexLitGeneric_DX9_Vars_t &info,
  1844. VertexCompressionType_t vertexCompression,
  1845. CBasePerMaterialContextData **pContextDataPtr, BOOL bCSMEnabled, BOOL bVertexLitGeneric )
  1846. {
  1847. CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr );
  1848. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  1849. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  1850. bool bHasEnvmap = (info.m_nEnvmap) != -1 && (params[info.m_nEnvmap]->IsTexture());
  1851. if ( bHasEnvmap )
  1852. {
  1853. DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, info.m_nEnvmap, info.m_nEnvmapFrame );
  1854. }
  1855. DynamicCmdsOut.End();
  1856. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  1857. // Set up light combo state
  1858. LightState_t lightState = {0, false, false};
  1859. ShaderApiFast( pShaderAPI )->GetDX9LightState( &lightState );
  1860. bool bHasBump = IsTextureSet( info.m_nBumpmap, params );
  1861. bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture();
  1862. if ( !bHasBump )
  1863. {
  1864. ITexture *pDepthTextureAtlas = NULL;
  1865. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1866. float vConst[ 4 ] = { lightState.m_bStaticLight ? 1.0f : 0.0f, cascadeState.m_vLightColor.x, cascadeState.m_vLightColor.y, cascadeState.m_vLightColor.z };
  1867. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vConst );
  1868. }
  1869. int numBones = ShaderApiFast( pShaderAPI )->GetCurrentNumBones();
  1870. int nDetailTranslucencyTexture = -1;
  1871. int nDetailBlendMode= GetIntParam( info.m_nDetailTextureCombineMode, params );
  1872. float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 );
  1873. bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params );
  1874. if ( bHasDetailTexture && ( fBlendFactor > 0.0 ) )
  1875. {
  1876. if ( ( nDetailBlendMode == DETAIL_BLEND_MODE_FADE ) ||
  1877. ( nDetailBlendMode == DETAIL_BLEND_MODE_MULTIPLY ) ||
  1878. ( nDetailBlendMode == DETAIL_BLEND_MODE_MASK_BASE_BY_DETAIL_ALPHA ) )
  1879. {
  1880. nDetailTranslucencyTexture = info.m_nDetail;
  1881. }
  1882. }
  1883. BlendType_t nBlendType;
  1884. bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params );
  1885. if ( bHasBaseTexture )
  1886. {
  1887. nBlendType = pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true, nDetailTranslucencyTexture );
  1888. }
  1889. else
  1890. {
  1891. nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false );
  1892. }
  1893. bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0;
  1894. bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested;
  1895. MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
  1896. bool bWriteDepthToAlpha;
  1897. bool bWriteWaterFogToAlpha;
  1898. if( bFullyOpaque )
  1899. {
  1900. bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
  1901. bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
  1902. }
  1903. else
  1904. {
  1905. //can't write a special value to dest alpha if we're actually using as-intended alpha
  1906. bWriteDepthToAlpha = false;
  1907. bWriteWaterFogToAlpha = false;
  1908. }
  1909. pShaderAPI->SetBooleanPixelShaderConstant( 0, &bCSMEnabled, 1 );
  1910. if ( bCSMEnabled )
  1911. {
  1912. ITexture *pDepthTextureAtlas = NULL;
  1913. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1914. pShader->BindTexture( SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1915. pShaderAPI->SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1916. }
  1917. bool bBlendWithSmokeGrenade = IsBoolSet( info.m_nBlendWithSmokeGrenade, params );
  1918. if ( bBlendWithSmokeGrenade )
  1919. {
  1920. float vSmokeGrenadePosSmoke[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  1921. params[ info.m_nBlendWithSmokeGrenadePosSmoke ]->GetVecValue( vSmokeGrenadePosSmoke, 3 );
  1922. if ( vSmokeGrenadePosSmoke[0] == 0 && vSmokeGrenadePosSmoke[1] == 0 && vSmokeGrenadePosSmoke[2] == 0 )
  1923. {
  1924. bBlendWithSmokeGrenade = false;
  1925. }
  1926. else
  1927. {
  1928. DynamicCmdsOut.SetPixelShaderConstant( 6, vSmokeGrenadePosSmoke, 1 );
  1929. }
  1930. }
  1931. bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
  1932. bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
  1933. bool bStaticLight3Streams = (r_staticlight_streams.GetInt() == 3) && (!(bHasVertexColor || bHasVertexAlpha));
  1934. bool bStaticLight3 = lightState.m_bStaticLight && bStaticLight3Streams;
  1935. int32 nStaticLightVsCombo = bStaticLight3 ? ( !r_staticlight_streams_indirect_only.GetBool() ? 2 : 1 ) : 0;
  1936. if ( bHasBump || bHasDiffuseWarp )
  1937. {
  1938. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  1939. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0);
  1940. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression);
  1941. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, TESSELLATION_MODE_DISABLED );
  1942. //SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, false );
  1943. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, nStaticLightVsCombo );
  1944. SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 );
  1945. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 );
  1946. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  1947. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight && !bStaticLight3 );
  1948. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, false );
  1949. SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, false );
  1950. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1951. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, 0 );
  1952. SET_DYNAMIC_PIXEL_SHADER_COMBO( STATICLIGHT3, bStaticLight3 );
  1953. SET_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 );
  1954. *vsDynIndex = _vshIndex.GetIndex();
  1955. *psDynIndex = _pshIndex.GetIndex();
  1956. }
  1957. else
  1958. {
  1959. DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 );
  1960. int staticLight3VSCombo = ( lightState.m_bStaticLight && bStaticLight3Streams ) ? ( ( lightState.m_bStaticLightIndirectOnly ) ? 2 : 1 ) : 0;
  1961. //[msmith] Using dynamic lights on a statically lit prop causes a visual pop in the lighting. For this reason, we ignore dynamic lights on staticly lit props.
  1962. SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
  1963. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0);
  1964. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression);
  1965. SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, TESSELLATION_MODE_DISABLED );
  1966. //SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, false );
  1967. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATICLIGHT3, staticLight3VSCombo );
  1968. SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 );
  1969. DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 );
  1970. SET_DYNAMIC_PIXEL_SHADER_COMBO( SMOKEGRENADEBLEND, bBlendWithSmokeGrenade );
  1971. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, false );
  1972. SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, false );
  1973. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1974. SET_DYNAMIC_PIXEL_SHADER_COMBO( CASCADE_SIZE, 0 );
  1975. SET_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 );
  1976. *vsDynIndex = _vshIndex.GetIndex();
  1977. *psDynIndex = _pshIndex.GetIndex();
  1978. }
  1979. bool bUnusedTexCoords[3] = { false, false, true };
  1980. ShaderApiFast( pShaderAPI )->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords );
  1981. bool bTreeSway = ( GetIntParam( info.m_nTreeSway, params, 0 ) != 0 );
  1982. if ( bHasBump || bHasDiffuseWarp )
  1983. {
  1984. ITexture *pDepthTextureAtlas = NULL;
  1985. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas );
  1986. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, &cascadeState.m_vLightColor.x );
  1987. }
  1988. if ( !bHasBump || bTreeSway )
  1989. {
  1990. float fTempConst[4];
  1991. fTempConst[0] = 0.0f;
  1992. fTempConst[1] = ShaderApiFast( pShaderAPI )->CurrentTime();
  1993. Vector windDir = IsBoolSet( info.m_nTreeSwayStatic, params ) ? Vector(0.5f,0.5f,0) : pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_WIND_DIRECTION );
  1994. fTempConst[2] = windDir.x;
  1995. fTempConst[3] = windDir.y;
  1996. ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, fTempConst );
  1997. }
  1998. float fWriteDepthToAlpha = bWriteDepthToAlpha? 1.0f : 0.0f;
  1999. float fWriteWaterFogToDestAlpha = bWriteWaterFogToAlpha? 1.0f : 0.0f;
  2000. float fVertexAlpha = bHasVertexAlpha ? 1.0f : 0.0f;
  2001. float fBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) ? 1.0f : 0.0f;
  2002. bool bHasTintMaskTexture = IsTextureSet( info.m_nTintMaskTexture, params );
  2003. fBlendTintByBaseAlpha = bHasTintMaskTexture ? 1.0f : fBlendTintByBaseAlpha; // This is needed to make the shader math work out in the tint texture case
  2004. // Controls for lerp-style paths through shader code (used by bump and non-bump)
  2005. float vShaderControls[4] = { IsBoolSet( info.m_nNoTint, params ) ? -1.0f : ( 1.0f - fBlendTintByBaseAlpha ), fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha };
  2006. if ( bHasBump )
  2007. {
  2008. // Bump shader doesn't use vertex alpha
  2009. vShaderControls[ 3 ] = GetIntParam( info.m_nEnvMapMaskInTintMaskTexture, params, 0 ) ? 1.0f : 0.0f;
  2010. }
  2011. else
  2012. {
  2013. // Nonbump shader doesn't use water fog dest alpha thing.
  2014. vShaderControls[ 2 ] = GetIntParam( info.m_nEnvMapMaskInTintMaskTexture, params, 0 ) ? 1.0f : 0.0f;
  2015. }
  2016. DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 );
  2017. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 12, vShaderControls, 1 );
  2018. }
  2019. void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI * pShaderAPI,
  2020. IShaderShadow* pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
  2021. CBasePerMaterialContextData **pContextDataPtr )
  2022. {
  2023. if ( WantsPhongShader( params, info ) && g_pHardwareConfig->SupportsPixelShaders_2_b() /*&& mat_bumpmap.GetBool()*/ )
  2024. {
  2025. DrawPhong_DX9( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr );
  2026. return;
  2027. }
  2028. bool bReceiveFlashlight = bVertexLitGeneric || ( GetIntParam( info.m_nReceiveFlashlight, params ) != 0 );
  2029. bool bHasFlashlight = bReceiveFlashlight && pShader->UsingFlashlight( params );
  2030. //since single pass flashlights have a different snapshot than multipass. We need to get snapshots of both and only actually draw the enabled mode
  2031. if( IsX360() || IsPS3() || !bHasFlashlight || (GetIntParam( info.m_nSinglePassFlashlight, params ) == 0) )
  2032. {
  2033. //360/PS3 only support single pass flashlight, so bHasFlashlight == bSinglePassFlashlight. And single pass flashlights are the same as multipass when there's no flashlight.
  2034. DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI,
  2035. pShaderShadow, bVertexLitGeneric, bHasFlashlight, IsX360() || IsPS3(), info, vertexCompression, pContextDataPtr );
  2036. }
  2037. else //single pass flashlight enabled material. Support both multipass and single pass flashlight
  2038. {
  2039. if( pShaderShadow )
  2040. {
  2041. //snapshotting, grab a snapshot of both modes
  2042. DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI,
  2043. pShaderShadow, bVertexLitGeneric, bHasFlashlight, false, info, vertexCompression, pContextDataPtr );
  2044. DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI,
  2045. pShaderShadow, bVertexLitGeneric, bHasFlashlight, true, info, vertexCompression, pContextDataPtr );
  2046. }
  2047. else
  2048. {
  2049. Assert( pShaderAPI );
  2050. if( ShaderApiFast( pShaderAPI )->SinglePassFlashlightModeEnabled() )
  2051. {
  2052. //use only the second (singlepass flashlights) snapshot
  2053. pShader->Draw( false );
  2054. DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI,
  2055. pShaderShadow, bVertexLitGeneric, bHasFlashlight, true, info, vertexCompression, pContextDataPtr );
  2056. }
  2057. else
  2058. {
  2059. //use only the first (multipass flashlights) snapshot
  2060. DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI,
  2061. pShaderShadow, bVertexLitGeneric, bHasFlashlight, false, info, vertexCompression, pContextDataPtr );
  2062. pShader->Draw( false );
  2063. }
  2064. }
  2065. }
  2066. }
  2067. void DrawVertexLitGeneric_DX9_ExecuteFastPath( int *vsDynIndex, int *psDynIndex,
  2068. CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI * pShaderAPI,
  2069. VertexLitGeneric_DX9_Vars_t &info,
  2070. VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr,
  2071. BOOL bCSMEnabled, BOOL bVertexLitGeneric /*= true*/ )
  2072. {
  2073. if ( WantsPhongShader( params, info ) )
  2074. {
  2075. DrawPhong_DX9_ExecuteFastPath( vsDynIndex, psDynIndex, pShader, params, pShaderAPI, info, vertexCompression, pContextDataPtr, bCSMEnabled );
  2076. return;
  2077. }
  2078. DrawVertexLitGeneric_DX9_Internal_ExecuteFastPath( vsDynIndex, psDynIndex, pShader, params, pShaderAPI,
  2079. info, vertexCompression, pContextDataPtr, bCSMEnabled, bVertexLitGeneric );
  2080. }