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.

592 lines
20 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "BaseVSShader.h"
  8. #include "mathlib/vmatrix.h"
  9. #include "common_hlsl_cpp_consts.h" // hack hack hack!
  10. #include "convar.h"
  11. #include "WaterCheap_vs20.inc"
  12. #include "WaterCheap_ps20.inc"
  13. #include "WaterCheap_ps20b.inc"
  14. #include "Water_vs20.inc"
  15. #include "Water_ps20.inc"
  16. #include "water_ps20b.inc"
  17. #ifndef _X360
  18. static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE );
  19. #endif
  20. DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR )
  21. BEGIN_VS_SHADER( Water_DX90,
  22. "Help for Water" )
  23. BEGIN_SHADER_PARAMS
  24. SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" )
  25. SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" )
  26. SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" )
  27. SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" )
  28. SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" )
  29. SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" )
  30. SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" )
  31. SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
  32. SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
  33. SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" )
  34. SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" )
  35. SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" )
  36. SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." )
  37. SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." )
  38. SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" )
  39. SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  40. SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" )
  41. SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_BOOL, "", "" )
  42. SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" )
  43. SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" )
  44. SHADER_PARAM( FOGSTART, SHADER_PARAM_TYPE_FLOAT, "", "" )
  45. SHADER_PARAM( FOGEND, SHADER_PARAM_TYPE_FLOAT, "", "" )
  46. SHADER_PARAM( ABOVEWATER, SHADER_PARAM_TYPE_BOOL, "", "" )
  47. SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" )
  48. SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" )
  49. SHADER_PARAM( NOLOWENDLIGHTMAP, SHADER_PARAM_TYPE_BOOL, "0", "" )
  50. SHADER_PARAM( SCROLL1, SHADER_PARAM_TYPE_COLOR, "", "" )
  51. SHADER_PARAM( SCROLL2, SHADER_PARAM_TYPE_COLOR, "", "" )
  52. SHADER_PARAM( BLURREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Cause the refraction to be blurry on ps2b hardware" )
  53. END_SHADER_PARAMS
  54. SHADER_INIT_PARAMS()
  55. {
  56. if( !params[ABOVEWATER]->IsDefined() )
  57. {
  58. Warning( "***need to set $abovewater for material %s\n", pMaterialName );
  59. params[ABOVEWATER]->SetIntValue( 1 );
  60. }
  61. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  62. if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() )
  63. {
  64. params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f );
  65. }
  66. if( !params[CHEAPWATERENDDISTANCE]->IsDefined() )
  67. {
  68. params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f );
  69. }
  70. if( !params[SCALE]->IsDefined() )
  71. {
  72. params[SCALE]->SetVecValue( 1.0f, 1.0f );
  73. }
  74. if( !params[SCROLL1]->IsDefined() )
  75. {
  76. params[SCROLL1]->SetVecValue( 0.0f, 0.0f, 0.0f );
  77. }
  78. if( !params[SCROLL2]->IsDefined() )
  79. {
  80. params[SCROLL2]->SetVecValue( 0.0f, 0.0f, 0.0f );
  81. }
  82. if( !params[FOGCOLOR]->IsDefined() )
  83. {
  84. params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f );
  85. Warning( "material %s needs to have a $fogcolor.\n", pMaterialName );
  86. }
  87. if( !params[REFLECTENTITIES]->IsDefined() )
  88. {
  89. params[REFLECTENTITIES]->SetIntValue( 0 );
  90. }
  91. if( !params[REFLECTBLENDFACTOR]->IsDefined() )
  92. {
  93. params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f );
  94. }
  95. // By default, we're force expensive on dx9. NO WE DON'T!!!!
  96. if( !params[FORCEEXPENSIVE]->IsDefined() )
  97. {
  98. #ifdef _X360
  99. params[FORCEEXPENSIVE]->SetIntValue( 0 );
  100. #else
  101. params[FORCEEXPENSIVE]->SetIntValue( 1 );
  102. #endif
  103. }
  104. if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() )
  105. {
  106. params[FORCEEXPENSIVE]->SetIntValue( 0 );
  107. }
  108. // Fallbacks for water need lightmaps usually
  109. if ( !params[NOLOWENDLIGHTMAP]->GetIntValue() )
  110. {
  111. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
  112. }
  113. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
  114. if( g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() )
  115. {
  116. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP );
  117. }
  118. }
  119. SHADER_FALLBACK
  120. {
  121. if( g_pHardwareConfig->GetDXSupportLevel() < 90 )
  122. {
  123. return "Water_DX81";
  124. }
  125. return 0;
  126. }
  127. SHADER_INIT
  128. {
  129. Assert( params[WATERDEPTH]->IsDefined() );
  130. if( params[REFRACTTEXTURE]->IsDefined() )
  131. {
  132. LoadTexture( REFRACTTEXTURE, TEXTUREFLAGS_SRGB );
  133. }
  134. if( params[REFLECTTEXTURE]->IsDefined() )
  135. {
  136. LoadTexture( REFLECTTEXTURE, TEXTUREFLAGS_SRGB );
  137. }
  138. if ( params[ENVMAP]->IsDefined() )
  139. {
  140. LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB );
  141. }
  142. if ( params[NORMALMAP]->IsDefined() )
  143. {
  144. LoadBumpMap( NORMALMAP );
  145. }
  146. if( params[BASETEXTURE]->IsDefined() )
  147. {
  148. LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB );
  149. }
  150. }
  151. inline void GetVecParam( int constantVar, float *val )
  152. {
  153. if( constantVar == -1 )
  154. return;
  155. IMaterialVar* pVar = s_ppParams[constantVar];
  156. Assert( pVar );
  157. if (pVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
  158. pVar->GetVecValue( val, 4 );
  159. else
  160. val[0] = val[1] = val[2] = val[3] = pVar->GetFloatValue();
  161. }
  162. inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow,
  163. IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction )
  164. {
  165. SHADOW_STATE
  166. {
  167. SetInitialShadowState( );
  168. if( bRefraction )
  169. {
  170. // refract sampler
  171. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  172. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  173. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
  174. }
  175. if( bReflection )
  176. {
  177. // reflect sampler
  178. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  179. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  180. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true );
  181. if( params[BASETEXTURE]->IsTexture() )
  182. {
  183. // BASETEXTURE
  184. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  185. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
  186. // LIGHTMAP
  187. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  188. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true );
  189. }
  190. }
  191. // normal map
  192. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
  193. // Normalizing cube map
  194. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
  195. int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T;
  196. // texcoord0 : base texcoord
  197. // texcoord1 : lightmap texcoord
  198. // texcoord2 : lightmap texcoord offset
  199. int numTexCoords = 1;
  200. if( params[BASETEXTURE]->IsTexture() )
  201. {
  202. numTexCoords = 3;
  203. }
  204. pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 );
  205. Vector4D Scroll1;
  206. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  207. DECLARE_STATIC_VERTEX_SHADER( water_vs20 );
  208. SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  209. SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() );
  210. SET_STATIC_VERTEX_SHADER( water_vs20 );
  211. // "REFLECT" "0..1"
  212. // "REFRACT" "0..1"
  213. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  214. {
  215. DECLARE_STATIC_PIXEL_SHADER( water_ps20b );
  216. SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection );
  217. SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction );
  218. SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() );
  219. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  220. SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() );
  221. SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() );
  222. SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) NORMAL_DECODE_NONE );
  223. SET_STATIC_PIXEL_SHADER( water_ps20b );
  224. }
  225. else
  226. {
  227. DECLARE_STATIC_PIXEL_SHADER( water_ps20 );
  228. SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection );
  229. SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction );
  230. SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() );
  231. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  232. SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() );
  233. SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) NORMAL_DECODE_NONE );
  234. SET_STATIC_PIXEL_SHADER( water_ps20 );
  235. }
  236. FogToFogColor();
  237. // we are writing linear values from this shader.
  238. pShaderShadow->EnableSRGBWrite( true );
  239. pShaderShadow->EnableAlphaWrites( true );
  240. }
  241. DYNAMIC_STATE
  242. {
  243. pShaderAPI->SetDefaultState();
  244. if( bRefraction )
  245. {
  246. // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable
  247. BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 );
  248. }
  249. if( bReflection )
  250. {
  251. BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 );
  252. }
  253. BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME );
  254. if( params[BASETEXTURE]->IsTexture() )
  255. {
  256. BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME );
  257. pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP );
  258. }
  259. pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
  260. // Refraction tint
  261. if( bRefraction )
  262. {
  263. SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT );
  264. }
  265. // Reflection tint
  266. if( bReflection )
  267. {
  268. if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
  269. {
  270. // Need to multiply by 4 in linear space since we premultiplied into
  271. // the render target by .25 to get overbright data in the reflection render target.
  272. float gammaReflectTint[3];
  273. params[REFLECTTINT]->GetVecValue( gammaReflectTint, 3 );
  274. float linearReflectTint[4];
  275. linearReflectTint[0] = GammaToLinear( gammaReflectTint[0] ) * 4.0f;
  276. linearReflectTint[1] = GammaToLinear( gammaReflectTint[1] ) * 4.0f;
  277. linearReflectTint[2] = GammaToLinear( gammaReflectTint[2] ) * 4.0f;
  278. linearReflectTint[3] = 1.0f;
  279. pShaderAPI->SetPixelShaderConstant( 4, linearReflectTint, 1 );
  280. }
  281. else
  282. {
  283. SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT );
  284. }
  285. }
  286. SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM );
  287. float curtime=pShaderAPI->CurrentTime();
  288. float vc0[4];
  289. float v0[4];
  290. params[SCROLL1]->GetVecValue(v0,4);
  291. vc0[0]=curtime*v0[0];
  292. vc0[1]=curtime*v0[1];
  293. params[SCROLL2]->GetVecValue(v0,4);
  294. vc0[2]=curtime*v0[0];
  295. vc0[3]=curtime*v0[1];
  296. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 );
  297. float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f };
  298. pShaderAPI->SetPixelShaderConstant( 0, c0, 1 );
  299. float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f };
  300. pShaderAPI->SetPixelShaderConstant( 2, c2, 1 );
  301. // fresnel constants
  302. float c3[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
  303. pShaderAPI->SetPixelShaderConstant( 3, c3, 1 );
  304. float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(),
  305. params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() };
  306. pShaderAPI->SetPixelShaderConstant( 5, c5, 1 );
  307. SetPixelShaderConstantGammaToLinear( 6, FOGCOLOR );
  308. float c7[4] =
  309. {
  310. params[FOGSTART]->GetFloatValue(),
  311. params[FOGEND]->GetFloatValue() - params[FOGSTART]->GetFloatValue(),
  312. 1.0f,
  313. 0.0f
  314. };
  315. if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
  316. {
  317. // water overbright factor
  318. c7[2] = 4.0;
  319. }
  320. pShaderAPI->SetPixelShaderConstant( 7, c7, 1 );
  321. pShaderAPI->SetPixelShaderFogParams( 8 );
  322. DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 );
  323. SET_DYNAMIC_VERTEX_SHADER( water_vs20 );
  324. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  325. {
  326. DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b );
  327. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  328. SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() );
  329. SET_DYNAMIC_PIXEL_SHADER( water_ps20b );
  330. }
  331. else
  332. {
  333. DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 );
  334. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  335. SET_DYNAMIC_PIXEL_SHADER( water_ps20 );
  336. }
  337. }
  338. Draw();
  339. }
  340. inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow,
  341. IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bRefraction )
  342. {
  343. SHADOW_STATE
  344. {
  345. SetInitialShadowState( );
  346. // In edit mode, use nocull
  347. if ( UsingEditor( params ) )
  348. {
  349. s_pShaderShadow->EnableCulling( false );
  350. }
  351. if( bBlend )
  352. {
  353. EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  354. }
  355. // envmap
  356. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  357. // normal map
  358. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  359. if( bRefraction && bBlend )
  360. {
  361. // refraction map (used for alpha)
  362. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  363. }
  364. // Normalizing cube map
  365. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
  366. int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T;
  367. pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
  368. DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 );
  369. SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction );
  370. SET_STATIC_VERTEX_SHADER( watercheap_vs20 );
  371. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  372. {
  373. DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b );
  374. SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 );
  375. SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend );
  376. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction );
  377. SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() );
  378. Vector4D Scroll1;
  379. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  380. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  381. SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) NORMAL_DECODE_NONE );
  382. SET_STATIC_PIXEL_SHADER( watercheap_ps20b );
  383. }
  384. else
  385. {
  386. DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 );
  387. SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 );
  388. SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend );
  389. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction );
  390. SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() );
  391. Vector4D Scroll1;
  392. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  393. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  394. SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) NORMAL_DECODE_NONE );
  395. SET_STATIC_PIXEL_SHADER( watercheap_ps20 );
  396. }
  397. // HDRFIXME: test cheap water!
  398. if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
  399. {
  400. // we are writing linear values from this shader.
  401. pShaderShadow->EnableSRGBWrite( true );
  402. }
  403. FogToFogColor();
  404. }
  405. DYNAMIC_STATE
  406. {
  407. pShaderAPI->SetDefaultState();
  408. BindTexture( SHADER_SAMPLER0, ENVMAP, ENVMAPFRAME );
  409. BindTexture( SHADER_SAMPLER1, NORMALMAP, BUMPFRAME );
  410. if( bRefraction && bBlend )
  411. {
  412. BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 );
  413. }
  414. pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
  415. SetPixelShaderConstant( 0, FOGCOLOR );
  416. float cheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue();
  417. float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue();
  418. float cheapWaterParams[4] =
  419. {
  420. (float)(cheapWaterStartDistance * VSHADER_VECT_SCALE),
  421. (float)(cheapWaterEndDistance * VSHADER_VECT_SCALE),
  422. (float)(PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance )),
  423. cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ),
  424. };
  425. pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams );
  426. if( g_pConfig->bShowSpecular )
  427. {
  428. SetPixelShaderConstant( 2, REFLECTTINT, REFLECTBLENDFACTOR );
  429. }
  430. else
  431. {
  432. float zero[4] = { 0.0f, 0.0f, 0.0f, params[REFLECTBLENDFACTOR]->GetFloatValue() };
  433. pShaderAPI->SetPixelShaderConstant( 2, zero );
  434. }
  435. pShaderAPI->SetPixelShaderFogParams( 3 );
  436. if( params[SCROLL1]->IsDefined())
  437. {
  438. float curtime=pShaderAPI->CurrentTime();
  439. float vc0[4];
  440. float v0[4];
  441. params[SCROLL1]->GetVecValue(v0,4);
  442. vc0[0]=curtime*v0[0];
  443. vc0[1]=curtime*v0[1];
  444. params[SCROLL2]->GetVecValue(v0,4);
  445. vc0[2]=curtime*v0[0];
  446. vc0[3]=curtime*v0[1];
  447. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 );
  448. }
  449. DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 );
  450. SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 );
  451. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  452. {
  453. DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b );
  454. SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() );
  455. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  456. SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b );
  457. }
  458. else
  459. {
  460. DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 );
  461. SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() );
  462. SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
  463. SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 );
  464. }
  465. }
  466. Draw();
  467. }
  468. SHADER_DRAW
  469. {
  470. // TODO: fit the cheap water stuff into the water shader so that we don't have to do
  471. // 2 passes.
  472. #ifdef _X360
  473. bool bForceExpensive = false;
  474. #else
  475. bool bForceExpensive = r_waterforceexpensive.GetBool();
  476. #endif
  477. bool bForceCheap = (params[FORCECHEAP]->GetIntValue() != 0) || UsingEditor( params );
  478. if ( bForceCheap )
  479. {
  480. bForceExpensive = false;
  481. }
  482. else
  483. {
  484. bForceExpensive = bForceExpensive || (params[FORCEEXPENSIVE]->GetIntValue() != 0);
  485. }
  486. Assert( !( bForceCheap && bForceExpensive ) );
  487. bool bRefraction = params[REFRACTTEXTURE]->IsTexture();
  488. #ifdef _X360
  489. bool bReflection = params[REFLECTTEXTURE]->IsTexture();
  490. #else
  491. bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture();
  492. #endif
  493. bool bDrewSomething = false;
  494. if ( !bForceCheap && ( bReflection || bRefraction ) )
  495. {
  496. bDrewSomething = true;
  497. DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction );
  498. }
  499. // Use $decal to see if we are a decal or not. . if we are, then don't bother
  500. // drawing the cheap version for now since we don't have access to env_cubemap
  501. #ifdef _X360
  502. if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bForceExpensive )
  503. #else
  504. if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) )
  505. #endif
  506. {
  507. bDrewSomething = true;
  508. DrawCheapWater( params, pShaderShadow, pShaderAPI, !bForceCheap, bRefraction );
  509. }
  510. if( !bDrewSomething )
  511. {
  512. // We are likely here because of the tools. . . draw something so that
  513. // we won't go into wireframe-land.
  514. Draw();
  515. }
  516. }
  517. END_SHADER
  518. //-----------------------------------------------------------------------------
  519. // This allows us to use a block labelled 'Water_DX9_HDR' in the water materials
  520. //-----------------------------------------------------------------------------
  521. BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90,
  522. "Help for Water_DX9_HDR" )
  523. SHADER_FALLBACK
  524. {
  525. if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
  526. {
  527. return "WATER_DX90";
  528. }
  529. return 0;
  530. }
  531. END_INHERITED_SHADER