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.

1212 lines
50 KiB

  1. //========= Copyright (c) 1996-2014, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose: Lightmapped_4WayBlend shader
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //=============================================================================
  8. #include "lightmapped_4wayblend_dx9_helper.h"
  9. #include "BaseVSShader.h"
  10. #include "shaderlib/commandbuilder.h"
  11. #include "convar.h"
  12. #include "lightmapped_4wayblend_vs20.inc"
  13. #include "lightmapped_4wayblend_ps20b.inc"
  14. #if !defined( _X360 ) && !defined( _PS3 )
  15. #include "lightmapped_4wayblend_vs30.inc"
  16. #include "lightmapped_4wayblend_ps30.inc"
  17. #endif
  18. #include "shaderapifast.h"
  19. #include "tier0/vprof.h"
  20. #include "tier0/memdbgon.h"
  21. extern ConVar mat_ambient_light_r;
  22. extern ConVar mat_ambient_light_g;
  23. extern ConVar mat_ambient_light_b;
  24. #if defined( CSTRIKE15 ) && defined( _X360 )
  25. static ConVar r_shader_srgbread( "r_shader_srgbread", "1", 0, "1 = use shader srgb texture reads, 0 = use HW" );
  26. #else
  27. static ConVar r_shader_srgbread( "r_shader_srgbread", "0", 0, "1 = use shader srgb texture reads, 0 = use HW" );
  28. #endif
  29. static ConVar mat_force_vertexfog( "mat_force_vertexfog", "0", FCVAR_DEVELOPMENTONLY );
  30. void InitParamsLightmapped_4WayBlend_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Lightmapped_4WayBlend_DX9_Vars_t &info )
  31. {
  32. // A little strange, but we do support "skinning" in that we can do
  33. // fast-path instance rendering with lightmapped generic, and this
  34. // tells the system to insert the PI command buffer to set the per-instance matrix.
  35. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  36. // Override vertex fog via the global setting if it isn't enabled/disabled in the material file.
  37. if ( !IS_FLAG_DEFINED( MATERIAL_VAR_VERTEXFOG ) && mat_force_vertexfog.GetBool() )
  38. {
  39. SET_FLAGS( MATERIAL_VAR_VERTEXFOG );
  40. }
  41. params[FLASHLIGHTTEXTURE]->SetStringValue( GetFlashlightTextureFilename() );
  42. if( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() )
  43. {
  44. if( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 )
  45. {
  46. Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName );
  47. params[info.m_nEnvmap]->SetUndefined();
  48. }
  49. }
  50. if( !params[info.m_nEnvmapTint]->IsDefined() )
  51. params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  52. if( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() )
  53. params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 );
  54. if( !params[info.m_nSelfIllumTint]->IsDefined() )
  55. params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f );
  56. if( !params[info.m_nDetailScale]->IsDefined() )
  57. params[info.m_nDetailScale]->SetFloatValue( 4.0f );
  58. if ( !params[info.m_nDetailTint]->IsDefined() )
  59. params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f );
  60. InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 );
  61. InitFloatParam( info.m_nDetailTextureBlendFactor2, params, 1.0 );
  62. InitFloatParam( info.m_nDetailTextureBlendFactor3, params, 1.0 );
  63. InitFloatParam( info.m_nDetailTextureBlendFactor4, params, 1.0 );
  64. InitIntParam( info.m_nDetailTextureCombineMode, params, 0 );
  65. InitFloatParam( info.m_nTexture2uvScale, params, 1.0f );
  66. InitFloatParam( info.m_nTexture3uvScale, params, 1.0f );
  67. InitFloatParam( info.m_nTexture4uvScale, params, 1.0f );
  68. InitFloatParam( info.m_nTexture2BlendStart, params, 0.0f );
  69. InitFloatParam( info.m_nTexture3BlendStart, params, 0.0f );
  70. InitFloatParam( info.m_nTexture4BlendStart, params, 0.0f );
  71. InitFloatParam( info.m_nTexture2BlendEnd, params, 1.0f );
  72. InitFloatParam( info.m_nTexture3BlendEnd, params, 1.0f );
  73. InitFloatParam( info.m_nTexture4BlendEnd, params, 1.0f );
  74. InitFloatParam( info.m_nTexture1LumStart, params, 0.0f );
  75. InitFloatParam( info.m_nTexture2LumStart, params, 0.0f );
  76. InitFloatParam( info.m_nTexture3LumStart, params, 0.0f );
  77. InitFloatParam( info.m_nTexture4LumStart, params, 0.0f );
  78. InitFloatParam( info.m_nTexture1LumEnd, params, 1.0f );
  79. InitFloatParam( info.m_nTexture2LumEnd, params, 1.0f );
  80. InitFloatParam( info.m_nTexture3LumEnd, params, 1.0f );
  81. InitFloatParam( info.m_nTexture4LumEnd, params, 1.0f );
  82. InitFloatParam( info.m_nTexture2BumpBlendFactor, params, 1.0f );
  83. InitFloatParam( info.m_nTexture3BumpBlendFactor, params, 1.0f );
  84. InitFloatParam( info.m_nTexture4BumpBlendFactor, params, 1.0f );
  85. InitFloatParam( info.m_nLumBlendFactor2, params, 1.0f );
  86. InitFloatParam( info.m_nLumBlendFactor3, params, 1.0f );
  87. InitFloatParam( info.m_nLumBlendFactor4, params, 1.0f );
  88. if( !params[info.m_nFresnelReflection]->IsDefined() )
  89. params[info.m_nFresnelReflection]->SetFloatValue( 1.0f );
  90. if( !params[info.m_nEnvmapMaskFrame]->IsDefined() )
  91. params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 );
  92. if( !params[info.m_nEnvmapFrame]->IsDefined() )
  93. params[info.m_nEnvmapFrame]->SetIntValue( 0 );
  94. if( !params[info.m_nBumpFrame]->IsDefined() )
  95. params[info.m_nBumpFrame]->SetIntValue( 0 );
  96. if( !params[info.m_nDetailFrame]->IsDefined() )
  97. params[info.m_nDetailFrame]->SetIntValue( 0 );
  98. if( !params[info.m_nEnvmapContrast]->IsDefined() )
  99. params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f );
  100. if( !params[info.m_nEnvmapSaturation]->IsDefined() )
  101. params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f );
  102. if ( ( info.m_nEnvmapAnisotropyScale != -1 ) && !params[info.m_nEnvmapAnisotropyScale]->IsDefined() )
  103. params[info.m_nEnvmapAnisotropyScale]->SetFloatValue( 1.0f );
  104. if ( ( info.m_nEnvMapLightScaleMinMax != -1 ) && !params[info.m_nEnvMapLightScaleMinMax]->IsDefined() )
  105. params[info.m_nEnvMapLightScaleMinMax]->SetVecValue( 0.0, 1.0 );
  106. InitFloatParam( info.m_nAlphaTestReference, params, 0.0f );
  107. // No texture means no self-illum or env mask in base alpha
  108. if ( !params[info.m_nBaseTexture]->IsDefined() )
  109. {
  110. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  111. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  112. }
  113. if( params[info.m_nBumpmap]->IsDefined() )
  114. {
  115. params[info.m_nEnvmapMask]->SetUndefined();
  116. }
  117. // If in decal mode, no debug override...
  118. if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
  119. {
  120. SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  121. }
  122. if ( !params[info.m_nForceBumpEnable]->IsDefined() )
  123. {
  124. params[info.m_nForceBumpEnable]->SetIntValue( 0 );
  125. }
  126. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
  127. bool bShouldUseBump = g_pConfig->UseBumpmapping() || !!params[info.m_nForceBumpEnable]->GetIntValue();
  128. if( bShouldUseBump && params[info.m_nBumpmap]->IsDefined() && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0) )
  129. {
  130. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP );
  131. }
  132. // If mat_specular 0, then get rid of envmap
  133. if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() )
  134. {
  135. params[info.m_nEnvmap]->SetUndefined();
  136. }
  137. if( ( info.m_nSelfShadowedBumpFlag != -1 ) &&
  138. ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() )
  139. )
  140. {
  141. params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 );
  142. }
  143. // srgb read 360
  144. #if defined( CSTRIKE15 )
  145. InitIntParam( info.m_nShaderSrgbRead360, params, 1 );
  146. #else
  147. InitIntParam( info.m_nShaderSrgbRead360, params, 0 );
  148. #endif
  149. InitFloatParam( info.m_nEnvMapLightScale, params, 0.0f );
  150. }
  151. void InitLightmapped_4WayBlend_DX9( CBaseVSShader *pShader, IMaterialVar** params, Lightmapped_4WayBlend_DX9_Vars_t &info )
  152. {
  153. bool bShouldUseBump = g_pConfig->UseBumpmapping() || !!params[info.m_nForceBumpEnable]->GetIntValue();
  154. if ( bShouldUseBump && params[info.m_nBumpmap]->IsDefined() )
  155. {
  156. pShader->LoadBumpMap( info.m_nBumpmap, ANISOTROPIC_OVERRIDE );
  157. }
  158. if ( bShouldUseBump && params[info.m_nBumpmap2]->IsDefined() )
  159. {
  160. pShader->LoadBumpMap( info.m_nBumpmap2, ANISOTROPIC_OVERRIDE );
  161. }
  162. if (params[info.m_nBaseTexture]->IsDefined())
  163. {
  164. pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  165. if (!params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent())
  166. {
  167. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  168. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  169. }
  170. }
  171. if ( params[info.m_nBaseTexture2]->IsDefined() )
  172. {
  173. pShader->LoadTexture( info.m_nBaseTexture2, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  174. }
  175. if ( params[info.m_nBaseTexture3]->IsDefined() )
  176. {
  177. pShader->LoadTexture( info.m_nBaseTexture3, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  178. }
  179. if ( params[info.m_nBaseTexture4]->IsDefined() )
  180. {
  181. pShader->LoadTexture( info.m_nBaseTexture4, TEXTUREFLAGS_SRGB | ANISOTROPIC_OVERRIDE );
  182. }
  183. if (params[info.m_nDetail]->IsDefined())
  184. {
  185. int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue();
  186. if ( nDetailBlendMode != DETAIL_BLEND_MODE_RGB_EQUALS_BASE_x_DETAILx2 && nDetailBlendMode != DETAIL_BLEND_MODE_MOD2X_SELECT_TWO_PATTERNS && nDetailBlendMode != DETAIL_BLEND_MODE_NONE )
  187. {
  188. Msg( "Invalid DetailBlendMode in %s, %d not supported!", pShader->GetName(), nDetailBlendMode );
  189. }
  190. if ( nDetailBlendMode != DETAIL_BLEND_MODE_NONE )
  191. {
  192. pShader->LoadTexture( info.m_nDetail, IsSRGBDetailTexture( nDetailBlendMode ) ? TEXTUREFLAGS_SRGB : 0 );
  193. }
  194. }
  195. pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB );
  196. // Don't alpha test if the alpha channel is used for other purposes
  197. if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
  198. {
  199. CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
  200. }
  201. if ( g_pConfig->UseSpecular() )
  202. {
  203. if ( params[info.m_nEnvmap]->IsDefined() )
  204. {
  205. pShader->LoadCubeMap( info.m_nEnvmap, ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ) | ANISOTROPIC_OVERRIDE );
  206. if (params[info.m_nEnvmapMask]->IsDefined())
  207. {
  208. pShader->LoadTexture( info.m_nEnvmapMask );
  209. }
  210. }
  211. else
  212. {
  213. params[info.m_nEnvmapMask]->SetUndefined();
  214. }
  215. }
  216. else
  217. {
  218. params[info.m_nEnvmap]->SetUndefined();
  219. params[info.m_nEnvmapMask]->SetUndefined();
  220. }
  221. // We always need this because of the flashlight.
  222. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  223. }
  224. void DrawLightmapped_4WayBlend_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
  225. Lightmapped_4WayBlend_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr )
  226. {
  227. bool bSinglePassFlashlight = true;
  228. bool hasFlashlight = pShader->UsingFlashlight( params );
  229. CLightmapped_4WayBlend_DX9_Context *pContextData = reinterpret_cast< CLightmapped_4WayBlend_DX9_Context *> ( *pContextDataPtr );
  230. #if defined( CSTRIKE15 )
  231. bool bShaderSrgbRead = IsX360() && r_shader_srgbread.GetBool();
  232. #else
  233. bool bShaderSrgbRead = ( IsX360() && IS_PARAM_DEFINED( info.m_nShaderSrgbRead360 ) && params[info.m_nShaderSrgbRead360]->GetIntValue() );
  234. #endif
  235. bool bHDR = g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE;
  236. int nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params );
  237. if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged || ( hasFlashlight && !( IsX360() || IsPS3() ) ) )
  238. {
  239. bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture();
  240. int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask;
  241. BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture );
  242. bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0;
  243. bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360() || IsPS3()); //dest alpha is free for special use
  244. bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested;
  245. bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow;
  246. if ( ! pContextData ) // make sure allocated
  247. {
  248. pContextData = new CLightmapped_4WayBlend_DX9_Context;
  249. *pContextDataPtr = pContextData;
  250. }
  251. bool shouldUseBump = g_pConfig->UseBumpmapping() || !!params[info.m_nForceBumpEnable]->GetIntValue();
  252. bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && shouldUseBump;
  253. bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() );
  254. bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture();
  255. bool hasDetailTexture = params[info.m_nDetail]->IsTexture() && g_pConfig->UseDetailTexturing() && ( nDetailBlendMode != DETAIL_BLEND_MODE_NONE );
  256. bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM );
  257. if ( hasFlashlight && !( IsX360() || IsPS3() ) )
  258. {
  259. // !!speed!! do this in the caller so we don't build struct every time
  260. CBaseVSShader::DrawFlashlight_dx90_Vars_t vars;
  261. vars.m_bBump = hasBump;
  262. vars.m_nBumpmapVar = info.m_nBumpmap;
  263. vars.m_nBumpmapFrame = info.m_nBumpFrame;
  264. vars.m_nBumpTransform = info.m_nBumpTransform;
  265. vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture;
  266. vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame;
  267. vars.m_bLightmappedGeneric = true;
  268. vars.m_bWorldVertexTransition = true;
  269. vars.m_nBaseTexture2Var = info.m_nBaseTexture2;
  270. vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame;
  271. vars.m_nBumpmapVar2 = info.m_nBumpmap2;
  272. vars.m_nBumpmapFrame2 = info.m_nBumpFrame2;
  273. vars.m_nBumpTransform2 = info.m_nBumpTransform2;
  274. vars.m_nAlphaTestReference = info.m_nAlphaTestReference;
  275. vars.m_bSSBump = hasSSBump;
  276. vars.m_nDetailVar = info.m_nDetail;
  277. vars.m_nDetailScale = info.m_nDetailScale;
  278. vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode;
  279. vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor;
  280. vars.m_nDetailTint = info.m_nDetailTint;
  281. if ( ( info.m_nSeamlessMappingScale != -1 ) )
  282. vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue();
  283. else
  284. vars.m_fSeamlessScale = 0.0;
  285. pShader->DrawFlashlight_dx90( params, pShaderAPI, pShaderShadow, vars );
  286. return;
  287. }
  288. pContextData->m_bFullyOpaque = bFullyOpaque;
  289. pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest;
  290. bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
  291. bool bEnvmapAnisotropy = hasBump && !hasSSBump && ( info.m_nEnvmapAnisotropy != -1 ) &&
  292. ( params[info.m_nEnvmapAnisotropy]->GetIntValue() == 1 );
  293. if ( pShaderShadow || bNeedRegenStaticCmds )
  294. {
  295. bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
  296. bool hasEnvmap = params[info.m_nEnvmap]->IsTexture();
  297. bEnvmapAnisotropy = bEnvmapAnisotropy && hasEnvmap;
  298. int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
  299. if( hasEnvmap )
  300. {
  301. //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
  302. envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && (g_pHardwareConfig->SupportsPixelShaders_2_b() || !hasBump2)) ? 2 : 1;
  303. }
  304. else
  305. {
  306. envmap_variant = 0;
  307. }
  308. if ( hasDetailTexture )
  309. {
  310. ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue();
  311. if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP )
  312. {
  313. if ( hasBump )
  314. nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_BUMP;
  315. else
  316. nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_NOBUMP;
  317. }
  318. }
  319. bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
  320. ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
  321. if ( bNeedRegenStaticCmds )
  322. {
  323. pContextData->ResetStaticCmds();
  324. CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf;
  325. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  326. if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() )
  327. {
  328. staticCmdsBuf.SetVertexShaderNearAndFarZ( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 ); // Needed for SSAO
  329. }
  330. if( !hasBaseTexture )
  331. {
  332. if( hasEnvmap )
  333. {
  334. // if we only have an envmap (no basetexture), then we want the albedo to be black.
  335. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_BLACK );
  336. }
  337. else
  338. {
  339. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_WHITE );
  340. }
  341. }
  342. // mariod - are lightmaps ever srgb?
  343. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_LIGHTMAP );
  344. if ( bSeamlessMapping )
  345. {
  346. staticCmdsBuf.SetVertexShaderConstant4(
  347. VERTEX_SHADER_SHADER_SPECIFIC_CONST_0,
  348. params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 );
  349. }
  350. staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 );
  351. #ifndef _PS3
  352. staticCmdsBuf.SetPixelShaderFogParams( 11 );
  353. #endif
  354. staticCmdsBuf.End();
  355. // now, copy buf
  356. pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()];
  357. memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() );
  358. }
  359. if ( pShaderShadow )
  360. {
  361. // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState
  362. pShaderShadow->EnableAlphaTest( bIsAlphaTested );
  363. if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
  364. {
  365. pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() );
  366. }
  367. pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture );
  368. unsigned int flags = VERTEX_POSITION;
  369. if( hasEnvmap || ( ( IsX360() || IsPS3() ) && hasFlashlight ) )
  370. {
  371. flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL;
  372. }
  373. if ( hasDetailTexture )
  374. {
  375. ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue();
  376. if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP )
  377. {
  378. if ( hasBump )
  379. nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_BUMP;
  380. else
  381. nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_NOBUMP;
  382. }
  383. pShaderShadow->EnableTexture( SHADER_SAMPLER12, true );
  384. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, IsSRGBDetailTexture( nDetailBlendMode ) );
  385. }
  386. if( hasFlashlight && ( IsX360() || IsPS3() ) )
  387. {
  388. //pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 );
  389. }
  390. if( hasVertexColor || hasBump2 )
  391. {
  392. flags |= VERTEX_COLOR;
  393. }
  394. flags |= VERTEX_SPECULAR;
  395. // texcoord0 : base texcoord
  396. // texcoord1 : lightmap texcoord
  397. // texcoord2 : lightmap texcoord offset
  398. int numTexCoords;
  399. // if ( ShaderApiFast( pShaderAPI )->InEditorMode() )
  400. // if ( pShader->CanUseEditorMaterials() )
  401. // {
  402. // numTexCoords = 1;
  403. // }
  404. // else
  405. {
  406. numTexCoords = 2;
  407. if( hasBump )
  408. {
  409. numTexCoords = 3;
  410. }
  411. }
  412. int nTexture3BlendMode = GetIntParam( info.m_nTexture3BlendMode, params );
  413. int nTexture4BlendMode = GetIntParam( info.m_nTexture4BlendMode, params );
  414. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  415. pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
  416. // Pre-cache pixel shaders
  417. bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  418. int bumpmap_variant=(hasSSBump) ? 2 : hasBump;
  419. bool bCSMBlending = g_pHardwareConfig->GetCSMAccurateBlending();
  420. #if !defined( _X360 ) && !defined( _PS3 )
  421. if ( !g_pHardwareConfig->SupportsPixelShaders_3_0() )
  422. #endif
  423. {
  424. DECLARE_STATIC_VERTEX_SHADER( lightmapped_4wayblend_vs20 );
  425. SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask );
  426. SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() );
  427. SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump );
  428. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) );
  429. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  430. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  431. SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture );
  432. SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum );
  433. #if defined( _X360 ) || defined( _PS3 )
  434. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight);
  435. #endif
  436. SET_STATIC_VERTEX_SHADER( lightmapped_4wayblend_vs20 );
  437. DECLARE_STATIC_PIXEL_SHADER( lightmapped_4wayblend_ps20b );
  438. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
  439. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 );
  440. SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE3_BLENDMODE, nTexture3BlendMode );
  441. SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE4_BLENDMODE, nTexture4BlendMode );
  442. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
  443. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask );
  444. SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask );
  445. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum );
  446. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  447. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  448. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPANISOTROPY, bEnvmapAnisotropy );
  449. #if defined( _X360 ) || defined( _PS3 )
  450. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight);
  451. #endif
  452. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  453. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  454. SET_STATIC_PIXEL_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  455. SET_STATIC_PIXEL_SHADER( lightmapped_4wayblend_ps20b );
  456. }
  457. #if !defined( _X360 ) && !defined( _PS3 )
  458. else // Shader model 3.0, PC only
  459. {
  460. int nCSMQualityComboValue = g_pHardwareConfig->GetCSMShaderMode( materials->GetCurrentConfigForVideoCard().GetCSMQualityMode() );
  461. DECLARE_STATIC_VERTEX_SHADER( lightmapped_4wayblend_vs30 );
  462. SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask );
  463. SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() );
  464. SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump );
  465. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) );
  466. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  467. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  468. SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture );
  469. SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum );
  470. SET_STATIC_VERTEX_SHADER( lightmapped_4wayblend_vs30 );
  471. DECLARE_STATIC_PIXEL_SHADER( lightmapped_4wayblend_ps30 );
  472. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
  473. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 );
  474. SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE3_BLENDMODE, nTexture3BlendMode );
  475. SET_STATIC_PIXEL_SHADER_COMBO( TEXTURE4_BLENDMODE, nTexture4BlendMode );
  476. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
  477. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask );
  478. SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask );
  479. SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum );
  480. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  481. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
  482. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPANISOTROPY, bEnvmapAnisotropy );
  483. SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead );
  484. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  485. SET_STATIC_PIXEL_SHADER_COMBO( CSM_MODE, ( g_pHardwareConfig->SupportsCascadedShadowMapping() && !ToolsEnabled() ) ? nCSMQualityComboValue : 0 );
  486. SET_STATIC_PIXEL_SHADER_COMBO( CSM_BLENDING, bCSMBlending );
  487. SET_STATIC_PIXEL_SHADER( lightmapped_4wayblend_ps30 );
  488. }
  489. #endif
  490. // HACK HACK HACK - enable alpha writes all the time so that we have them for
  491. // underwater stuff and writing depth to dest alpha
  492. // But only do it if we're not using the alpha already for translucency
  493. pShaderShadow->EnableAlphaWrites( bFullyOpaque );
  494. pShaderShadow->EnableSRGBWrite( true );
  495. pShader->DefaultFog();
  496. // NOTE: This isn't optimal. If $color2 is ever changed by a material
  497. // proxy, this code won't get re-run, but too bad. No time to make this work
  498. // Also note that if the lightmap scale factor changes
  499. // all shadow state blocks will be re-run, so that's ok
  500. float flLScale = pShaderShadow->GetLightMapScaleFactor();
  501. pShader->PI_BeginCommandBuffer();
  502. if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
  503. {
  504. pShader->PI_SetModulationPixelShaderDynamicState( 21 );
  505. }
  506. // MAINTOL4DMERGEFIXME
  507. // Need to reflect this change which is from this rel changelist since this constant set was moved from the dynamic block to here:
  508. // Change 578692 by Alex@alexv_rel on 2008/06/04 18:07:31
  509. //
  510. // Fix for portalareawindows in ep2 being rendered black. The color variable was being multipurposed for both the vs and ps differently where the ps doesn't care about alpha, but the vs does. Only applying the alpha2 DoD hack to the pixel shader constant where the alpha was never used in the first place and leaving alpha as is for the vs.
  511. // color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f;
  512. // pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color );
  513. pShader->PI_SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( 12, flLScale );
  514. pShader->PI_SetModulationVertexShaderDynamicState_LinearScale( flLScale );
  515. pShader->PI_EndCommandBuffer();
  516. } // end shadow state
  517. } // end shadow || regen display list
  518. if ( pShaderAPI && ( pContextData->m_bMaterialVarsChanged ) )
  519. {
  520. // need to regenerate the semistatic cmds
  521. pContextData->m_SemiStaticCmdsOut.Reset();
  522. #ifdef _PS3
  523. pContextData->m_flashlightECB.Reset();
  524. #endif
  525. pContextData->m_bMaterialVarsChanged = false;
  526. // If we don't have a texture transform, we don't have
  527. // to set vertex shader constants or run vertex shader instructions
  528. // for the texture transform.
  529. bool bHasTextureTransform =
  530. !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() &&
  531. params[info.m_nBumpTransform]->MatrixIsIdentity() &&
  532. params[info.m_nBumpTransform2]->MatrixIsIdentity() &&
  533. params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() );
  534. pContextData->m_bVertexShaderFastPath = !bHasTextureTransform;
  535. if( params[info.m_nDetail]->IsTexture() )
  536. {
  537. pContextData->m_bVertexShaderFastPath = false;
  538. }
  539. int nTransformToLoad = -1;
  540. if( ( hasBump || hasSSBump ) && hasDetailTexture && !hasSelfIllum )
  541. {
  542. nTransformToLoad = info.m_nBumpTransform;
  543. }
  544. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform(
  545. VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, nTransformToLoad );
  546. if ( ! pContextData->m_bVertexShaderFastPath )
  547. {
  548. bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
  549. ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
  550. bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
  551. if (!bSeamlessMapping )
  552. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
  553. // If we have a detail texture, then the bump texcoords are the same as the base texcoords.
  554. if( hasBump && !hasDetailTexture )
  555. {
  556. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform );
  557. }
  558. if( hasEnvmapMask )
  559. {
  560. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform );
  561. }
  562. else if ( hasBump2 )
  563. {
  564. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 );
  565. }
  566. }
  567. pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint );
  568. float bumpblendfactors[ 3 ];
  569. bumpblendfactors[ 0 ] = clamp( GetFloatParam( info.m_nTexture2BumpBlendFactor, params, 1.0f ), 0.0f, 1.0f );
  570. bumpblendfactors[ 1 ] = clamp( GetFloatParam( info.m_nTexture3BumpBlendFactor, params, 1.0f ), 0.0f, 1.0f );
  571. bumpblendfactors[ 2 ] = clamp( GetFloatParam( info.m_nTexture4BumpBlendFactor, params, 1.0f ), 0.0f, 1.0f );
  572. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 1, bumpblendfactors );
  573. float ranges[ 4 ];
  574. ranges[ 0 ] = clamp( GetFloatParam( info.m_nTexture1LumStart, params, 0.0f ), 0.0f, 1.0f );
  575. ranges[ 1 ] = clamp( GetFloatParam( info.m_nTexture1LumEnd, params, 1.0f ), 0.0f, 1.0f );
  576. ranges[ 2 ] = clamp( GetFloatParam( info.m_nTexture2LumStart, params, 0.0f ), 0.0f, 1.0f );
  577. ranges[ 3 ] = clamp( GetFloatParam( info.m_nTexture2LumEnd, params, 1.0f ), 0.0f, 1.0f );
  578. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, ranges );
  579. ranges[ 0 ] = clamp( GetFloatParam( info.m_nTexture3LumStart, params, 0.0f ), 0.0f, 1.0f );
  580. ranges[ 1 ] = clamp( GetFloatParam( info.m_nTexture3LumEnd, params, 1.0f ), 0.0f, 1.0f );
  581. ranges[ 2 ] = clamp( GetFloatParam( info.m_nTexture4LumStart, params, 0.0f ), 0.0f, 1.0f );
  582. ranges[ 3 ] = clamp( GetFloatParam( info.m_nTexture4LumEnd, params, 1.0f ), 0.0f, 1.0f );
  583. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 28, ranges );
  584. if ( hasDetailTexture )
  585. {
  586. float detailTint[4] = {1, 1, 1, 1};
  587. if ( info.m_nDetailTint != -1 )
  588. {
  589. params[ info.m_nDetailTint ]->GetVecValue( detailTint, 3 );
  590. }
  591. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTint );
  592. float fDetailBlendFactors[ 4 ];
  593. fDetailBlendFactors[ 0 ] = clamp( GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ), 0.0f, 1.0f );
  594. fDetailBlendFactors[ 1 ] = clamp( GetFloatParam( info.m_nDetailTextureBlendFactor2, params, 1.0 ), 0.0f, 1.0f );
  595. fDetailBlendFactors[ 2 ] = clamp( GetFloatParam( info.m_nDetailTextureBlendFactor3, params, 1.0 ), 0.0f, 1.0f );
  596. fDetailBlendFactors[ 3 ] = clamp( GetFloatParam( info.m_nDetailTextureBlendFactor4, params, 1.0 ), 0.0f, 1.0f );
  597. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 9, fDetailBlendFactors );
  598. }
  599. ranges[ 0 ] = clamp( GetFloatParam( info.m_nTexture2BlendStart, params, 0.0f ), 0.0f, 1.0f );
  600. ranges[ 1 ] = clamp( GetFloatParam( info.m_nTexture2BlendEnd, params, 1.0f ), 0.0f, 1.0f );
  601. ranges[ 2 ] = clamp( GetFloatParam( info.m_nTexture3BlendStart, params, 0.0f ), 0.0f, 1.0f );
  602. ranges[ 3 ] = clamp( GetFloatParam( info.m_nTexture3BlendEnd, params, 1.0f ), 0.0f, 1.0f );
  603. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 15, ranges );
  604. float uvScales[ 4 ] = { 1.0f, 1.0f, 1.0f, 1.0f };
  605. if ( info.m_nTexture2uvScale != -1 )
  606. {
  607. params[ info.m_nTexture2uvScale ]->GetVecValue( &uvScales[ 0 ], 2 );
  608. }
  609. if ( info.m_nTexture3uvScale != -1 )
  610. {
  611. params[ info.m_nTexture3uvScale ]->GetVecValue( &uvScales[ 2 ], 2 );
  612. }
  613. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 16, uvScales );
  614. uvScales[ 0 ] = clamp( GetFloatParam( info.m_nTexture4BlendStart, params, 0.0f ), 0.0f, 1.0f );
  615. uvScales[ 1 ] = clamp( GetFloatParam( info.m_nTexture4BlendEnd, params, 1.0f ), 0.0f, 1.0f );
  616. if ( info.m_nTexture4uvScale != -1 )
  617. {
  618. params[ info.m_nTexture4uvScale ]->GetVecValue( &uvScales[ 2 ], 2 );
  619. }
  620. else
  621. {
  622. uvScales[ 2 ] = 1.0f;
  623. uvScales[ 3 ] = 1.0f;
  624. }
  625. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 17, uvScales );
  626. float lumblends[ 3 ];
  627. lumblends[ 0 ] = clamp( GetFloatParam( info.m_nLumBlendFactor2, params, 1.0f ), 0.0f, 1.0f );
  628. lumblends[ 1 ] = clamp( GetFloatParam( info.m_nLumBlendFactor3, params, 1.0f ), 0.0f, 1.0f );
  629. lumblends[ 2 ] = clamp( GetFloatParam( info.m_nLumBlendFactor4, params, 1.0f ), 0.0f, 1.0f );
  630. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 18, lumblends );
  631. float envmapTintVal[4];
  632. float selfIllumTintVal[4];
  633. params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 );
  634. params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 );
  635. float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
  636. float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue();
  637. float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue();
  638. bool hasEnvmap = params[info.m_nEnvmap]->IsTexture();
  639. bEnvmapAnisotropy = bEnvmapAnisotropy && hasEnvmap;
  640. int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
  641. if( hasEnvmap )
  642. {
  643. //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
  644. envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && (g_pHardwareConfig->SupportsPixelShaders_2_b() || !hasBump2)) ? 2 : 1;
  645. }
  646. else
  647. {
  648. envmap_variant = 0;
  649. }
  650. pContextData->m_bPixelShaderFastPath = true;
  651. bool bUsingContrastOrSaturation = hasEnvmap && ( ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) || (envmapSaturation != 1.0f) );
  652. bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f);
  653. bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f);
  654. if ( bUsingContrastOrSaturation || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular )
  655. {
  656. pContextData->m_bPixelShaderFastPath = false;
  657. }
  658. if( !pContextData->m_bPixelShaderFastPath )
  659. {
  660. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 );
  661. pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() );
  662. pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() );
  663. float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue();
  664. // [ 0, 0, 1-R(0), R(0) ]
  665. pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel );
  666. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() );
  667. }
  668. // cubemap light scale mapping parms (c20)
  669. if ( ( envmap_variant == 2 ) || bEnvmapAnisotropy )
  670. {
  671. float envMapParams[4] = { 0, 0, 0, 0 };
  672. if ( bEnvmapAnisotropy )
  673. {
  674. envMapParams[0] = GetFloatParam( info.m_nEnvmapAnisotropyScale, params );
  675. }
  676. if ( envmap_variant == 2 )
  677. {
  678. envMapParams[1] = GetFloatParam( info.m_nEnvMapLightScale, params );
  679. float lightScaleMinMax[2] = { 0.0, 0.0 };
  680. params[info.m_nEnvMapLightScaleMinMax]->GetVecValue( lightScaleMinMax, 2 );
  681. envMapParams[2] = lightScaleMinMax[0];
  682. envMapParams[3] = lightScaleMinMax[1] + lightScaleMinMax[0];
  683. }
  684. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 20, envMapParams );
  685. }
  686. // texture binds
  687. if( hasBaseTexture )
  688. {
  689. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, SRGBReadMask( !bShaderSrgbRead ), info.m_nBaseTexture, info.m_nBaseTextureFrame );
  690. }
  691. // always set the transform for detail textures since I'm assuming that you'll
  692. // always have a detailscale.
  693. if( hasDetailTexture )
  694. {
  695. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale );
  696. }
  697. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, SRGBReadMask( !bShaderSrgbRead ), info.m_nBaseTexture2, info.m_nBaseTexture2Frame );
  698. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, SRGBReadMask( !bShaderSrgbRead ), info.m_nBaseTexture3, info.m_nBaseTexture3Frame );
  699. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, SRGBReadMask( !bShaderSrgbRead ), info.m_nBaseTexture4, info.m_nBaseTexture4Frame );
  700. if( hasDetailTexture )
  701. {
  702. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, SRGBReadMask( IsSRGBDetailTexture( nDetailBlendMode ) && !bShaderSrgbRead ), info.m_nDetail, info.m_nDetailFrame );
  703. }
  704. if( hasBump )
  705. {
  706. if( !g_pConfig->m_bFastNoBump )
  707. {
  708. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, info.m_nBumpmap, info.m_nBumpFrame );
  709. }
  710. else
  711. {
  712. if( hasSSBump )
  713. {
  714. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, TEXTURE_SSBUMP_FLAT );
  715. }
  716. else
  717. {
  718. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  719. }
  720. }
  721. }
  722. if( hasBump2 )
  723. {
  724. if( !g_pConfig->m_bFastNoBump )
  725. {
  726. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, info.m_nBumpmap2, info.m_nBumpFrame2 );
  727. }
  728. else
  729. {
  730. if( hasSSBump )
  731. {
  732. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  733. }
  734. else
  735. {
  736. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_SSBUMP_FLAT );
  737. }
  738. }
  739. }
  740. if( hasEnvmapMask )
  741. {
  742. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame );
  743. }
  744. // handle mat_fullbright 2
  745. bool bLightingOnly = g_pConfig->nFullbright == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  746. if( bLightingOnly )
  747. {
  748. // BASE TEXTURE
  749. if( hasSelfIllum )
  750. {
  751. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_GREY_ALPHA_ZERO );
  752. }
  753. else
  754. {
  755. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_GREY );
  756. }
  757. // BASE TEXTURE 2
  758. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_GREY );
  759. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_GREY );
  760. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, SRGBReadMask( !bShaderSrgbRead ), TEXTURE_GREY );
  761. // DETAIL TEXTURE
  762. if( hasDetailTexture )
  763. {
  764. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_BINDFLAGS_NONE, TEXTURE_GREY );
  765. }
  766. // disable color modulation
  767. float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  768. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color );
  769. // turn off environment mapping
  770. envmapTintVal[0] = 0.0f;
  771. envmapTintVal[1] = 0.0f;
  772. envmapTintVal[2] = 0.0f;
  773. }
  774. if ( hasFlashlight && ( IsX360() || IsPS3() ) )
  775. {
  776. #ifdef _PS3
  777. {
  778. pContextData->m_flashlightECB.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 );
  779. }
  780. #endif
  781. if( IsX360())
  782. {
  783. pContextData->m_SemiStaticCmdsOut.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 );
  784. }
  785. CBCmdSetPixelShaderFlashlightState_t state;
  786. state.m_LightSampler = SHADER_SAMPLER13;
  787. state.m_DepthSampler = SHADER_SAMPLER14;
  788. state.m_ShadowNoiseSampler = SHADER_SAMPLER15;
  789. state.m_nColorConstant = 28;
  790. state.m_nAttenConstant = 13;
  791. state.m_nOriginConstant = 14;
  792. state.m_nDepthTweakConstant = 19;
  793. state.m_nScreenScaleConstant = 31;
  794. state.m_nWorldToTextureConstant = -1;
  795. state.m_bFlashlightNoLambert = false;
  796. state.m_bSinglePassFlashlight = bSinglePassFlashlight;
  797. #ifdef _PS3
  798. {
  799. pContextData->m_flashlightECB.SetPixelShaderFlashlightState( state );
  800. pContextData->m_flashlightECB.End();
  801. }
  802. #else
  803. {
  804. pContextData->m_SemiStaticCmdsOut.SetPixelShaderFlashlightState( state );
  805. }
  806. #endif
  807. }
  808. pContextData->m_SemiStaticCmdsOut.End();
  809. }
  810. }
  811. DYNAMIC_STATE
  812. {
  813. #ifdef _PS3
  814. CCommandBufferBuilder< CDynamicCommandStorageBuffer > DynamicCmdsOut;
  815. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_pStaticCmds );
  816. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_SemiStaticCmdsOut.Base() );
  817. if (hasFlashlight) ShaderApiFast( pShaderAPI )->ExecuteCommandBufferPPU( pContextData->m_flashlightECB.Base() );
  818. #else
  819. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  820. DynamicCmdsOut.Call( pContextData->m_pStaticCmds );
  821. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  822. #endif
  823. bool hasEnvmap = params[info.m_nEnvmap]->IsTexture();
  824. if( hasEnvmap )
  825. {
  826. DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER2, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, info.m_nEnvmap, info.m_nEnvmapFrame );
  827. }
  828. bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath;
  829. int nFixedLightingMode = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
  830. if( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
  831. {
  832. bVertexShaderFastPath = false;
  833. }
  834. bool bWorldNormal = ( nFixedLightingMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH );
  835. if ( bWorldNormal && IsPC() )
  836. {
  837. float vEyeDir[4];
  838. ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraDirection( vEyeDir );
  839. float flFarZ = ShaderApiFast( pShaderAPI )->GetFarZ();
  840. vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm
  841. vEyeDir[1] /= flFarZ;
  842. vEyeDir[2] /= flFarZ;
  843. DynamicCmdsOut.SetVertexShaderConstant4( 12, vEyeDir[0], vEyeDir[1], vEyeDir[2], 1.0f );
  844. }
  845. MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
  846. #if !defined( _X360 ) && !defined( _PS3 )
  847. if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
  848. {
  849. DECLARE_DYNAMIC_VERTEX_SHADER( lightmapped_4wayblend_vs30 );
  850. SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath );
  851. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmapped_4wayblend_vs30 );
  852. }
  853. else
  854. #endif
  855. {
  856. DECLARE_DYNAMIC_VERTEX_SHADER( lightmapped_4wayblend_vs20 );
  857. SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath );
  858. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmapped_4wayblend_vs20 );
  859. }
  860. // This block of logic is up here and is so verbose because the compiler on the Mac was previously
  861. // optimizing much of this away and allowing out of range values into the logic which ultimately
  862. // computes the dynamic index. Please leave this here and don't try to weave it into the dynamic
  863. // combo setting macros below.
  864. bool bPixelShaderFastPath = false;
  865. if ( pContextData->m_bPixelShaderFastPath )
  866. bPixelShaderFastPath = true;
  867. bool bFastPath = false;
  868. if ( bPixelShaderFastPath )
  869. bFastPath = true;
  870. if ( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
  871. {
  872. bPixelShaderFastPath = false;
  873. }
  874. bool bWriteDepthToAlpha = false;
  875. bool bWriteWaterFogToAlpha;
  876. if( pContextData->m_bFullyOpaque )
  877. {
  878. bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
  879. bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
  880. AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
  881. }
  882. else
  883. {
  884. //can't write a special value to dest alpha if we're actually using as-intended alpha
  885. bWriteDepthToAlpha = false;
  886. bWriteWaterFogToAlpha = false;
  887. }
  888. bool bFlashlightShadows = false;
  889. bool bUberlight = false;
  890. if( hasFlashlight && ( IsX360() || IsPS3() ) )
  891. {
  892. ShaderApiFast( pShaderAPI )->GetFlashlightShaderInfo( &bFlashlightShadows, &bUberlight );
  893. }
  894. else
  895. {
  896. // only do ambient light when not using flashlight
  897. float vAmbientColor[4] = { mat_ambient_light_r.GetFloat(), mat_ambient_light_g.GetFloat(), mat_ambient_light_b.GetFloat(), 0.0f };
  898. if ( g_pConfig->nFullbright == 1 )
  899. {
  900. vAmbientColor[0] = vAmbientColor[1] = vAmbientColor[2] = 0.0f;
  901. }
  902. DynamicCmdsOut.SetPixelShaderConstant( 31, vAmbientColor, 1 );
  903. }
  904. /* Time - used for debugging
  905. float vTimeConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  906. float flTime = pShaderAPI->CurrentTime();
  907. vTimeConst[0] = flTime;
  908. DynamicCmdsOut.SetPixelShaderConstant( 27, vTimeConst, 1 );
  909. //*/
  910. float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
  911. #if !defined( _X360 ) && !defined( _PS3 )
  912. if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
  913. {
  914. BOOL bCSMEnabled = pShaderAPI->IsCascadedShadowMapping() && !ToolsEnabled();
  915. if ( bCSMEnabled )
  916. {
  917. ITexture *pDepthTextureAtlas = NULL;
  918. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas, true );
  919. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  920. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  921. }
  922. pShaderAPI->SetBooleanPixelShaderConstant( 0, &bCSMEnabled, 1 );
  923. DECLARE_DYNAMIC_PIXEL_SHADER( lightmapped_4wayblend_ps30 );
  924. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bFastPath );
  925. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
  926. // Don't write fog to alpha if we're using translucency
  927. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
  928. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  929. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  930. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmapped_4wayblend_ps30 );
  931. }
  932. else
  933. #endif
  934. {
  935. if ( IsGameConsole() && pShaderAPI->IsCascadedShadowMapping() )
  936. {
  937. ITexture *pDepthTextureAtlas = NULL;
  938. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas, true );
  939. if ( pDepthTextureAtlas )
  940. {
  941. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  942. DynamicCmdsOut.SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  943. DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_13, &cascadeState.m_vLightDir.x, 1 );
  944. }
  945. }
  946. DECLARE_DYNAMIC_PIXEL_SHADER( lightmapped_4wayblend_ps20b );
  947. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bFastPath );
  948. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
  949. // Don't write fog to alpha if we're using translucency
  950. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
  951. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  952. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  953. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmapped_4wayblend_ps20b );
  954. }
  955. DynamicCmdsOut.End();
  956. #ifdef _PS3
  957. ShaderApiFast( pShaderAPI )->SetPixelShaderFogParams( 11 );
  958. #endif
  959. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  960. }
  961. pShader->Draw();
  962. if( IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest )
  963. {
  964. //Alpha testing makes it so we can't write to dest alpha
  965. //Writing to depth makes it so later polygons can't write to dest alpha either
  966. //This leads to situations with garbage in dest alpha.
  967. //Fix it now by converting depth to dest alpha for any pixels that just wrote.
  968. pShader->DrawEqualDepthToDestAlpha();
  969. }
  970. }
  971. void DrawLightmapped_4WayBlend_DX9_FastPath( int *dynVSIdx, int *dynPSIdx, CBaseVSShader *pShader, IMaterialVar** params,
  972. IShaderDynamicAPI *pShaderAPI, Lightmapped_4WayBlend_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr, BOOL bCSMEnabled )
  973. {
  974. CLightmapped_4WayBlend_DX9_Context *pContextData = reinterpret_cast< CLightmapped_4WayBlend_DX9_Context *> ( *pContextDataPtr );
  975. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  976. DynamicCmdsOut.Call( pContextData->m_pStaticCmds );
  977. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  978. bool hasEnvmap = params[info.m_nEnvmap]->IsTexture();
  979. if( hasEnvmap )
  980. {
  981. DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER2, TEXTURE_BINDFLAGS_NONE, info.m_nEnvmap, info.m_nEnvmapFrame );
  982. }
  983. DynamicCmdsOut.End();
  984. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  985. bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath;
  986. DECLARE_DYNAMIC_VERTEX_SHADER( lightmapped_4wayblend_vs30 );
  987. SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath );
  988. SET_DYNAMIC_VERTEX_SHADER( lightmapped_4wayblend_vs30 );
  989. float vAmbientColor[4] = { mat_ambient_light_r.GetFloat(), mat_ambient_light_g.GetFloat(), mat_ambient_light_b.GetFloat(), 0.0f };
  990. if ( g_pConfig->nFullbright == 1 )
  991. {
  992. vAmbientColor[0] = vAmbientColor[1] = vAmbientColor[2] = 0.0f;
  993. }
  994. pShaderAPI->SetPixelShaderConstant( 31, vAmbientColor, 1 );
  995. pShaderAPI->SetBooleanPixelShaderConstant( 0, (BOOL*)&bCSMEnabled, 1 );
  996. if ( bCSMEnabled )
  997. {
  998. ITexture *pDepthTextureAtlas = NULL;
  999. const CascadedShadowMappingState_t &cascadeState = pShaderAPI->GetCascadedShadowMappingState( &pDepthTextureAtlas, true );
  1000. pShader->BindTexture( SHADER_SAMPLER15, TEXTURE_BINDFLAGS_SHADOWDEPTH, pDepthTextureAtlas, 0 );
  1001. pShaderAPI->SetPixelShaderConstant( 64, &cascadeState.m_vLightColor.x, CASCADED_SHADOW_MAPPING_CONSTANT_BUFFER_SIZE );
  1002. }
  1003. bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath;
  1004. float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
  1005. DECLARE_DYNAMIC_PIXEL_SHADER( lightmapped_4wayblend_ps30 );
  1006. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath );
  1007. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
  1008. MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
  1009. // Don't write fog to alpha if we're using translucency
  1010. bool bWriteDepthToAlpha = false;
  1011. bool bWriteWaterFogToAlpha;
  1012. if( pContextData->m_bFullyOpaque )
  1013. {
  1014. bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
  1015. bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
  1016. }
  1017. else
  1018. {
  1019. //can't write a special value to dest alpha if we're actually using as-intended alpha
  1020. bWriteDepthToAlpha = false;
  1021. bWriteWaterFogToAlpha = false;
  1022. }
  1023. bool bFlashlightShadows = false;
  1024. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
  1025. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  1026. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  1027. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmapped_4wayblend_ps30 );
  1028. *dynVSIdx = _vshIndex.GetIndex();
  1029. *dynPSIdx = _pshIndex.GetIndex();
  1030. }