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.

648 lines
28 KiB

  1. //========= Copyright � 1996-2007, Valve Corporation, All rights reserved. ============//
  2. #include "BaseVSShader.h"
  3. #include "Blob_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 "blob_vs30.inc"
  11. #include "blob_ps30.inc"
  12. #include "blob_arm_vs20.inc"
  13. #include "blob_arm_ps20b.inc"
  14. void InitParamsBlob( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, BlobVars_t &info )
  15. {
  16. // Set material parameter default values
  17. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nBackSurface, kDefaultBackSurface );
  18. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nUVScale, kDefaultUVScale );
  19. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nBumpStrength, kDefaultBumpStrength );
  20. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nFresnelBumpStrength, kDefaultFresnelBumpStrength );
  21. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nInteriorEnable, kDefaultInteriorEnable );
  22. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorFogStrength, kDefaultInteriorFogStrength );
  23. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorFogLimit, kDefaultInteriorFogLimit );
  24. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorFogNormalBoost, kDefaultInteriorFogNormalBoost );
  25. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorBackgroundBoost, kDefaultInteriorBackgroundBoost );
  26. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorAmbientScale, kDefaultInteriorAmbientScale );
  27. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorBackLightScale, kDefaultInteriorBackLightScale );
  28. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nInteriorColor, kDefaultInteriorColor, 3 );
  29. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorRefractStrength, kDefaultInteriorRefractStrength );
  30. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nInteriorRefractBlur, kDefaultInteriorRefractBlur );
  31. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nFresnelParams, kDefaultFresnelParams, 3 );
  32. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nBaseColorTint, kDefaultBaseColorTint, 3 );
  33. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nDiffuseScale, kDefaultDiffuseScale );
  34. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecExp, kDefaultSpecExp );
  35. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecScale, kDefaultSpecScale );
  36. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecExp2, kDefaultSpecExp );
  37. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nSpecScale2, kDefaultSpecScale );
  38. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nRimLightExp, kDefaultRimLightExp );
  39. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nRimLightScale, kDefaultRimLightScale );
  40. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nSelfIllumFresnelEnable, kDefaultSelfIllumFresnelEnable );
  41. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nSelfIllumFresnelParams, kDefaultSelfIllumFresnelParams, 3 );
  42. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nSelfIllumTint, kDefaultSelfIllumTint, 3 );
  43. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nUVProjOffset, kDefaultUVProjOffset, 3 );
  44. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nBBMin, kDefaultBB, 3 );
  45. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nBBMax, kDefaultBB, 3 );
  46. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nArmature, kDefaultArmature );
  47. // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture
  48. Assert( info.m_nFlashlightTexture >= 0 );
  49. if ( g_pHardwareConfig->SupportsBorderColor() )
  50. {
  51. params[info.m_nFlashlightTexture]->SetStringValue( "effects/flashlight_border" );
  52. }
  53. else
  54. {
  55. params[info.m_nFlashlightTexture]->SetStringValue( "effects/flashlight001" );
  56. }
  57. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nFlashlightTextureFrame, 0 );
  58. SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nArmColorTint, kDefaultArmColorTint, 3 );
  59. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nArmWiden, kDefaultArmWiden );
  60. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nArmWidthExp, kDefaultArmWidthExp );
  61. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nArmWidthScale, kDefaultArmWidthScale );
  62. SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nArmWidthBias, kDefaultArmWidthBias );
  63. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nAnimateArmPulses, kDefaultAnimateArmPulses );
  64. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nVolumeTex, kDefaultVolumeTex );
  65. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nBumpFrame, kDefaultBumpFrame )
  66. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nGlowScale, kDefaultGlowScale );
  67. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nPulse, kDefaultPulse );
  68. SET_PARAM_INT_IF_NOT_DEFINED( info.m_nContactShadows, kDefaultContactShadows );
  69. if ( IS_PARAM_DEFINED( info.m_nPulse ) && params[info.m_nPulse]->GetIntValue() &&
  70. IS_PARAM_DEFINED( info.m_nContactShadows ) && params[info.m_nContactShadows]->GetIntValue() )
  71. {
  72. Warning( "ERROR: material (%s) has invalid settings - contactShadows and pulse cannot both be set to 1\n", pMaterialName );
  73. params[info.m_nContactShadows]->SetIntValue( 0 );
  74. }
  75. // Set material flags
  76. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  77. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
  78. //SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  79. //SET_FLAGS( MATERIAL_VAR_TRANSLUCENT );
  80. // This flag is turned off even though the shader needs the full framebuffer texture.
  81. // The blob client code kicks off updating the framebuffer texture explicitly once it's done with drawing the innards.
  82. if ( params[info.m_nInteriorEnable]->IsDefined() && params[info.m_nInteriorEnable]->GetIntValue() != 0 )
  83. {
  84. SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
  85. }
  86. }
  87. void InitBlob( CBaseVSShader *pShader, IMaterialVar** params, BlobVars_t &info )
  88. {
  89. // Load textures
  90. if ( (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsDefined() )
  91. {
  92. pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB );
  93. }
  94. if ( (info.m_nNormalMap != -1) && params[info.m_nNormalMap]->IsDefined() )
  95. {
  96. pShader->LoadTexture( info.m_nNormalMap );
  97. }
  98. if ( (info.m_nSpecMap != -1) && params[info.m_nSpecMap]->IsDefined() )
  99. {
  100. pShader->LoadTexture( info.m_nSpecMap );
  101. }
  102. if ( (info.m_nLightWarpTexture != -1) && params[info.m_nLightWarpTexture]->IsDefined() )
  103. {
  104. pShader->LoadTexture( info.m_nLightWarpTexture, TEXTUREFLAGS_SRGB );
  105. }
  106. if ( (info.m_nFresnelWarpTexture != -1) && params[info.m_nFresnelWarpTexture]->IsDefined() )
  107. {
  108. pShader->LoadTexture( info.m_nFresnelWarpTexture );
  109. }
  110. if ( (info.m_nOpacityTexture != -1) && params[info.m_nOpacityTexture]->IsDefined() )
  111. {
  112. pShader->LoadTexture( info.m_nOpacityTexture );
  113. }
  114. if ( (info.m_nFlashlightTexture != -1) && params[info.m_nFlashlightTexture]->IsDefined() )
  115. {
  116. pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB );
  117. }
  118. }
  119. void DrawBlob( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
  120. IShaderShadow* pShaderShadow, BlobVars_t &info, VertexCompressionType_t vertexCompression )
  121. {
  122. if ( (info.m_nArmature != -1) && ( params[info.m_nArmature]->GetIntValue() > 0 ) )
  123. {
  124. DrawArmature( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, 0 );
  125. DrawArmature( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, 1 );
  126. return;
  127. }
  128. bool bHasFlashlight = pShader->UsingFlashlight( params );
  129. bool bBackSurface = (info.m_nBackSurface != -1) && ( params[info.m_nBackSurface]->GetIntValue() > 0 );
  130. bool bLightWarp = (info.m_nLightWarpTexture != -1) && params[info.m_nLightWarpTexture]->IsDefined();
  131. bool bFresnelWarp = (info.m_nFresnelWarpTexture != -1) && params[info.m_nFresnelWarpTexture]->IsDefined();
  132. bool bOpacityTexture = (info.m_nOpacityTexture != -1) && params[info.m_nOpacityTexture]->IsDefined();
  133. bool bInteriorLayer = (info.m_nInteriorEnable != -1) && ( params[info.m_nInteriorEnable]->GetIntValue() > 0 );
  134. bool bSelfIllumFresnel = (info.m_nSelfIllumFresnelEnable != -1) && ( params[info.m_nSelfIllumFresnelEnable]->GetIntValue() > 0 );
  135. bool bVolumeTex = (info.m_nVolumeTex != -1) && ( params[info.m_nVolumeTex]->GetIntValue() > 0 );
  136. bool bContactShadows = (info.m_nContactShadows != -1) && ( params[info.m_nContactShadows]->GetIntValue() > 0 );
  137. bool bPulse = (info.m_nPulse != -1) && ( params[info.m_nPulse]->GetIntValue() > 0 );
  138. SHADOW_STATE
  139. {
  140. // Set stream format (note that this shader supports compression)
  141. unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
  142. int nTexCoordCount = 1;
  143. int userDataSize = 0;
  144. int texCoordDims[4] = { 4, 4, 4, 4 };
  145. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, texCoordDims, userDataSize );
  146. ShadowFilterMode_t nShadowFilterMode = SHADOWFILTERMODE_DEFAULT;
  147. if ( bHasFlashlight )
  148. {
  149. nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode( false /* bForceLowQuality */, true /* bPS30 */ ); // Based upon vendor and device dependent formats
  150. }
  151. // Vertex Shader
  152. DECLARE_STATIC_VERTEX_SHADER( blob_vs30 );
  153. SET_STATIC_VERTEX_SHADER_COMBO( CONTACT_SHADOW, bContactShadows ); // only do contact shadows on outer shell (which has interior layer enabled)
  154. SET_STATIC_VERTEX_SHADER_COMBO( VOLUME_TEXTURE, bVolumeTex );
  155. SET_STATIC_VERTEX_SHADER( blob_vs30 );
  156. // Pixel Shader
  157. if( /* g_pHardwareConfig->SupportsPixelShaders_3_0() */ true )
  158. {
  159. DECLARE_STATIC_PIXEL_SHADER( blob_ps30 );
  160. SET_STATIC_PIXEL_SHADER_COMBO( BACK_SURFACE, bBackSurface );
  161. SET_STATIC_PIXEL_SHADER_COMBO( LIGHT_WARP, bLightWarp );
  162. SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL_WARP, bFresnelWarp );
  163. SET_STATIC_PIXEL_SHADER_COMBO( OPACITY_TEXTURE, bOpacityTexture );
  164. SET_STATIC_PIXEL_SHADER_COMBO( INTERIOR_LAYER, bInteriorLayer );
  165. SET_STATIC_PIXEL_SHADER_COMBO( HIGH_PRECISION_DEPTH, (g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT) ? true : false );
  166. SET_STATIC_PIXEL_SHADER_COMBO( SELF_ILLUM_FRESNEL, bSelfIllumFresnel );
  167. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  168. SET_STATIC_PIXEL_SHADER_COMBO( CONTACT_SHADOW, bContactShadows ); // only do contact shadows on outer shell (which has interior layer enabled)
  169. SET_STATIC_PIXEL_SHADER_COMBO( SELF_ILLUM_PULSE, bPulse );
  170. SET_STATIC_PIXEL_SHADER_COMBO( VOLUME_TEXTURE, bVolumeTex );
  171. SET_STATIC_PIXEL_SHADER( blob_ps30 );
  172. }
  173. else
  174. {
  175. Assert( !"No ps_3_0" );
  176. }
  177. // Textures
  178. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); //[sRGB] Base
  179. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  180. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump
  181. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
  182. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); //[sRGB] Backbuffer
  183. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true );
  184. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Spec mask
  185. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false );
  186. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); //[sRGB] Light warp
  187. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true );
  188. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Fresnel warp // TODO: Could be in alpha of lightwarp
  189. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false );
  190. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Opacity
  191. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false );
  192. if( bHasFlashlight )
  193. {
  194. pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Shadow depth map
  195. //pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 );
  196. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, false );
  197. pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Noise map
  198. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, false );
  199. pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); //[sRGB] Flashlight cookie
  200. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true );
  201. }
  202. pShaderShadow->EnableSRGBWrite( true );
  203. /*
  204. // Blending
  205. pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  206. pShaderShadow->EnableAlphaWrites( false );
  207. */
  208. pShaderShadow->EnableAlphaWrites( true );
  209. // Per-instance state
  210. pShader->PI_BeginCommandBuffer();
  211. pShader->PI_SetVertexShaderAmbientLightCube();
  212. pShader->PI_SetPixelShaderAmbientLightCube( PSREG_AMBIENT_CUBE );
  213. pShader->PI_SetPixelShaderLocalLighting( PSREG_LIGHT_INFO_ARRAY );
  214. pShader->PI_EndCommandBuffer();
  215. }
  216. DYNAMIC_STATE
  217. {
  218. ///////////////////////
  219. // VERTEX SHADER SETUP
  220. ///////////////////////
  221. // Set Vertex Shader Combos
  222. DECLARE_DYNAMIC_VERTEX_SHADER( blob_vs30 );
  223. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  224. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  225. SET_DYNAMIC_VERTEX_SHADER( blob_vs30 );
  226. LightState_t lightState = { 0, false, false };
  227. pShaderAPI->GetDX9LightState( &lightState );
  228. // VS constants
  229. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  230. flConsts[0] = IS_PARAM_DEFINED( info.m_nUVScale ) ? params[info.m_nUVScale]->GetFloatValue() : kDefaultUVScale;
  231. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, flConsts );
  232. if ( IS_PARAM_DEFINED( info.m_nUVProjOffset ) )
  233. params[info.m_nUVProjOffset]->GetVecValue( flConsts, 3 );
  234. else
  235. memcpy( flConsts, kDefaultUVProjOffset, sizeof( kDefaultUVProjOffset ) );
  236. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, flConsts );
  237. if ( IS_PARAM_DEFINED( info.m_nBBMin ) )
  238. params[info.m_nBBMin]->GetVecValue( flConsts, 3 );
  239. else
  240. memcpy( flConsts, kDefaultBB, sizeof( kDefaultBB ) );
  241. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flConsts );
  242. if ( IS_PARAM_DEFINED( info.m_nBBMax ) )
  243. params[info.m_nBBMax]->GetVecValue( flConsts, 3 );
  244. else
  245. memcpy( flConsts, kDefaultBB, sizeof( kDefaultBB ) );
  246. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, flConsts );
  247. //////////////////////
  248. // PIXEL SHADER SETUP
  249. //////////////////////
  250. // Bind textures
  251. pShader->BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_SRGBREAD, BASETEXTURE );
  252. pShader->BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, info.m_nNormalMap, info.m_nBumpFrame );
  253. pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map
  254. if ( (info.m_nSpecMap != -1) && params[info.m_nSpecMap]->IsDefined() )
  255. {
  256. pShader->BindTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, info.m_nSpecMap );
  257. }
  258. else
  259. {
  260. pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, TEXTURE_WHITE );
  261. }
  262. if ( bLightWarp )
  263. {
  264. pShader->BindTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_SRGBREAD, info.m_nLightWarpTexture );
  265. }
  266. if ( bFresnelWarp )
  267. {
  268. pShader->BindTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, info.m_nFresnelWarpTexture );
  269. }
  270. if ( bOpacityTexture )
  271. {
  272. pShader->BindTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, info.m_nOpacityTexture );
  273. }
  274. // flashlightfixme: put this in common code.
  275. bool bFlashlightShadows = false;
  276. if( bHasFlashlight )
  277. {
  278. Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 );
  279. pShader->BindTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_SRGBREAD, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame );
  280. VMatrix worldToTexture;
  281. ITexture *pFlashlightDepthTexture;
  282. FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
  283. bFlashlightShadows = state.m_bEnableShadows;
  284. SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
  285. if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows )
  286. {
  287. pShader->BindTexture( SHADER_SAMPLER7, TEXTURE_BINDFLAGS_SHADOWDEPTH, pFlashlightDepthTexture );
  288. pShaderAPI->BindStandardTexture( SHADER_SAMPLER8, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D );
  289. }
  290. float atten[4], pos[4], tweaks[4];
  291. atten[0] = state.m_fConstantAtten; // Set the flashlight attenuation factors
  292. atten[1] = state.m_fLinearAtten;
  293. atten[2] = state.m_fQuadraticAtten;
  294. atten[3] = state.m_FarZAtten;
  295. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
  296. pos[0] = state.m_vecLightOrigin[0]; // Set the flashlight origin
  297. pos[1] = state.m_vecLightOrigin[1];
  298. pos[2] = state.m_vecLightOrigin[2];
  299. pos[3] = state.m_FarZ;
  300. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost
  301. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 );
  302. // Tweaks associated with a given flashlight
  303. tweaks[0] = ShadowFilterFromState( state );
  304. tweaks[1] = ShadowAttenFromState( state );
  305. pShader->HashShadow2DJitter( state.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
  306. pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
  307. // Dimensions of screen, used for screen-space noise map sampling
  308. float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
  309. int nWidth, nHeight;
  310. pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
  311. int nTexWidth, nTexHeight;
  312. pShaderAPI->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D );
  313. vScreenScale[0] = (float) nWidth / nTexWidth;
  314. vScreenScale[1] = (float) nHeight / nTexHeight;
  315. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
  316. if ( IsX360() )
  317. {
  318. pShaderAPI->SetBooleanPixelShaderConstant( 0, &state.m_nShadowQuality, 1 );
  319. }
  320. }
  321. flConsts[0] = IS_PARAM_DEFINED( info.m_nBumpStrength ) ? params[info.m_nBumpStrength]->GetFloatValue() : kDefaultBumpStrength;
  322. flConsts[1] = (g_pHardwareConfig->GetHDRType() == HDR_TYPE_FLOAT) ? 8192.0f : 192.0f; // destalpha dest scale factor. TODO: put this in its own const and call shaderAPI method to set
  323. flConsts[2] = IS_PARAM_DEFINED( info.m_nInteriorFogStrength ) ? params[info.m_nInteriorFogStrength]->GetFloatValue() : kDefaultInteriorFogStrength;
  324. flConsts[3] = IS_PARAM_DEFINED( info.m_nInteriorRefractStrength ) ? params[info.m_nInteriorRefractStrength]->GetFloatValue() : kDefaultInteriorRefractStrength;
  325. pShaderAPI->SetPixelShaderConstant( 0, flConsts, 1 );
  326. Assert( IS_PARAM_DEFINED( info.m_nFresnelParams ) );
  327. if ( IS_PARAM_DEFINED( info.m_nFresnelParams ) )
  328. params[info.m_nFresnelParams]->GetVecValue( flConsts, 3 );
  329. else
  330. memcpy( flConsts, kDefaultFresnelParams, sizeof( kDefaultFresnelParams ) );
  331. flConsts[3] = params[info.m_nInteriorBackgroundBoost]->GetFloatValue();
  332. pShaderAPI->SetPixelShaderConstant( 1, flConsts, 1 );
  333. flConsts[0] = IS_PARAM_DEFINED( info.m_nRimLightExp ) ? params[info.m_nRimLightExp]->GetFloatValue() : kDefaultRimLightExp;
  334. flConsts[1] = IS_PARAM_DEFINED( info.m_nRimLightScale ) ? params[info.m_nRimLightScale]->GetFloatValue() : kDefaultRimLightScale;
  335. flConsts[2] = IS_PARAM_DEFINED( info.m_nSpecScale ) ? params[info.m_nSpecScale]->GetFloatValue() : kDefaultSpecScale;
  336. flConsts[3] = IS_PARAM_DEFINED( info.m_nSpecExp2 ) ? params[info.m_nSpecExp2]->GetFloatValue() : kDefaultSpecExp;
  337. pShaderAPI->SetPixelShaderConstant( 3, flConsts, 1 );
  338. flConsts[0] = IS_PARAM_DEFINED( info.m_nSpecScale2 ) ? params[info.m_nSpecScale2]->GetFloatValue() : kDefaultSpecScale;
  339. flConsts[1] = IS_PARAM_DEFINED( info.m_nFresnelBumpStrength ) ? params[info.m_nFresnelBumpStrength]->GetFloatValue() : kDefaultFresnelBumpStrength;
  340. flConsts[2] = IS_PARAM_DEFINED( info.m_nDiffuseScale ) ? params[info.m_nDiffuseScale]->GetFloatValue() : kDefaultDiffuseScale;
  341. flConsts[3] = IS_PARAM_DEFINED( info.m_nInteriorAmbientScale ) ? params[info.m_nInteriorAmbientScale]->GetFloatValue() : kDefaultInteriorAmbientScale;
  342. pShaderAPI->SetPixelShaderConstant( 10, flConsts, 1 );
  343. pShaderAPI->GetWorldSpaceCameraPosition( flConsts );
  344. flConsts[3] = IS_PARAM_DEFINED( info.m_nSpecExp ) ? params[info.m_nSpecExp]->GetFloatValue() : kDefaultSpecExp;
  345. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, flConsts, 1 );
  346. // Depth alpha [ TODO: support fog ]
  347. bool bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha();
  348. flConsts[0] = bWriteDepthToAlpha ? 1.0f : 0.0f;
  349. pShaderAPI->SetPixelShaderConstant( PSREG_FOG_PARAMS, flConsts, 1 );
  350. if ( IS_PARAM_DEFINED( info.m_nBaseColorTint ) )
  351. params[info.m_nBaseColorTint]->GetVecValue( flConsts, 3 );
  352. else
  353. memcpy( flConsts, kDefaultBaseColorTint, sizeof( kDefaultBaseColorTint ) );
  354. flConsts[3] = IS_PARAM_DEFINED( info.m_nInteriorBackLightScale ) ? params[info.m_nInteriorBackLightScale]->GetFloatValue() : kDefaultInteriorBackLightScale;
  355. pShaderAPI->SetPixelShaderConstant( 19, flConsts, 1 );
  356. if( bSelfIllumFresnel )
  357. {
  358. if ( IS_PARAM_DEFINED( info.m_nSelfIllumFresnelParams ) )
  359. params[info.m_nSelfIllumFresnelParams]->GetVecValue( flConsts, 3 );
  360. else
  361. memcpy( flConsts, kDefaultSelfIllumFresnelParams, sizeof( kDefaultSelfIllumFresnelParams ) );
  362. float flMin = flConsts[0];
  363. float flMax = flConsts[1];
  364. float flExp = flConsts[2];
  365. flConsts[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias
  366. flConsts[0] = 1.0f - flConsts[1]; // Scale
  367. flConsts[2] = flExp; // Exp
  368. flConsts[3] = flMax; // Brightness
  369. pShaderAPI->SetPixelShaderConstant( 26, flConsts, 1 );
  370. if ( IS_PARAM_DEFINED( info.m_nSelfIllumTint ) )
  371. params[info.m_nSelfIllumTint]->GetVecValue( flConsts, 3 );
  372. else
  373. memcpy( flConsts, kDefaultSelfIllumTint, sizeof( kDefaultSelfIllumTint ) );
  374. pShaderAPI->SetPixelShaderConstant( 27, flConsts, 1 );
  375. }
  376. if ( IS_PARAM_DEFINED( info.m_nInteriorColor ) )
  377. params[info.m_nInteriorColor]->GetVecValue( flConsts, 3 );
  378. else
  379. memcpy( flConsts, kDefaultInteriorColor, sizeof( kDefaultInteriorColor ) );
  380. flConsts[3] = params[info.m_nInteriorRefractBlur]->GetFloatValue();
  381. pShaderAPI->SetPixelShaderConstant( 32, flConsts, 1 );
  382. float mView[16];
  383. pShaderAPI->GetMatrix( MATERIAL_VIEW, mView );
  384. pShaderAPI->SetPixelShaderConstant( 33, mView, 3 );
  385. flConsts[0] = IS_PARAM_DEFINED( info.m_nInteriorFogLimit ) ? params[info.m_nInteriorFogLimit]->GetFloatValue() : kDefaultInteriorFogLimit;
  386. flConsts[0] = 1.0f - flConsts[0];
  387. flConsts[1] = params[info.m_nInteriorFogNormalBoost]->GetFloatValue();
  388. flConsts[2] = params[info.m_nGlowScale]->GetFloatValue();
  389. pShaderAPI->SetPixelShaderConstant( 36, flConsts, 1 );
  390. // Set Pixel Shader Combos
  391. if( /*g_pHardwareConfig->SupportsPixelShaders_2_b()*/ true )
  392. {
  393. DECLARE_DYNAMIC_PIXEL_SHADER( blob_ps30 );
  394. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  395. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
  396. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  397. SET_DYNAMIC_PIXEL_SHADER( blob_ps30 );
  398. }
  399. else
  400. {
  401. Assert( !"No ps_3_0" );
  402. }
  403. }
  404. pShader->Draw();
  405. }
  406. void DrawArmature( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
  407. IShaderShadow* pShaderShadow, BlobVars_t &info, VertexCompressionType_t vertexCompression, int nPassIdx )
  408. {
  409. Assert( nPassIdx >= 0 && nPassIdx < 2 );
  410. bool bSelfIllumFresnel = (info.m_nSelfIllumFresnelEnable != -1) && ( params[info.m_nSelfIllumFresnelEnable]->GetIntValue() > 0 );
  411. bool bArmWiden = (info.m_nArmWiden != -1) && ( params[info.m_nArmWiden]->GetIntValue() > 0 );
  412. bool bNormalMap = (info.m_nNormalMap != -1) && params[info.m_nNormalMap]->IsDefined();
  413. bool bBaseMap = params[BASETEXTURE]->IsDefined();
  414. bool bAnimatedPulses = (info.m_nAnimateArmPulses != -1) && ( params[info.m_nAnimateArmPulses]->GetIntValue() > 0 );
  415. SHADOW_STATE
  416. {
  417. if ( nPassIdx != 0 )
  418. {
  419. // Reset shadow state manually since we're drawing from two materials
  420. pShader->SetInitialShadowState();
  421. }
  422. // Set stream format (note that this shader supports compression)
  423. unsigned int flags = VERTEX_COLOR;
  424. int nTexCoordCount = 5;
  425. int userDataSize = 0;
  426. int texCoordDims[5] = { 4, 4, 4, 4, 4 };
  427. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, texCoordDims, userDataSize );
  428. // Vertex Shader
  429. DECLARE_STATIC_VERTEX_SHADER( blob_arm_vs20 );
  430. SET_STATIC_VERTEX_SHADER_COMBO( WIDEN_TIPS, bArmWiden );
  431. SET_STATIC_VERTEX_SHADER( blob_arm_vs20 );
  432. // Pixel Shader
  433. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  434. {
  435. DECLARE_STATIC_PIXEL_SHADER( blob_arm_ps20b );
  436. SET_STATIC_PIXEL_SHADER_COMBO( SELF_ILLUM_FRESNEL, bSelfIllumFresnel );
  437. SET_STATIC_PIXEL_SHADER_COMBO( PRE_PASS, ( nPassIdx == 0 ) );
  438. SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, bNormalMap );
  439. SET_STATIC_PIXEL_SHADER_COMBO( MOVING_PULSES, bAnimatedPulses );
  440. SET_STATIC_PIXEL_SHADER( blob_arm_ps20b );
  441. }
  442. else
  443. {
  444. Assert( !"No ps_2_b" );
  445. }
  446. // Textures
  447. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base
  448. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  449. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump
  450. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Not sRGB
  451. pShaderShadow->EnableSRGBWrite( true );
  452. pShaderShadow->EnableAlphaToCoverage( nPassIdx == 0 );
  453. pShaderShadow->EnableAlphaTest( nPassIdx == 0 );
  454. pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, 0.5f );
  455. pShaderShadow->EnableColorWrites( nPassIdx > 0 );
  456. if ( nPassIdx != 0 )
  457. {
  458. pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
  459. }
  460. // Blending
  461. pShaderShadow->EnableAlphaWrites( true );
  462. // Per-instance state
  463. pShader->PI_BeginCommandBuffer();
  464. pShader->PI_SetVertexShaderAmbientLightCube();
  465. pShader->PI_SetPixelShaderAmbientLightCube( PSREG_AMBIENT_CUBE );
  466. pShader->PI_SetPixelShaderLocalLighting( PSREG_LIGHT_INFO_ARRAY );
  467. pShader->PI_EndCommandBuffer();
  468. }
  469. DYNAMIC_STATE
  470. {
  471. if ( nPassIdx != 0 )
  472. {
  473. // Reset render state manually since we're drawing from two materials
  474. pShaderAPI->SetDefaultState();
  475. }
  476. // Set Vertex Shader Combos
  477. DECLARE_DYNAMIC_VERTEX_SHADER( blob_arm_vs20 );
  478. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  479. SET_DYNAMIC_VERTEX_SHADER( blob_arm_vs20 );
  480. LightState_t lightState = { 0, false, false };
  481. pShaderAPI->GetDX9LightState( &lightState );
  482. // VS constants
  483. float flConsts[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  484. flConsts[0] = IS_PARAM_DEFINED( info.m_nArmWidthExp ) ? params[info.m_nArmWidthExp]->GetFloatValue() : kDefaultArmWidthExp;
  485. flConsts[1] = IS_PARAM_DEFINED( info.m_nArmWidthScale ) ? params[info.m_nArmWidthScale]->GetFloatValue() : kDefaultArmWidthScale;
  486. flConsts[2] = IS_PARAM_DEFINED( info.m_nArmWidthBias ) ? params[info.m_nArmWidthBias]->GetFloatValue() : kDefaultArmWidthBias;
  487. flConsts[3] = IS_PARAM_DEFINED( info.m_nUVScale ) ? params[info.m_nUVScale]->GetFloatValue() : kDefaultUVScale;
  488. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, flConsts );
  489. pShaderAPI->GetWorldSpaceCameraPosition( flConsts );
  490. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, flConsts );
  491. // Set Pixel Shader Combos
  492. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  493. {
  494. DECLARE_DYNAMIC_PIXEL_SHADER( blob_arm_ps20b );
  495. SET_DYNAMIC_PIXEL_SHADER( blob_arm_ps20b );
  496. }
  497. else
  498. {
  499. Assert( !"No ps_2_b" );
  500. }
  501. // Bind textures
  502. if ( bBaseMap )
  503. {
  504. pShader->BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_SRGBREAD, BASETEXTURE );
  505. }
  506. else
  507. {
  508. pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_WHITE );
  509. }
  510. if ( bNormalMap )
  511. {
  512. pShader->BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, info.m_nNormalMap );
  513. }
  514. pShaderAPI->GetWorldSpaceCameraPosition( flConsts );
  515. flConsts[3] = IS_PARAM_DEFINED( info.m_nSpecExp ) ? params[info.m_nSpecExp]->GetFloatValue() : kDefaultSpecExp;
  516. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, flConsts, 1 );
  517. if ( IS_PARAM_DEFINED( info.m_nArmColorTint ) )
  518. params[info.m_nArmColorTint ]->GetVecValue( flConsts, 3 );
  519. else
  520. memcpy( flConsts, kDefaultArmColorTint, sizeof( kDefaultArmColorTint ) );
  521. pShaderAPI->SetPixelShaderConstant( 19, flConsts, 1 );
  522. if ( IS_PARAM_DEFINED( info.m_nSelfIllumTint ) )
  523. params[info.m_nSelfIllumTint]->GetVecValue( flConsts, 3 );
  524. else
  525. memcpy( flConsts, kDefaultSelfIllumTint, sizeof( flConsts ) );
  526. if( bSelfIllumFresnel )
  527. {
  528. if ( IS_PARAM_DEFINED( info.m_nSelfIllumFresnelParams ) )
  529. params[info.m_nSelfIllumFresnelParams]->GetVecValue( flConsts, 3 );
  530. else
  531. memcpy( flConsts, kDefaultSelfIllumTint, sizeof( flConsts ) );
  532. float flMin = flConsts[0];
  533. float flMax = flConsts[1];
  534. float flExp = flConsts[2];
  535. flConsts[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias
  536. flConsts[0] = 1.0f - flConsts[1]; // Scale
  537. flConsts[2] = flExp; // Exp
  538. flConsts[3] = flMax; // Brightness
  539. pShaderAPI->SetPixelShaderConstant( 26, flConsts, 1 );
  540. if ( IS_PARAM_DEFINED( info.m_nSelfIllumTint ) )
  541. params[info.m_nSelfIllumTint]->GetVecValue( flConsts, 3 );
  542. else
  543. memcpy( flConsts, kDefaultSelfIllumTint, sizeof( flConsts ) );
  544. pShaderAPI->SetPixelShaderConstant( 27, flConsts, 1 );
  545. }
  546. }
  547. pShader->Draw();
  548. }