Team Fortress 2 Source Code as on 22/4/2020
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.

578 lines
22 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "BaseVSShader.h"
  7. #include "cpp_shader_constant_register_map.h"
  8. #include "teeth_vs20.inc"
  9. #include "teeth_flashlight_vs20.inc"
  10. #include "teeth_bump_vs20.inc"
  11. #include "teeth_ps20.inc"
  12. #include "teeth_ps20b.inc"
  13. #include "teeth_flashlight_ps20.inc"
  14. #include "teeth_flashlight_ps20b.inc"
  15. #include "teeth_bump_ps20.inc"
  16. #include "teeth_bump_ps20b.inc"
  17. #ifndef _X360
  18. #include "teeth_vs30.inc"
  19. #include "teeth_ps30.inc"
  20. #include "teeth_bump_vs30.inc"
  21. #include "teeth_bump_ps30.inc"
  22. #include "teeth_flashlight_vs30.inc"
  23. #include "teeth_flashlight_ps30.inc"
  24. #endif
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX9 )
  28. extern ConVar r_flashlight_version2;
  29. BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" )
  30. BEGIN_SHADER_PARAMS
  31. SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" )
  32. SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" )
  33. SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" )
  34. SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "100", "phong exponent" )
  35. SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" )
  36. SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" )
  37. SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" )
  38. END_SHADER_PARAMS
  39. SHADER_INIT_PARAMS()
  40. {
  41. if ( g_pHardwareConfig->SupportsBorderColor() )
  42. {
  43. params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" );
  44. }
  45. else
  46. {
  47. params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" );
  48. }
  49. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  50. if( !params[INTRO]->IsDefined() )
  51. {
  52. params[INTRO]->SetIntValue( 0 );
  53. }
  54. }
  55. SHADER_FALLBACK
  56. {
  57. if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pConfig->bSoftwareLighting )
  58. {
  59. return "Teeth_dx8";
  60. }
  61. return 0;
  62. }
  63. SHADER_INIT
  64. {
  65. LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB );
  66. LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB );
  67. if( params[BUMPMAP]->IsDefined() )
  68. {
  69. LoadTexture( BUMPMAP );
  70. }
  71. }
  72. void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression )
  73. {
  74. bool hasBump = params[BUMPMAP]->IsTexture();
  75. BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true );
  76. bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use
  77. SHADOW_STATE
  78. {
  79. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map
  80. int flags = VERTEX_POSITION | VERTEX_NORMAL;
  81. int nTexCoordCount = 1;
  82. int userDataSize = 0;
  83. if ( hasBump )
  84. {
  85. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump map
  86. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
  87. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalization sampler for per-pixel lighting
  88. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false );
  89. userDataSize = 4; // tangent S
  90. }
  91. // This shader supports compressed vertices, so OR in that flag:
  92. flags |= VERTEX_FORMAT_COMPRESSED;
  93. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
  94. if ( hasBump )
  95. {
  96. #ifndef _X360
  97. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  98. #endif
  99. {
  100. bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
  101. DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs20 );
  102. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  103. SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow );
  104. SET_STATIC_VERTEX_SHADER( teeth_bump_vs20 );
  105. // ps_2_b version which does phong
  106. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  107. {
  108. DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20b );
  109. SET_STATIC_PIXEL_SHADER( teeth_bump_ps20b );
  110. }
  111. else
  112. {
  113. DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20 );
  114. SET_STATIC_PIXEL_SHADER( teeth_bump_ps20 );
  115. }
  116. }
  117. #ifndef _X360
  118. else
  119. {
  120. // The vertex shader uses the vertex id stream
  121. SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
  122. DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs30 );
  123. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  124. SET_STATIC_VERTEX_SHADER( teeth_bump_vs30 );
  125. DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps30 );
  126. SET_STATIC_PIXEL_SHADER( teeth_bump_ps30 );
  127. }
  128. #endif
  129. }
  130. else
  131. {
  132. #ifndef _X360
  133. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  134. #endif
  135. {
  136. bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
  137. DECLARE_STATIC_VERTEX_SHADER( teeth_vs20 );
  138. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  139. SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow );
  140. SET_STATIC_VERTEX_SHADER( teeth_vs20 );
  141. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  142. {
  143. DECLARE_STATIC_PIXEL_SHADER( teeth_ps20b );
  144. SET_STATIC_PIXEL_SHADER( teeth_ps20b );
  145. }
  146. else
  147. {
  148. DECLARE_STATIC_PIXEL_SHADER( teeth_ps20 );
  149. SET_STATIC_PIXEL_SHADER( teeth_ps20 );
  150. }
  151. }
  152. #ifndef _X360
  153. else
  154. {
  155. // The vertex shader uses the vertex id stream
  156. SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
  157. DECLARE_STATIC_VERTEX_SHADER( teeth_vs30 );
  158. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  159. SET_STATIC_VERTEX_SHADER( teeth_vs30 );
  160. DECLARE_STATIC_PIXEL_SHADER( teeth_ps30 );
  161. SET_STATIC_PIXEL_SHADER( teeth_ps30 );
  162. }
  163. #endif
  164. }
  165. // On DX9, do sRGB
  166. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  167. pShaderShadow->EnableSRGBWrite( true );
  168. FogToFogColor();
  169. pShaderShadow->EnableAlphaWrites( bFullyOpaque );
  170. }
  171. DYNAMIC_STATE
  172. {
  173. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  174. if ( hasBump )
  175. {
  176. BindTexture( SHADER_SAMPLER1, BUMPMAP );
  177. }
  178. pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
  179. pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE );
  180. pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY );
  181. Vector4D lighting;
  182. params[FORWARD]->GetVecValue( lighting.Base(), 3 );
  183. lighting[3] = params[ILLUMFACTOR]->GetFloatValue();
  184. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() );
  185. LightState_t lightState;
  186. pShaderAPI->GetDX9LightState( &lightState );
  187. pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
  188. float vEyePos_SpecExponent[4];
  189. pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
  190. vEyePos_SpecExponent[3] = 0.0f;
  191. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
  192. if ( hasBump )
  193. {
  194. #ifndef _X360
  195. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  196. #endif
  197. {
  198. bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
  199. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 );
  200. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  201. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  202. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 );
  203. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  204. SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights );
  205. SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 );
  206. // ps_2_b version which does Phong
  207. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  208. {
  209. Vector4D vSpecExponent;
  210. vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue();
  211. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 );
  212. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b );
  213. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  214. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  215. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 );
  216. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  217. SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b );
  218. }
  219. else
  220. {
  221. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 );
  222. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  223. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  224. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 );
  225. SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 );
  226. }
  227. }
  228. #ifndef _X360
  229. else
  230. {
  231. SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
  232. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 );
  233. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  234. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  235. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 );
  236. SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() );
  237. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  238. SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 );
  239. Vector4D vSpecExponent;
  240. vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue();
  241. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 );
  242. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 );
  243. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  244. SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
  245. SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 );
  246. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  247. SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 );
  248. }
  249. #endif
  250. }
  251. else
  252. {
  253. // For non-bumped case, ambient cube is computed in the vertex shader
  254. SetAmbientCubeDynamicStateVertexShader();
  255. #ifndef _X360
  256. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  257. #endif
  258. {
  259. bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow();
  260. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs20 );
  261. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  262. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  263. SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
  264. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 );
  265. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  266. SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights );
  267. SET_DYNAMIC_VERTEX_SHADER( teeth_vs20 );
  268. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  269. {
  270. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20b );
  271. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  272. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  273. SET_DYNAMIC_PIXEL_SHADER( teeth_ps20b );
  274. }
  275. else
  276. {
  277. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20 );
  278. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  279. SET_DYNAMIC_PIXEL_SHADER( teeth_ps20 );
  280. }
  281. }
  282. #ifndef _X360
  283. else
  284. {
  285. SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
  286. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs30 );
  287. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  288. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  289. SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() );
  290. SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLightVertex ? 1 : 0 );
  291. SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() );
  292. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  293. SET_DYNAMIC_VERTEX_SHADER( teeth_vs30 );
  294. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps30 );
  295. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  296. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() );
  297. SET_DYNAMIC_PIXEL_SHADER( teeth_ps30 );
  298. }
  299. #endif
  300. }
  301. if( params[INTRO]->GetIntValue() )
  302. {
  303. float curTime = params[WARPPARAM]->GetFloatValue();
  304. float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime };
  305. Assert( params[ENTITYORIGIN]->IsDefined() );
  306. params[ENTITYORIGIN]->GetVecValue( timeVec, 3 );
  307. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 );
  308. }
  309. }
  310. Draw();
  311. }
  312. void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression )
  313. {
  314. SHADOW_STATE
  315. {
  316. // Be sure not to write to dest alpha
  317. pShaderShadow->EnableAlphaWrites( false );
  318. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map
  319. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  320. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Flashlight spot
  321. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
  322. // Additive blend the teeth, lit by the flashlight
  323. s_pShaderShadow->EnableAlphaTest( false );
  324. s_pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE );
  325. s_pShaderShadow->EnableBlending( true );
  326. // Set stream format (note that this shader supports compression)
  327. int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED;
  328. int nTexCoordCount = 1;
  329. int userDataSize = 0;
  330. pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize );
  331. int nShadowFilterMode = 0;
  332. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  333. {
  334. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // shadow depth map
  335. pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER2 );
  336. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // shadow noise
  337. nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats
  338. }
  339. #ifndef _X360
  340. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  341. #endif
  342. {
  343. DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 );
  344. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  345. SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 );
  346. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  347. {
  348. DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b );
  349. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  350. SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b );
  351. }
  352. else
  353. {
  354. DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 );
  355. SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 );
  356. }
  357. }
  358. #ifndef _X360
  359. else
  360. {
  361. // The vertex shader uses the vertex id stream
  362. SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID );
  363. DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 );
  364. SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 );
  365. SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 );
  366. DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 );
  367. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
  368. SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 );
  369. }
  370. #endif
  371. // On DX9, do sRGB
  372. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  373. pShaderShadow->EnableSRGBWrite( true );
  374. FogToFogColor();
  375. }
  376. DYNAMIC_STATE
  377. {
  378. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  379. // State for spotlight projection, attenuation etc
  380. SetFlashlightVertexShaderConstants( false, -1, false, -1, true );
  381. VMatrix worldToTexture;
  382. ITexture *pFlashlightDepthTexture;
  383. FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
  384. SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
  385. bool bFlashlightShadows = g_pHardwareConfig->SupportsPixelShaders_2_b() ? state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) : false;
  386. if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows )
  387. {
  388. BindTexture( SHADER_SAMPLER2, pFlashlightDepthTexture, 0 );
  389. pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_SHADOW_NOISE_2D );
  390. }
  391. Vector4D lighting;
  392. params[FORWARD]->GetVecValue( lighting.Base(), 3 );
  393. lighting[3] = params[ILLUMFACTOR]->GetFloatValue();
  394. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, lighting.Base() );
  395. float atten[4], pos[4], tweaks[4];
  396. const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture );
  397. SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
  398. BindTexture( SHADER_SAMPLER1, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame );
  399. atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors
  400. atten[1] = flashlightState.m_fLinearAtten;
  401. atten[2] = flashlightState.m_fQuadraticAtten;
  402. atten[3] = flashlightState.m_FarZ;
  403. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
  404. pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin
  405. pos[1] = flashlightState.m_vecLightOrigin[1];
  406. pos[2] = flashlightState.m_vecLightOrigin[2];
  407. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost
  408. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 );
  409. // Tweaks associated with a given flashlight
  410. tweaks[0] = ShadowFilterFromState( flashlightState );
  411. tweaks[1] = ShadowAttenFromState( flashlightState );
  412. HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
  413. pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
  414. // Dimensions of screen, used for screen-space noise map sampling
  415. float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
  416. int nWidth, nHeight;
  417. pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
  418. vScreenScale[0] = (float) nWidth / 32.0f;
  419. vScreenScale[1] = (float) nHeight / 32.0f;
  420. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
  421. float vFlashlightPos[4];
  422. pShaderAPI->GetWorldSpaceCameraPosition( vFlashlightPos );
  423. pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vFlashlightPos, 1 );
  424. if ( IsX360() )
  425. {
  426. pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 );
  427. }
  428. #ifndef _X360
  429. if ( !g_pHardwareConfig->HasFastVertexTextures() )
  430. #endif
  431. {
  432. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 );
  433. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  434. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  435. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  436. SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 );
  437. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  438. {
  439. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b );
  440. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  441. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  442. SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b );
  443. }
  444. else
  445. {
  446. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 );
  447. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  448. SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 );
  449. }
  450. }
  451. #ifndef _X360
  452. else
  453. {
  454. SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 );
  455. DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 );
  456. SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  457. SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 );
  458. SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() );
  459. SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
  460. SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 );
  461. DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 );
  462. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  463. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  464. SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 );
  465. }
  466. #endif
  467. if( params[INTRO]->GetIntValue() )
  468. {
  469. float curTime = params[WARPPARAM]->GetFloatValue();
  470. float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime };
  471. Assert( params[ENTITYORIGIN]->IsDefined() );
  472. params[ENTITYORIGIN]->GetVecValue( timeVec, 3 );
  473. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, timeVec, 1 );
  474. }
  475. }
  476. Draw();
  477. }
  478. SHADER_DRAW
  479. {
  480. SHADOW_STATE
  481. {
  482. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
  483. }
  484. bool hasFlashlight = UsingFlashlight( params );
  485. if ( !hasFlashlight || ( IsX360() || r_flashlight_version2.GetInt() ) )
  486. {
  487. DrawUsingVertexShader( params, pShaderAPI, pShaderShadow, vertexCompression );
  488. SHADOW_STATE
  489. {
  490. SetInitialShadowState();
  491. }
  492. }
  493. if( hasFlashlight )
  494. {
  495. DrawFlashlight( params, pShaderAPI, pShaderShadow, vertexCompression );
  496. }
  497. }
  498. END_SHADER