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.

592 lines
26 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. #include "BaseVSShader.h"
  3. #include "customhero_dx9_helper.h"
  4. #include "cpp_shader_constant_register_map.h"
  5. /*
  6. #include "mathlib/VMatrix.h"
  7. #include "convar.h"
  8. */
  9. // Auto generated inc files
  10. #include "customhero_vs20.inc"
  11. #include "customhero_ps20.inc"
  12. #include "customhero_ps20b.inc"
  13. #include "customhero_vs30.inc"
  14. #include "customhero_ps30.inc"
  15. #include "shaderlib/commandbuilder.h"
  16. void InitParamsCustomHero( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, CustomHeroVars_t &info )
  17. {
  18. // Set material parameter default values
  19. SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFresnelWarp, kDefaultFresnelWarp );
  20. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nFlashlightTextureFrame, 0 );
  21. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDetail1Scale, kDefaultDetailScale );
  22. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nDetail1Frame, kDefaultDetailFrame );
  23. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nDetail1BlendMode, kDefaultDetailBlendMode );
  24. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDetail1BlendFactor, kDefaultDetail1BlendFactor );
  25. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDetail1BlendToFull, kDefaultBlendToFull );
  26. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDetail2Scale, kDefaultDetailScale );
  27. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nDetail2Frame, kDefaultDetailFrame );
  28. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nDetail2BlendMode, kDefaultDetailBlendMode );
  29. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDetail2BlendFactor, kDefaultDetail2BlendFactor );
  30. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDiffuseWarpBlendToFull, kDefaultBlendToFull );
  31. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nColorWarpBlendFactor, kDefaultColorWarpBlendFactor );
  32. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nFresnelColorWarpBlendToFull, kDefaultBlendToFull );
  33. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecularExponent, kDefaultExponent );
  34. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecularExponentBlendToFull, kDefaultBlendToFull );
  35. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecularBlendToFull, kDefaultBlendToFull );
  36. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nSpecularColor, kDefaultSpecularColor, 3 );
  37. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecularScale, kDefaultIntensity );
  38. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nEnvMapBlendToFull, kDefaultBlendToFull );
  39. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nEnvMapBlendToFull, kDefaultBlendToFull );
  40. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nMetallnessBlendToFull, kDefaultBlendToFull );
  41. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nAmbientScale, kDefaultAmbientScale );
  42. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nRimLightScale, kDefaultIntensity );
  43. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSelfIllumBlendToFull, kDefaultBlendToFull );
  44. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  45. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
  46. }
  47. void InitCustomHero( CBaseVSShader *pShader, IMaterialVar** params, CustomHeroVars_t &info )
  48. {
  49. // Load textures
  50. if ( ( info.m_nBaseTexture != -1 ) && params[info.m_nBaseTexture]->IsDefined() )
  51. {
  52. pShader->LoadTexture( info.m_nBaseTexture );
  53. }
  54. if ( ( info.m_nNormalMap != -1 ) && params[info.m_nNormalMap]->IsDefined() )
  55. {
  56. pShader->LoadTexture( info.m_nNormalMap );
  57. }
  58. if ( ( info.m_nMaskMap1 != -1 ) && params[info.m_nMaskMap1]->IsDefined() )
  59. {
  60. pShader->LoadTexture( info.m_nMaskMap1 );
  61. }
  62. if ( ( info.m_nMaskMap2 != -1 ) && params[info.m_nMaskMap2]->IsDefined() )
  63. {
  64. pShader->LoadTexture( info.m_nMaskMap2 );
  65. }
  66. if ( ( info.m_nDiffuseWarp != -1 ) && params[info.m_nDiffuseWarp]->IsDefined() )
  67. {
  68. pShader->LoadTexture( info.m_nDiffuseWarp );
  69. }
  70. if ( ( info.m_nFresnelColorWarp != -1 ) && params[info.m_nFresnelColorWarp]->IsDefined() )
  71. {
  72. pShader->LoadTexture( info.m_nFresnelColorWarp );
  73. }
  74. if ( ( info.m_nColorWarp != -1 ) && params[info.m_nColorWarp]->IsDefined() )
  75. {
  76. pShader->LoadTexture( info.m_nColorWarp );
  77. }
  78. if ( ( info.m_nDetail1 != -1 ) && params[info.m_nDetail1]->IsDefined() )
  79. {
  80. pShader->LoadTexture( info.m_nDetail1 );
  81. }
  82. if ( ( info.m_nDetail2 != -1 ) && params[info.m_nDetail2]->IsDefined() )
  83. {
  84. pShader->LoadTexture( info.m_nDetail2 );
  85. }
  86. if ( ( info.m_nEnvMap != -1 ) && params[info.m_nEnvMap]->IsDefined() )
  87. {
  88. pShader->LoadCubeMap( info.m_nEnvMap );
  89. }
  90. if ( ( info.m_nFlashlightTexture != -1 ) && params[info.m_nFlashlightTexture]->IsDefined() )
  91. {
  92. pShader->LoadTexture( info.m_nFlashlightTexture );
  93. }
  94. if ( ( info.m_nFresnelWarp != -1 ) && params[info.m_nFresnelWarp]->IsDefined() )
  95. {
  96. pShader->LoadTexture( info.m_nFresnelWarp );
  97. }
  98. }
  99. class CCustomHero_DX9_Context : public CBasePerMaterialContextData
  100. {
  101. public:
  102. CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut;
  103. };
  104. void DrawCustomHero( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
  105. IShaderShadow* pShaderShadow, CustomHeroVars_t &info, VertexCompressionType_t vertexCompression,
  106. CBasePerMaterialContextData **pContextDataPtr )
  107. {
  108. CCustomHero_DX9_Context *pContextData = reinterpret_cast< CCustomHero_DX9_Context *> ( *pContextDataPtr );
  109. bool bHasFlashlight = pShader->UsingFlashlight( params );
  110. bool bAlphaBlend = IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT );
  111. bool bDetail1 = ( info.m_nDetail1 != -1 )&& params[info.m_nDetail1]->IsTexture() && ( info.m_nDetail1BlendMode != -1 )&& ( params[info.m_nDetail1BlendMode]->GetIntValue() > 0 );
  112. if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) )
  113. {
  114. bool bMaskMap1 = ( info.m_nMaskMap1 != -1 ) && params[info.m_nMaskMap1]->IsTexture();
  115. bool bMaskMap2 = ( info.m_nMaskMap2 != -1 ) && params[info.m_nMaskMap2]->IsTexture();
  116. bool bDiffuseWarp = ( info.m_nDiffuseWarp != -1 )&& params[info.m_nDiffuseWarp]->IsTexture();
  117. bool bColorWarp = ( info.m_nColorWarp != -1 )&& params[info.m_nColorWarp]->IsTexture();
  118. bool bFresnelColorWarp = ( info.m_nFresnelColorWarp != -1 )&& params[info.m_nFresnelColorWarp]->IsTexture();
  119. bool bEnvMap = ( info.m_nEnvMap != -1 )&& params[info.m_nEnvMap]->IsTexture();
  120. int nDetail1BlendMode = ( info.m_nDetail1BlendMode != -1 )? params[info.m_nDetail1BlendMode]->GetIntValue() : kDefaultDetailBlendMode;
  121. nDetail1BlendMode = bDetail1 ? clamp( nDetail1BlendMode, 0, kMaxDetailBlendMode ): 0;
  122. if ( pShader->IsSnapshotting() )
  123. {
  124. // Set stream format (note that this shader supports compression)
  125. unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
  126. int nTexCoordCount = 1;
  127. int userDataSize = 4;
  128. int texCoordDims[4] = { 2, 2, 2, 2 };
  129. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, texCoordDims, userDataSize );
  130. int nShadowFilterMode = 0;
  131. if ( bHasFlashlight )
  132. {
  133. nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats
  134. }
  135. // Vertex Shader
  136. if ( g_pHardwareConfig->GetDXSupportLevel() >= 95 )
  137. {
  138. //looks the same but we'll be enabling vs30-only effects in the shader
  139. // Is it necessary to do this?
  140. DECLARE_STATIC_VERTEX_SHADER( customhero_vs30 );
  141. SET_STATIC_VERTEX_SHADER_COMBO( DETAIL1, bDetail1 );
  142. SET_STATIC_VERTEX_SHADER( customhero_vs30 );
  143. }
  144. else
  145. {
  146. DECLARE_STATIC_VERTEX_SHADER( customhero_vs20 );
  147. SET_STATIC_VERTEX_SHADER_COMBO( DETAIL1, bDetail1 );
  148. SET_STATIC_VERTEX_SHADER( customhero_vs20 );
  149. }
  150. // Pixel Shader
  151. if ( g_pHardwareConfig->GetDXSupportLevel() >= 95 )
  152. {
  153. DECLARE_STATIC_PIXEL_SHADER( customhero_ps30 );
  154. SET_STATIC_PIXEL_SHADER_COMBO( ALPHABLEND, bAlphaBlend );
  155. //TODO: enable flashlight
  156. //SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  157. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP1, bMaskMap1 );
  158. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP2, bMaskMap2 );
  159. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1, bDetail1 ); // no combo for detail2 because it should always be available for status effects
  160. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1BLENDMODE, nDetail1BlendMode );
  161. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEWARP, bDiffuseWarp );
  162. SET_STATIC_PIXEL_SHADER_COMBO( COLORWARP, bColorWarp );
  163. SET_STATIC_PIXEL_SHADER_COMBO( FRESNELCOLORWARP, bFresnelColorWarp );
  164. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAP, bEnvMap );
  165. SET_STATIC_PIXEL_SHADER( customhero_ps30 );
  166. }
  167. else if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  168. {
  169. DECLARE_STATIC_PIXEL_SHADER( customhero_ps20b );
  170. // no combo for detail2 because it should always be available for status effects
  171. SET_STATIC_PIXEL_SHADER_COMBO( ALPHABLEND, bAlphaBlend );
  172. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP1, bMaskMap1 );
  173. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP2, bMaskMap2 );
  174. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1, bDetail1 );
  175. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1BLENDMODE, nDetail1BlendMode );
  176. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEWARP, bDiffuseWarp );
  177. SET_STATIC_PIXEL_SHADER_COMBO( COLORWARP, bColorWarp );
  178. SET_STATIC_PIXEL_SHADER_COMBO( FRESNELCOLORWARP, bFresnelColorWarp );
  179. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAP, bEnvMap );
  180. SET_STATIC_PIXEL_SHADER( customhero_ps20b );
  181. }
  182. else
  183. {
  184. DECLARE_STATIC_PIXEL_SHADER( customhero_ps20 );
  185. // no combo for detail2 because it should always be available for status effects
  186. SET_STATIC_PIXEL_SHADER_COMBO( ALPHABLEND, bAlphaBlend );
  187. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP1, bMaskMap1 );
  188. SET_STATIC_PIXEL_SHADER_COMBO( MASKMAP2, bMaskMap2 );
  189. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1, bDetail1 );
  190. SET_STATIC_PIXEL_SHADER_COMBO( DETAIL1BLENDMODE, nDetail1BlendMode );
  191. SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEWARP, bDiffuseWarp );
  192. SET_STATIC_PIXEL_SHADER_COMBO( COLORWARP, bColorWarp );
  193. SET_STATIC_PIXEL_SHADER_COMBO( ENVMAP, bEnvMap );
  194. SET_STATIC_PIXEL_SHADER( customhero_ps20 );
  195. }
  196. // Textures
  197. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // [sRGB] Base
  198. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  199. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Normal
  200. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
  201. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // [sRGB] Detail2 for status effects
  202. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true );
  203. pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); // Fresnel warp
  204. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER14, false );
  205. if( bMaskMap1 )
  206. {
  207. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Mask set 1
  208. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false );
  209. }
  210. if( bMaskMap2 )
  211. {
  212. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Mask set 2
  213. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
  214. }
  215. if( bDetail1 )
  216. {
  217. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // [sRGB] Detail1
  218. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true );
  219. }
  220. if( bDiffuseWarp )
  221. {
  222. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Diffuse Warp
  223. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false );
  224. }
  225. if( bFresnelColorWarp )
  226. {
  227. pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // [sRGB] Fresnel Color Warp
  228. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true );
  229. }
  230. if( bColorWarp )
  231. {
  232. pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // [sRGB] Base Color Warp
  233. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true );
  234. }
  235. if( bEnvMap )
  236. {
  237. pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // [sRGB] Env map
  238. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true );
  239. }
  240. if ( bHasFlashlight )
  241. {
  242. pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Shadow depth map
  243. pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER11 );
  244. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER11, false );
  245. pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Noise map
  246. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, false );
  247. pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); //[sRGB] Flashlight cookie
  248. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true );
  249. // Flashlight passes - additive blending
  250. pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
  251. pShaderShadow->EnableAlphaWrites( false );
  252. pShaderShadow->EnableDepthWrites( false );
  253. }
  254. if ( bAlphaBlend )
  255. {
  256. // Base pass - alpha blending (regular translucency)
  257. pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  258. pShaderShadow->EnableAlphaWrites( false );
  259. pShaderShadow->EnableDepthWrites( true );
  260. }
  261. else
  262. {
  263. // Base pass - opaque blending
  264. pShader->DisableAlphaBlending();
  265. pShaderShadow->EnableAlphaWrites( true );
  266. pShaderShadow->EnableDepthWrites( true );
  267. }
  268. pShaderShadow->EnableSRGBWrite( true );
  269. // Per-instance state
  270. pShader->PI_BeginCommandBuffer();
  271. pShader->PI_SetVertexShaderAmbientLightCube();
  272. pShader->PI_SetPixelShaderAmbientLightCube( 4 ); // c4-c9
  273. pShader->PI_SetPixelShaderLocalLighting( PSREG_LIGHT_INFO_ARRAY ); // c20-c25
  274. pShader->PI_EndCommandBuffer();
  275. }
  276. if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) )
  277. {
  278. if ( !pContextData ) // make sure allocated
  279. {
  280. pContextData = new CCustomHero_DX9_Context;
  281. *pContextDataPtr = pContextData;
  282. }
  283. pContextData->m_bMaterialVarsChanged = false;
  284. pContextData->m_SemiStaticCmdsOut.Reset();
  285. ///////////////////////////
  286. // Semi-static block
  287. ///////////////////////////
  288. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  289. // VS consts
  290. flConsts[0] = IS_PARAM_DEFINED( info.m_nDetail1Scale ) ? params[info.m_nDetail1Scale]->GetFloatValue() : kDefaultDetailScale;
  291. flConsts[1] = IS_PARAM_DEFINED( info.m_nDetail2Scale ) ? params[info.m_nDetail2Scale]->GetFloatValue() : kDefaultDetailScale;
  292. flConsts[2] = IS_PARAM_DEFINED( info.m_nAmbientScale ) ? params[info.m_nAmbientScale]->GetFloatValue() : kDefaultAmbientScale;
  293. flConsts[3] = 0; // Empty
  294. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, flConsts, 1 );
  295. if ( info.m_nBaseTextureTransform != -1 )
  296. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBaseTextureTransform ); // 1-2
  297. if ( IS_PARAM_DEFINED( info.m_nBaseTextureTransform ) )
  298. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nDetail1TextureTransform, info.m_nDetail1Scale ); // 3-4
  299. else
  300. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBaseTextureTransform, info.m_nDetail1Scale );
  301. if ( IS_PARAM_DEFINED( info.m_nBaseTextureTransform ) )
  302. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nDetail2TextureTransform, info.m_nDetail2Scale ); // 5-6
  303. else
  304. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nBaseTextureTransform, info.m_nDetail2Scale );
  305. // 8 free
  306. // PS Constants
  307. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, BASETEXTURE, -1 );
  308. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, false, info.m_nNormalMap, -1 );
  309. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER14, info.m_nFresnelWarp, -1);
  310. if( bMaskMap1 )
  311. {
  312. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nMaskMap1, -1 );
  313. }
  314. if( bMaskMap2 )
  315. {
  316. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nMaskMap2, -1 );
  317. }
  318. if( bDiffuseWarp )
  319. {
  320. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nDiffuseWarp, -1 );
  321. }
  322. if( bFresnelColorWarp )
  323. {
  324. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nFresnelColorWarp, -1 );
  325. }
  326. if( bColorWarp )
  327. {
  328. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nColorWarp, -1 );
  329. }
  330. if( bEnvMap )
  331. {
  332. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER10, info.m_nEnvMap, -1 );
  333. }
  334. float flDetail1BlendToFull = IS_PARAM_DEFINED( info.m_nDetail1BlendToFull ) ? clamp( params[info.m_nDetail1BlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  335. float flDiffuseWarpBlendToFull = IS_PARAM_DEFINED( info.m_nDiffuseWarpBlendToFull ) ? clamp( params[info.m_nDiffuseWarpBlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  336. float flSpecularBlendToFull = IS_PARAM_DEFINED( info.m_nSpecularBlendToFull ) ? clamp( params[info.m_nSpecularBlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  337. float flSpecularExponentBlendToFull = IS_PARAM_DEFINED( info.m_nSpecularExponentBlendToFull ) ? clamp( params[info.m_nSpecularExponentBlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  338. float flReflectionsTintByBaseBlendToNone = IS_PARAM_DEFINED( info.m_nReflectionsTintByBaseBlendToNone ) ? clamp( params[info.m_nReflectionsTintByBaseBlendToNone]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  339. float flEnvMapBlendToFull = IS_PARAM_DEFINED( info.m_nEnvMapBlendToFull ) ? clamp( params[info.m_nEnvMapBlendToFull]->GetFloatValue(), 0.0f, 1.0 ): kDefaultBlendToFull;
  340. float flMetallnessBlendToFull = IS_PARAM_DEFINED( info.m_nMetallnessBlendToFull ) ? clamp( params[info.m_nMetallnessBlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  341. float flSelfIllumBlendToFull = IS_PARAM_DEFINED( info.m_nSelfIllumBlendToFull ) ? clamp( params[info.m_nSelfIllumBlendToFull]->GetFloatValue(), 0.0f, 1.0f ): kDefaultBlendToFull;
  342. if( IS_PARAM_DEFINED( info.m_nSpecularColor ) )
  343. params[info.m_nSpecularColor]->GetVecValue( flConsts, 3 );
  344. else
  345. memcpy( flConsts, kDefaultSpecularColor, sizeof( kDefaultSpecularColor ) );
  346. flConsts[3] = IS_PARAM_DEFINED( info.m_nSpecularScale ) ? params[info.m_nSpecularScale]->GetFloatValue() : kDefaultIntensity;
  347. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 0, flConsts, 1 );
  348. flConsts[0] = IS_PARAM_DEFINED( info.m_nSpecularExponent ) ? params[info.m_nSpecularExponent]->GetFloatValue(): kDefaultExponent;
  349. flConsts[1] = IS_PARAM_DEFINED( info.m_nRimLightScale ) ? params[info.m_nRimLightScale]->GetFloatValue() : kDefaultIntensity;
  350. flConsts[2] = 0; //free
  351. flConsts[3] = 0; //free
  352. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 1, flConsts, 1 );
  353. flConsts[0] = IS_PARAM_DEFINED( info.m_nColorWarpBlendFactor ) ? params[info.m_nColorWarpBlendFactor]->GetFloatValue(): kDefaultColorWarpBlendFactor;
  354. flConsts[1] = IS_PARAM_DEFINED( info.m_nFresnelColorWarpBlendToFull ) ? params[info.m_nFresnelColorWarpBlendToFull]->GetFloatValue(): kDefaultIntensity;
  355. flConsts[2] = IS_PARAM_DEFINED( info.m_nDetail1BlendFactor ) ? params[info.m_nDetail1BlendFactor]->GetFloatValue() : kDefaultDetail1BlendFactor;
  356. flConsts[3] = IS_PARAM_DEFINED( info.m_nDetail2BlendFactor ) ? params[info.m_nDetail2BlendFactor]->GetFloatValue() : kDefaultDetail2BlendFactor;
  357. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, flConsts, 1 );
  358. // 10 is free
  359. // 19 is free
  360. flConsts[0] = flDetail1BlendToFull;
  361. flConsts[1] = flDiffuseWarpBlendToFull;
  362. flConsts[2] = flMetallnessBlendToFull;
  363. flConsts[3] = flSelfIllumBlendToFull;
  364. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 26, flConsts, 1 );
  365. flConsts[0] = flSpecularBlendToFull;
  366. flConsts[1] = flEnvMapBlendToFull;
  367. flConsts[2] = flReflectionsTintByBaseBlendToNone;
  368. flConsts[3] = flSpecularExponentBlendToFull;
  369. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 27, flConsts, 1 );
  370. // 29 is free
  371. // 30 is free
  372. pContextData->m_SemiStaticCmdsOut.End();
  373. }
  374. }
  375. if ( pShaderAPI ) //DYNAMIC_STATE
  376. {
  377. CCommandBufferBuilder< CFixedCommandStorageBuffer< 400 > > DynamicCmdsOut;
  378. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  379. ///////////////////////////
  380. // dynamic block
  381. ///////////////////////////
  382. bool bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha() && !bAlphaBlend;
  383. bool bWriteWaterFogToAlpha = MATERIAL_FOG_LINEAR_BELOW_FOG_Z && !bAlphaBlend;
  384. int nDetail2BlendMode = IS_PARAM_DEFINED( info.m_nDetail2BlendMode ) ? ( params[info.m_nDetail2BlendMode]->GetIntValue() ): kDefaultDetailBlendMode;
  385. nDetail2BlendMode = clamp( nDetail2BlendMode, 0, kMaxDetailBlendMode );
  386. LightState_t lightState = { 0, false, false };
  387. pShaderAPI->GetDX9LightState( &lightState );
  388. ///////////////////////
  389. // VERTEX SHADER SETUP
  390. ///////////////////////
  391. // Set Vertex Shader Combos
  392. if ( g_pHardwareConfig->GetDXSupportLevel() >= 95 )
  393. {
  394. //looks the same but we'll be enabling vs30-only effects in the shader
  395. // Is it necessary to do this?
  396. DECLARE_DYNAMIC_VERTEX_SHADER( customhero_vs30 );
  397. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  398. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  399. SET_DYNAMIC_VERTEX_SHADER( customhero_vs30 );
  400. }
  401. else
  402. {
  403. DECLARE_DYNAMIC_VERTEX_SHADER( customhero_vs20 );
  404. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  405. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  406. SET_DYNAMIC_VERTEX_SHADER( customhero_vs20 );
  407. }
  408. // VS constants
  409. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  410. // TODO: Move out of VS into PS for ps2.0b
  411. pShaderAPI->GetWorldSpaceCameraPosition( flConsts );
  412. flConsts[3] = 0.0f;
  413. DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, flConsts, 1 );
  414. //////////////////////
  415. // PIXEL SHADER SETUP
  416. //////////////////////
  417. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail2, info.m_nDetail2Frame );
  418. if ( bDetail1 )
  419. {
  420. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nDetail1, info.m_nDetail1Frame );
  421. }
  422. flConsts[0] = 0.0f; //Empty
  423. flConsts[1] = 0.0f; //Empty
  424. flConsts[2] = 0.0f; //Empty
  425. flConsts[3] = bWriteDepthToAlpha ? 1.0f : 0.0f;
  426. DynamicCmdsOut.SetPixelShaderConstant( 11, flConsts, 1 );
  427. // TODO: Disable for PS2.0? Vertex fog only?
  428. DynamicCmdsOut.SetPixelShaderFogParams( 12 );
  429. // TODO: Remove? Can't use in PS2.0
  430. bool bFlashlightShadows = false;
  431. if ( bHasFlashlight && g_pHardwareConfig->SupportsPixelShaders_2_b() )
  432. {
  433. Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 );
  434. VMatrix worldToTexture;
  435. ITexture *pFlashlightDepthTexture;
  436. FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
  437. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER13, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame );
  438. bFlashlightShadows = state.m_bEnableShadows;
  439. SetFlashLightColorFromState( state, pShaderAPI, 28 );
  440. if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows )
  441. {
  442. DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, pFlashlightDepthTexture, -1 );
  443. DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_SHADOW_NOISE_2D );
  444. }
  445. float atten[4], pos[4], tweaks[4];
  446. atten[0] = state.m_fConstantAtten; // Set the flashlight attenuation factors
  447. atten[1] = state.m_fLinearAtten;
  448. atten[2] = state.m_fQuadraticAtten;
  449. atten[3] = state.m_FarZAtten;
  450. DynamicCmdsOut.SetPixelShaderConstant( 13, atten, 1 );
  451. pos[0] = state.m_vecLightOrigin[0]; // Set the flashlight origin
  452. pos[1] = state.m_vecLightOrigin[1];
  453. pos[2] = state.m_vecLightOrigin[2];
  454. pos[3] = state.m_FarZ;
  455. DynamicCmdsOut.SetPixelShaderConstant( 14, pos, 1 ); // steps on rim boost
  456. DynamicCmdsOut.SetPixelShaderConstant( 15, worldToTexture.Base(), 4 ); // c15-c18
  457. // Tweaks associated with a given flashlight
  458. tweaks[0] = ShadowFilterFromState( state );
  459. tweaks[1] = ShadowAttenFromState( state );
  460. pShader->HashShadow2DJitter( state.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
  461. DynamicCmdsOut.SetPixelShaderConstant( 2, tweaks, 1 );
  462. // Dimensions of screen, used for screen-space noise map sampling
  463. float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
  464. int nWidth, nHeight;
  465. pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
  466. int nTexWidth, nTexHeight;
  467. pShaderAPI->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D );
  468. vScreenScale[0] = (float) nWidth / nTexWidth;
  469. vScreenScale[1] = (float) nHeight / nTexHeight;
  470. DynamicCmdsOut.SetPixelShaderConstant( 31, vScreenScale, 1 );
  471. }
  472. DynamicCmdsOut.End();
  473. // end dynamic block
  474. pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  475. // Set Pixel Shader Combos
  476. if ( g_pHardwareConfig->GetDXSupportLevel() >= 95 )
  477. {
  478. DECLARE_DYNAMIC_PIXEL_SHADER( customhero_ps30 );
  479. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  480. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  481. SET_DYNAMIC_PIXEL_SHADER_COMBO( DETAIL2BLENDMODE, nDetail2BlendMode );
  482. //TODO: enable flashlight on ps30
  483. //SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  484. //SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  485. SET_DYNAMIC_PIXEL_SHADER( customhero_ps30 );
  486. }
  487. else if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  488. {
  489. DECLARE_DYNAMIC_PIXEL_SHADER( customhero_ps20b );
  490. SET_DYNAMIC_PIXEL_SHADER_COMBO( DETAIL2BLENDMODE, nDetail2BlendMode );
  491. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  492. SET_DYNAMIC_PIXEL_SHADER( customhero_ps20b );
  493. }
  494. else
  495. {
  496. DECLARE_DYNAMIC_PIXEL_SHADER( customhero_ps20 );
  497. SET_DYNAMIC_PIXEL_SHADER_COMBO( DETAIL2BLENDMODE, nDetail2BlendMode );
  498. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
  499. SET_DYNAMIC_PIXEL_SHADER( customhero_ps20 );
  500. }
  501. }
  502. pShader->Draw();
  503. }