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.

962 lines
34 KiB

  1. //========= Copyright (c) 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. ConVar r_buildingmapforworld( "r_buildingmapforworld", "0" );
  12. #include "WaterCheap_vs20.inc"
  13. #include "WaterCheap_ps20.inc"
  14. #include "WaterCheap_ps20b.inc"
  15. #include "Water_vs20.inc"
  16. #include "water_ps20.inc"
  17. #include "water_ps20b.inc"
  18. #include "shaderlib/commandbuilder.h"
  19. // NOTE: This has to be the last file included!
  20. #include "tier0/memdbgon.h"
  21. DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR )
  22. BEGIN_VS_SHADER( Water_DX90,
  23. "Help for Water" )
  24. BEGIN_SHADER_PARAMS
  25. SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" )
  26. SHADER_PARAM( SCENEDEPTH, SHADER_PARAM_TYPE_TEXTURE, "", "" )
  27. SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" )
  28. SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" )
  29. SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" )
  30. SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" )
  31. SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" )
  32. SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" )
  33. SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
  34. SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
  35. SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" )
  36. SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" )
  37. 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." )
  38. 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." )
  39. SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" )
  40. SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  41. SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" )
  42. SHADER_PARAM( FORCECHEAP, 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( WATERBLENDFACTOR, 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( FLASHLIGHTTINT, SHADER_PARAM_TYPE_FLOAT, "0", "" )
  53. SHADER_PARAM( LIGHTMAPWATERFOG, SHADER_PARAM_TYPE_BOOL, "0", "" )
  54. SHADER_PARAM( FORCEFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "" )
  55. SHADER_PARAM( FORCEENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" )
  56. SHADER_PARAM( DEPTH_FEATHER, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  57. // New flow params
  58. SHADER_PARAM( FLOWMAP, SHADER_PARAM_TYPE_TEXTURE, "", "flowmap" )
  59. SHADER_PARAM( FLOWMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $flowmap" )
  60. SHADER_PARAM( FLOWMAPSCROLLRATE, SHADER_PARAM_TYPE_VEC2, "[0 0", "2D rate to scroll $flowmap" )
  61. SHADER_PARAM( FLOW_NOISE_TEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow noise texture" )
  62. SHADER_PARAM( FLOW_WORLDUVSCALE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  63. SHADER_PARAM( FLOW_NORMALUVSCALE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  64. SHADER_PARAM( FLOW_TIMEINTERVALINSECONDS, SHADER_PARAM_TYPE_FLOAT, "", "" )
  65. SHADER_PARAM( FLOW_UVSCROLLDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  66. SHADER_PARAM( FLOW_BUMPSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "", "" )
  67. SHADER_PARAM( FLOW_NOISE_SCALE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  68. SHADER_PARAM( FLOW_DEBUG, SHADER_PARAM_TYPE_BOOL, "0", "" )
  69. SHADER_PARAM( COLOR_FLOW_UVSCALE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  70. SHADER_PARAM( COLOR_FLOW_TIMEINTERVALINSECONDS, SHADER_PARAM_TYPE_FLOAT, "", "" )
  71. SHADER_PARAM( COLOR_FLOW_UVSCROLLDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "" )
  72. SHADER_PARAM( COLOR_FLOW_LERPEXP, SHADER_PARAM_TYPE_FLOAT, "", "" )
  73. SHADER_PARAM( COLOR_FLOW_DISPLACEBYNORMALSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "", "" )
  74. SHADER_PARAM( SIMPLEOVERLAY, SHADER_PARAM_TYPE_TEXTURE, "", "simpleoverlay" )
  75. END_SHADER_PARAMS
  76. SHADER_INIT_PARAMS()
  77. {
  78. if( !params[ABOVEWATER]->IsDefined() )
  79. {
  80. Warning( "***need to set $abovewater for material %s\n", pMaterialName );
  81. params[ABOVEWATER]->SetIntValue( 1 );
  82. }
  83. SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
  84. if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() )
  85. {
  86. params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f );
  87. }
  88. if( !params[CHEAPWATERENDDISTANCE]->IsDefined() )
  89. {
  90. params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f );
  91. }
  92. if( !params[SCROLL1]->IsDefined() )
  93. {
  94. params[SCROLL1]->SetVecValue( 0.0f, 0.0f, 0.0f );
  95. }
  96. if( !params[SCROLL2]->IsDefined() )
  97. {
  98. params[SCROLL2]->SetVecValue( 0.0f, 0.0f, 0.0f );
  99. }
  100. if( !params[FOGCOLOR]->IsDefined() )
  101. {
  102. params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f );
  103. Warning( "material %s needs to have a $fogcolor.\n", pMaterialName );
  104. }
  105. if( !params[REFLECTENTITIES]->IsDefined() )
  106. {
  107. params[REFLECTENTITIES]->SetIntValue( 0 );
  108. }
  109. if( !params[WATERBLENDFACTOR]->IsDefined() )
  110. {
  111. params[WATERBLENDFACTOR]->SetFloatValue( 1.0f );
  112. }
  113. if ( IsPS3() && !params[SCENEDEPTH]->IsDefined() )
  114. {
  115. params[SCENEDEPTH]->SetStringValue( "^PS3^DEPTHBUFFER" );
  116. }
  117. // If there's no envmap or reflection texture, make sure to set the reflection tint to 0 so we don't reflect garbage
  118. // (The better change would be to add static combos to support no environment map but this is a lower impact change at this point)
  119. if ( !params[ ENVMAP ]->IsDefined() && !params[ REFLECTTEXTURE ]->IsDefined() )
  120. {
  121. params[ REFLECTTINT ]->SetVecValue( 0.0f, 0.0f, 0.0f, 0.0f );
  122. }
  123. InitFloatParam( FLOW_WORLDUVSCALE, params, 1.0f );
  124. InitFloatParam( FLOW_NORMALUVSCALE, params, 1.0f );
  125. InitFloatParam( FLOW_TIMEINTERVALINSECONDS, params, 0.4f );
  126. InitFloatParam( FLOW_UVSCROLLDISTANCE, params, 0.2f );
  127. InitFloatParam( FLOW_BUMPSTRENGTH, params, 1.0f );
  128. InitFloatParam( FLOW_NOISE_SCALE, params, 0.0002f );
  129. InitFloatParam( COLOR_FLOW_UVSCALE, params, 1.0f );
  130. InitFloatParam( COLOR_FLOW_TIMEINTERVALINSECONDS, params, 0.4f );
  131. InitFloatParam( COLOR_FLOW_UVSCROLLDISTANCE, params, 0.2f );
  132. InitFloatParam( COLOR_FLOW_LERPEXP, params, 1.0f );
  133. InitFloatParam( COLOR_FLOW_DISPLACEBYNORMALSTRENGTH, params, 0.0025f );
  134. InitIntParam( FORCEENVMAP, params, 0 );
  135. InitIntParam( FORCECHEAP, params, 0 );
  136. InitFloatParam( FLASHLIGHTTINT, params, 1.0f );
  137. InitIntParam( LIGHTMAPWATERFOG, params, 0 );
  138. InitFloatParam( FORCEFRESNEL, params, -1.0f );
  139. // Fallbacks for water need lightmaps usually
  140. if ( params[BASETEXTURE]->IsDefined() || ( params[LIGHTMAPWATERFOG]->GetIntValue() != 0 ) )
  141. {
  142. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
  143. }
  144. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
  145. // Don't need bumped lightmaps unless we have a basetexture. We only use them otherwise for lighting the water fog, which only needs one sample.
  146. if( params[BASETEXTURE]->IsDefined() && g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() )
  147. {
  148. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP );
  149. }
  150. if ( !params[DEPTH_FEATHER]->IsDefined() )
  151. {
  152. params[DEPTH_FEATHER]->SetIntValue( 0 );
  153. }
  154. }
  155. SHADER_FALLBACK
  156. {
  157. return 0;
  158. }
  159. SHADER_INIT
  160. {
  161. Assert( params[WATERDEPTH]->IsDefined() );
  162. if( params[REFRACTTEXTURE]->IsDefined() )
  163. {
  164. LoadTexture( REFRACTTEXTURE, TEXTUREFLAGS_SRGB );
  165. }
  166. if( params[SCENEDEPTH]->IsDefined() )
  167. {
  168. LoadTexture( SCENEDEPTH, 0 );
  169. }
  170. if( params[REFLECTTEXTURE]->IsDefined() )
  171. {
  172. LoadTexture( REFLECTTEXTURE, TEXTUREFLAGS_SRGB );
  173. }
  174. if ( params[ENVMAP]->IsDefined() )
  175. {
  176. LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB );
  177. }
  178. if ( params[NORMALMAP]->IsDefined() )
  179. {
  180. LoadBumpMap( NORMALMAP );
  181. }
  182. if( params[BASETEXTURE]->IsDefined() )
  183. {
  184. LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB );
  185. }
  186. if ( params[FLOWMAP]->IsDefined() )
  187. {
  188. LoadTexture( FLOWMAP );
  189. }
  190. if ( params[FLOW_NOISE_TEXTURE]->IsDefined() )
  191. {
  192. LoadTexture( FLOW_NOISE_TEXTURE );
  193. }
  194. if ( params[SIMPLEOVERLAY]->IsDefined() )
  195. {
  196. LoadTexture( SIMPLEOVERLAY, TEXTUREFLAGS_SRGB );
  197. }
  198. }
  199. inline void GetVecParam( int constantVar, float *val )
  200. {
  201. if( constantVar == -1 )
  202. return;
  203. IMaterialVar* pVar = s_ppParams[constantVar];
  204. Assert( pVar );
  205. if (pVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
  206. pVar->GetVecValue( val, 4 );
  207. else
  208. val[0] = val[1] = val[2] = val[3] = pVar->GetFloatValue();
  209. }
  210. inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow,
  211. IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction )
  212. {
  213. Vector4D Scroll1;
  214. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  215. bool bHasFlowmap = params[FLOWMAP]->IsTexture();
  216. bool bHasBaseTexture = params[BASETEXTURE]->IsTexture();
  217. bool bHasMultiTexture = fabs( Scroll1.x ) > 0.0f;
  218. bool hasFlashlight = !bHasMultiTexture && UsingFlashlight( params );
  219. bool bLightmapWaterFog = ( params[LIGHTMAPWATERFOG]->GetIntValue() != 0 );
  220. bool bHasSimpleOverlay = params[SIMPLEOVERLAY]->IsTexture();
  221. bool bForceFresnel = ( params[FORCEFRESNEL]->GetFloatValue() != -1.0f );
  222. if ( bHasFlowmap )
  223. {
  224. bHasMultiTexture = false;
  225. }
  226. if ( bHasBaseTexture || bHasMultiTexture )
  227. {
  228. //hasFlashlight = false;
  229. //bLightmapWaterFog = false;
  230. }
  231. // LIGHTMAP - needed either with basetexture or lightmapwaterfog. Not sure where the bReflection restriction comes in.
  232. bool bUsingLightmap = bLightmapWaterFog || ( bReflection && bHasBaseTexture );
  233. SHADOW_STATE
  234. {
  235. SetInitialShadowState( );
  236. if ( bRefraction )
  237. {
  238. // refract sampler
  239. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  240. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, !IsX360() );
  241. }
  242. if ( bReflection )
  243. {
  244. // reflect sampler
  245. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  246. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, !IsX360() );
  247. }
  248. else
  249. {
  250. // envmap sampler
  251. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  252. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false );
  253. }
  254. if ( bHasBaseTexture )
  255. {
  256. // BASETEXTURE
  257. pShaderShadow->EnableTexture( SHADER_SAMPLER10, true );
  258. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true );
  259. }
  260. // normal map
  261. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  262. if ( bUsingLightmap )
  263. {
  264. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  265. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false );
  266. }
  267. // flowmap
  268. if ( bHasFlowmap )
  269. {
  270. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
  271. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
  272. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
  273. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, false );
  274. }
  275. if( hasFlashlight )
  276. {
  277. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
  278. pShaderShadow->EnableTexture( SHADER_SAMPLER7, true );
  279. //pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 );
  280. pShaderShadow->EnableTexture( SHADER_SAMPLER8, true );
  281. }
  282. if ( IsGameConsole() )
  283. {
  284. pShaderShadow->EnableTexture( SHADER_SAMPLER9, true );
  285. }
  286. if ( bHasSimpleOverlay )
  287. {
  288. // SIMPLEOVERLAY
  289. pShaderShadow->EnableTexture( SHADER_SAMPLER11, true );
  290. pShaderShadow->EnableSRGBRead( SHADER_SAMPLER11, true );
  291. }
  292. // pseudo-translucent water only gets used on platforms which disable refract (as a cheaper substitute for refractive water)
  293. if( IS_FLAG_SET( MATERIAL_VAR_PSEUDO_TRANSLUCENT ) )
  294. {
  295. s_pShaderShadow->EnableBlendingForceOpaque( true );
  296. s_pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  297. s_pShaderShadow->EnableDepthWrites( true );
  298. }
  299. int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T;
  300. // texcoord0 : base texcoord
  301. // texcoord1 : lightmap texcoord
  302. // texcoord2 : lightmap texcoord offset
  303. int numTexCoords = 1;
  304. // You need lightmap data if you are using lightmapwaterfog or you have a basetexture.
  305. if ( bLightmapWaterFog || bHasBaseTexture )
  306. {
  307. numTexCoords = 3;
  308. }
  309. pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 );
  310. DECLARE_STATIC_VERTEX_SHADER( water_vs20 );
  311. SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE, bHasMultiTexture );
  312. SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, bHasBaseTexture );
  313. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight );
  314. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTMAPWATERFOG, bLightmapWaterFog );
  315. SET_STATIC_VERTEX_SHADER_COMBO( FLOWMAP, bHasFlowmap );
  316. SET_STATIC_VERTEX_SHADER( water_vs20 );
  317. // "REFLECT" "0..1"
  318. // "REFRACT" "0..1"
  319. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  320. {
  321. DECLARE_STATIC_PIXEL_SHADER( water_ps20b );
  322. SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection );
  323. SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction );
  324. SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() );
  325. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE, bHasMultiTexture );
  326. SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, bHasBaseTexture );
  327. SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
  328. SET_STATIC_PIXEL_SHADER_COMBO( FLOW_DEBUG, clamp( params[ FLOW_DEBUG ]->GetIntValue(), 0, 2 ) );
  329. SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight );
  330. SET_STATIC_PIXEL_SHADER_COMBO( LIGHTMAPWATERFOG, bLightmapWaterFog );
  331. SET_STATIC_PIXEL_SHADER_COMBO( FORCEFRESNEL, bForceFresnel );
  332. SET_STATIC_PIXEL_SHADER_COMBO( SIMPLEOVERLAY, bHasSimpleOverlay );
  333. SET_STATIC_PIXEL_SHADER( water_ps20b );
  334. }
  335. else
  336. {
  337. DECLARE_STATIC_PIXEL_SHADER( water_ps20 );
  338. SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection );
  339. SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction );
  340. SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() );
  341. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE, bHasMultiTexture );
  342. SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, bHasBaseTexture );
  343. // SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
  344. SET_STATIC_PIXEL_SHADER_COMBO( FLOW_DEBUG, clamp( params[ FLOW_DEBUG ]->GetIntValue(), 0, 2 ) );
  345. SET_STATIC_PIXEL_SHADER_COMBO( FORCEFRESNEL, bForceFresnel );
  346. SET_STATIC_PIXEL_SHADER_COMBO( SIMPLEOVERLAY, bHasSimpleOverlay );
  347. SET_STATIC_PIXEL_SHADER( water_ps20 );
  348. }
  349. FogToFogColor();
  350. // we are writing linear values from this shader.
  351. pShaderShadow->EnableSRGBWrite( true );
  352. pShaderShadow->EnableAlphaWrites( true );
  353. }
  354. DYNAMIC_STATE
  355. {
  356. pShaderAPI->SetDefaultState();
  357. if ( bRefraction )
  358. {
  359. // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable
  360. BindTexture( SHADER_SAMPLER0, SRGBReadMask( !IsX360() ), REFRACTTEXTURE, -1 );
  361. }
  362. if ( bReflection )
  363. {
  364. BindTexture( SHADER_SAMPLER1, SRGBReadMask( !IsX360() ), REFLECTTEXTURE, -1 );
  365. }
  366. else if ( params[ ENVMAP ]->IsDefined() )
  367. {
  368. BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, ENVMAP );
  369. }
  370. BindTexture( SHADER_SAMPLER2, TEXTURE_BINDFLAGS_NONE, NORMALMAP, BUMPFRAME );
  371. if ( bUsingLightmap )
  372. {
  373. pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, TEXTURE_LIGHTMAP );
  374. }
  375. if( bHasBaseTexture )
  376. {
  377. BindTexture( SHADER_SAMPLER10, IsX360() ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, BASETEXTURE, FRAME );
  378. }
  379. if ( bHasFlowmap )
  380. {
  381. BindTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, FLOWMAP, FLOWMAPFRAME );
  382. BindTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, FLOW_NOISE_TEXTURE );
  383. float vFlowConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  384. vFlowConst1[0] = 1.0f / params[ FLOW_WORLDUVSCALE ]->GetFloatValue();
  385. vFlowConst1[1] = 1.0f / params[ FLOW_NORMALUVSCALE ]->GetFloatValue();
  386. vFlowConst1[2] = params[ FLOW_BUMPSTRENGTH ]->GetFloatValue();
  387. vFlowConst1[3] = params[ COLOR_FLOW_DISPLACEBYNORMALSTRENGTH ]->GetFloatValue();
  388. pShaderAPI->SetPixelShaderConstant( 13, vFlowConst1, 1 );
  389. float vFlowConst2[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  390. vFlowConst2[0] = params[ FLOW_TIMEINTERVALINSECONDS ]->GetFloatValue();
  391. vFlowConst2[1] = params[ FLOW_UVSCROLLDISTANCE ]->GetFloatValue();
  392. vFlowConst2[2] = params[ FLOW_NOISE_SCALE ]->GetFloatValue();
  393. pShaderAPI->SetPixelShaderConstant( 14, vFlowConst2, 1 );
  394. float vColorFlowConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  395. vColorFlowConst1[0] = 1.0f / params[ COLOR_FLOW_UVSCALE ]->GetFloatValue();
  396. vColorFlowConst1[1] = params[ COLOR_FLOW_TIMEINTERVALINSECONDS ]->GetFloatValue();
  397. vColorFlowConst1[2] = params[ COLOR_FLOW_UVSCROLLDISTANCE ]->GetFloatValue();
  398. vColorFlowConst1[3] = params[ COLOR_FLOW_LERPEXP ]->GetFloatValue();
  399. pShaderAPI->SetPixelShaderConstant( 26, vColorFlowConst1, 1 );
  400. }
  401. if( bHasSimpleOverlay )
  402. {
  403. BindTexture( SHADER_SAMPLER11, TEXTURE_BINDFLAGS_SRGBREAD, SIMPLEOVERLAY );
  404. }
  405. if ( IsGameConsole() )
  406. {
  407. if ( IsPS3() )
  408. {
  409. BindTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, SCENEDEPTH, -1 );
  410. }
  411. else if ( IsX360() )
  412. {
  413. pShaderAPI->BindStandardTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, TEXTURE_FRAME_BUFFER_FULL_DEPTH );
  414. }
  415. else
  416. {
  417. Error( "water.cpp: Unsupported console platform.\n" );
  418. }
  419. VMatrix viewMatrix, projMatrix, worldToProjMatrix, projToWorldMatrix;
  420. pShaderAPI->GetMatrix( MATERIAL_VIEW, viewMatrix.m[0] );
  421. pShaderAPI->GetActualProjectionMatrix( projMatrix.m[0] );
  422. // The view and proj matrices are transposed vs. what you would normally expect, argh.
  423. //viewMatrix = viewMatrix.Transpose();
  424. //projMatrix = projMatrix.Transpose();
  425. //MatrixMultiply( projMatrix, viewMatrix, worldToProjMatrix );
  426. //MatrixInverseGeneral( worldToProjMatrix, projToWorldMatrix );
  427. // One less transpose.
  428. MatrixMultiply( viewMatrix, projMatrix, worldToProjMatrix );
  429. MatrixInverseGeneral( worldToProjMatrix, projToWorldMatrix );
  430. projToWorldMatrix = projToWorldMatrix.Transpose();
  431. // Send down rows 2 (Z) and 3 (W), because that's all the water shader needs to recover worldspace Z.
  432. pShaderAPI->SetPixelShaderConstant( 33, &projToWorldMatrix.m[2][0], 1 );
  433. pShaderAPI->SetPixelShaderConstant( 34, &projToWorldMatrix.m[3][0], 1 );
  434. int nDepthFeather = params[DEPTH_FEATHER]->GetIntValue();
  435. const float flDepthFeatherDistanceFactor = .16f;
  436. Vector4D vEdgeFeatheringParams( flDepthFeatherDistanceFactor, nDepthFeather ? 0.0f : 1.0f, 0.0f, 0.0f );
  437. pShaderAPI->SetPixelShaderConstant( 35, vEdgeFeatheringParams.Base(), 1 );
  438. }
  439. // Time
  440. float vTimeConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  441. float flTime = pShaderAPI->CurrentTime();
  442. vTimeConst[0] = flTime;
  443. //vTimeConst[0] -= ( float )( ( int )( vTimeConst[0] / 1000.0f ) ) * 1000.0f;
  444. pShaderAPI->SetPixelShaderConstant( 8, vTimeConst, 1 );
  445. // These constants are used to rotate the world space water normals around the up axis to align the
  446. // normal with the camera and then give us a 2D offset vector to use for reflection and refraction uv's
  447. VMatrix mView;
  448. pShaderAPI->GetMatrix( MATERIAL_VIEW, mView.m[0] );
  449. mView = mView.Transpose3x3();
  450. Vector4D vCameraRight( mView.m[0][0], mView.m[0][1], mView.m[0][2], 0.0f );
  451. vCameraRight.z = 0.0f; // Project onto the plane of water
  452. vCameraRight.AsVector3D().NormalizeInPlace();
  453. Vector4D vCameraForward;
  454. CrossProduct( Vector( 0.0f, 0.0f, 1.0f ), vCameraRight.AsVector3D(), vCameraForward.AsVector3D() ); // I assume the water surface normal is pointing along z!
  455. pShaderAPI->SetPixelShaderConstant( 22, vCameraRight.Base() );
  456. pShaderAPI->SetPixelShaderConstant( 23, vCameraForward.Base() );
  457. SetPixelShaderConstant( 25, FORCEFRESNEL );
  458. // Refraction tint
  459. if( bRefraction )
  460. {
  461. SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT );
  462. }
  463. // Reflection tint
  464. if ( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
  465. {
  466. // Need to multiply by 4 in linear space since we premultiplied into
  467. // the render target by .25 to get overbright data in the reflection render target.
  468. float gammaReflectTint[3];
  469. params[REFLECTTINT]->GetVecValue( gammaReflectTint, 3 );
  470. float linearReflectTint[4];
  471. linearReflectTint[0] = GammaToLinear( gammaReflectTint[0] ) * 4.0f;
  472. linearReflectTint[1] = GammaToLinear( gammaReflectTint[1] ) * 4.0f;
  473. linearReflectTint[2] = GammaToLinear( gammaReflectTint[2] ) * 4.0f;
  474. linearReflectTint[3] = params[WATERBLENDFACTOR]->GetFloatValue();
  475. pShaderAPI->SetPixelShaderConstant( 4, linearReflectTint, 1 );
  476. }
  477. else
  478. {
  479. SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT, WATERBLENDFACTOR );
  480. }
  481. SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM );
  482. float curtime=pShaderAPI->CurrentTime();
  483. float vc0[4];
  484. float v0[4];
  485. params[SCROLL1]->GetVecValue(v0,4);
  486. vc0[0]=curtime*v0[0];
  487. vc0[1]=curtime*v0[1];
  488. params[SCROLL2]->GetVecValue(v0,4);
  489. vc0[2]=curtime*v0[0];
  490. vc0[3]=curtime*v0[1];
  491. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 );
  492. float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f };
  493. pShaderAPI->SetPixelShaderConstant( 0, c0, 1 );
  494. float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f };
  495. pShaderAPI->SetPixelShaderConstant( 2, c2, 1 );
  496. // fresnel constants
  497. float c3[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
  498. pShaderAPI->SetPixelShaderConstant( 3, c3, 1 );
  499. float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(),
  500. params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() };
  501. pShaderAPI->SetPixelShaderConstant( 5, c5, 1 );
  502. #if 0
  503. SetPixelShaderConstantGammaToLinear( 6, FOGCOLOR );
  504. #else
  505. // Need to use the srgb curve since that we do in UpdatePixelFogColorConstant so that we match the older version of water where we render to an offscreen buffer and fog on the way in.
  506. float fogColorConstant[4];
  507. params[FOGCOLOR]->GetVecValue( fogColorConstant, 3 );
  508. fogColorConstant[3] = 0.0f;
  509. fogColorConstant[0] = SrgbGammaToLinear( fogColorConstant[0] );
  510. fogColorConstant[1] = SrgbGammaToLinear( fogColorConstant[1] );
  511. fogColorConstant[2] = SrgbGammaToLinear( fogColorConstant[2] );
  512. pShaderAPI->SetPixelShaderConstant( 6, fogColorConstant, 1 );
  513. #endif
  514. float c7[4] =
  515. {
  516. params[FOGSTART]->GetFloatValue(),
  517. params[FOGEND]->GetFloatValue() - params[FOGSTART]->GetFloatValue(),
  518. 1.0f,
  519. 0.0f
  520. };
  521. if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER )
  522. {
  523. // water overbright factor
  524. c7[2] = 4.0;
  525. }
  526. pShaderAPI->SetPixelShaderConstant( 7, c7, 1 );
  527. pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
  528. float vEyePos_SpecExponent[4];
  529. pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
  530. vEyePos_SpecExponent[3] = 0.0f;
  531. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
  532. if( bHasFlowmap )
  533. {
  534. SetPixelShaderConstant( 9, FLOWMAPSCROLLRATE );
  535. }
  536. DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 );
  537. SET_DYNAMIC_VERTEX_SHADER( water_vs20 );
  538. #ifdef _PS3
  539. CCommandBufferBuilder< CDynamicCommandStorageBuffer > DynamicCmdsOut;
  540. #else
  541. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  542. #endif
  543. bool bFlashlightShadows = false;
  544. bool bUberlight = false;
  545. if( hasFlashlight )
  546. {
  547. #ifdef _PS3
  548. CCommandBufferBuilder< CFixedCommandStorageBuffer< 256 > > flashlightECB;
  549. #endif
  550. pShaderAPI->GetFlashlightShaderInfo( &bFlashlightShadows, &bUberlight );
  551. #ifdef _PS3
  552. {
  553. flashlightECB.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 );
  554. }
  555. #endif
  556. if( IsX360())
  557. {
  558. DynamicCmdsOut.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 );
  559. }
  560. CBCmdSetPixelShaderFlashlightState_t state;
  561. state.m_LightSampler = SHADER_SAMPLER6; // FIXME . . don't want this here.
  562. state.m_DepthSampler = SHADER_SAMPLER7;
  563. state.m_ShadowNoiseSampler = SHADER_SAMPLER8;
  564. state.m_nColorConstant = PSREG_FLASHLIGHT_COLOR;
  565. state.m_nAttenConstant = 15;
  566. state.m_nOriginConstant = 16;
  567. state.m_nDepthTweakConstant = 21;
  568. state.m_nScreenScaleConstant = PSREG_FLASHLIGHT_SCREEN_SCALE;
  569. state.m_nWorldToTextureConstant = -1;
  570. state.m_bFlashlightNoLambert = false;
  571. state.m_bSinglePassFlashlight = true;
  572. #ifdef _PS3
  573. {
  574. flashlightECB.SetPixelShaderFlashlightState( state );
  575. flashlightECB.End();
  576. ShaderApiFast( pShaderAPI )->ExecuteCommandBufferPPU( flashlightECB.Base() );
  577. }
  578. #else
  579. {
  580. DynamicCmdsOut.SetPixelShaderFlashlightState( state );
  581. }
  582. #endif
  583. DynamicCmdsOut.SetPixelShaderConstant( 10, FLASHLIGHTTINT );
  584. }
  585. // Get viewport and render target dimensions and set shader constant to do a 2D mad
  586. int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
  587. pShaderAPI->GetCurrentViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );
  588. int nRtWidth, nRtHeight;
  589. pShaderAPI->GetCurrentRenderTargetDimensions( nRtWidth, nRtHeight );
  590. float vViewportMad[4];
  591. // viewport->screen transform
  592. vViewportMad[0] = ( float )nViewportWidth / ( float )nRtWidth;
  593. vViewportMad[1] = ( float )nViewportHeight / ( float )nRtHeight;
  594. vViewportMad[2] = ( float )nViewportX / ( float )nRtWidth;
  595. vViewportMad[3] = ( float )nViewportY / ( float )nRtHeight;
  596. DynamicCmdsOut.SetPixelShaderConstant( 24, vViewportMad, 1 );
  597. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  598. {
  599. DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b );
  600. SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
  601. SET_DYNAMIC_PIXEL_SHADER( water_ps20b );
  602. }
  603. else
  604. {
  605. DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 );
  606. SET_DYNAMIC_PIXEL_SHADER( water_ps20 );
  607. }
  608. DynamicCmdsOut.End();
  609. pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  610. }
  611. Draw();
  612. }
  613. inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow,
  614. IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bRefraction )
  615. {
  616. bool bHasFlowmap = params[FLOWMAP]->IsTexture();
  617. SHADOW_STATE
  618. {
  619. SetInitialShadowState( );
  620. // In edit mode, use nocull
  621. if ( UsingEditor( params ) )
  622. {
  623. s_pShaderShadow->EnableCulling( false );
  624. }
  625. if( bBlend )
  626. {
  627. EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  628. }
  629. // envmap
  630. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  631. // normal map
  632. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  633. if( bRefraction && bBlend )
  634. {
  635. // refraction map (used for alpha)
  636. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
  637. }
  638. // Noise texture
  639. if ( bHasFlowmap )
  640. {
  641. pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
  642. pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
  643. }
  644. // Normalizing cube map
  645. pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
  646. int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T;
  647. pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
  648. DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 );
  649. SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction );
  650. SET_STATIC_VERTEX_SHADER( watercheap_vs20 );
  651. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  652. {
  653. DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b );
  654. SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 );
  655. SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend );
  656. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction );
  657. SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() );
  658. Vector4D Scroll1;
  659. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  660. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  661. SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
  662. SET_STATIC_PIXEL_SHADER_COMBO( FLOW_DEBUG, clamp( params[ FLOW_DEBUG ]->GetIntValue(), 0, 2 ) );
  663. SET_STATIC_PIXEL_SHADER( watercheap_ps20b );
  664. }
  665. else
  666. {
  667. DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 );
  668. SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 );
  669. SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend );
  670. SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction );
  671. SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() );
  672. Vector4D Scroll1;
  673. params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 );
  674. SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0);
  675. SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap );
  676. SET_STATIC_PIXEL_SHADER_COMBO( FLOW_DEBUG, clamp( params[ FLOW_DEBUG ]->GetIntValue(), 0, 2 ) );
  677. SET_STATIC_PIXEL_SHADER( watercheap_ps20 );
  678. }
  679. // HDRFIXME: test cheap water!
  680. if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
  681. {
  682. // we are writing linear values from this shader.
  683. pShaderShadow->EnableSRGBWrite( true );
  684. }
  685. FogToFogColor();
  686. }
  687. DYNAMIC_STATE
  688. {
  689. pShaderAPI->SetDefaultState();
  690. BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_NONE, ENVMAP, ENVMAPFRAME );
  691. BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_NONE, NORMALMAP, BUMPFRAME );
  692. if( bRefraction && bBlend )
  693. {
  694. BindTexture( SHADER_SAMPLER2, TEXTURE_BINDFLAGS_NONE, REFRACTTEXTURE, -1 );
  695. }
  696. if ( bHasFlowmap )
  697. {
  698. BindTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, FLOWMAP );
  699. BindTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, FLOW_NOISE_TEXTURE );
  700. float vFlowConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  701. vFlowConst1[0] = 1.0f / params[ FLOW_WORLDUVSCALE ]->GetFloatValue();
  702. vFlowConst1[1] = 1.0f / params[ FLOW_NORMALUVSCALE ]->GetFloatValue();
  703. vFlowConst1[2] = params[ FLOW_BUMPSTRENGTH ]->GetFloatValue();
  704. pShaderAPI->SetPixelShaderConstant( 13, vFlowConst1, 1 );
  705. float vFlowConst2[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  706. vFlowConst2[0] = params[ FLOW_TIMEINTERVALINSECONDS ]->GetFloatValue();
  707. vFlowConst2[1] = params[ FLOW_UVSCROLLDISTANCE ]->GetFloatValue();
  708. vFlowConst2[2] = params[ FLOW_NOISE_SCALE ]->GetFloatValue();
  709. pShaderAPI->SetPixelShaderConstant( 14, vFlowConst2, 1 );
  710. // Time % 1000
  711. float vTimeConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  712. float flTime = pShaderAPI->CurrentTime();
  713. vTimeConst[0] = flTime;
  714. //vTimeConst[0] -= ( float )( ( int )( vTimeConst[0] / 1000.0f ) ) * 1000.0f;
  715. pShaderAPI->SetPixelShaderConstant( 10, vTimeConst, 1 );
  716. }
  717. pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
  718. SetPixelShaderConstant( 0, FOGCOLOR );
  719. float cheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue();
  720. float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue();
  721. float cheapWaterParams[4] =
  722. {
  723. cheapWaterStartDistance * VSHADER_VECT_SCALE,
  724. cheapWaterEndDistance * VSHADER_VECT_SCALE,
  725. PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ),
  726. cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ),
  727. };
  728. pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams );
  729. if( g_pConfig->bShowSpecular )
  730. {
  731. SetPixelShaderConstant( 2, REFLECTTINT, WATERBLENDFACTOR );
  732. }
  733. else
  734. {
  735. float zero[4] = { 0.0f, 0.0f, 0.0f, params[WATERBLENDFACTOR]->GetFloatValue() };
  736. pShaderAPI->SetPixelShaderConstant( 2, zero );
  737. }
  738. pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
  739. float vEyePos_SpecExponent[4];
  740. pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
  741. vEyePos_SpecExponent[3] = 0.0f;
  742. pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
  743. if( params[SCROLL1]->IsDefined())
  744. {
  745. float curtime=pShaderAPI->CurrentTime();
  746. float vc0[4];
  747. float v0[4];
  748. params[SCROLL1]->GetVecValue(v0,4);
  749. vc0[0]=curtime*v0[0];
  750. vc0[1]=curtime*v0[1];
  751. params[SCROLL2]->GetVecValue(v0,4);
  752. vc0[2]=curtime*v0[0];
  753. vc0[3]=curtime*v0[1];
  754. pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 );
  755. }
  756. DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 );
  757. SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 );
  758. if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  759. {
  760. DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b );
  761. SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() );
  762. SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b );
  763. }
  764. else
  765. {
  766. DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 );
  767. SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() );
  768. SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 );
  769. }
  770. }
  771. Draw();
  772. }
  773. SHADER_DRAW
  774. {
  775. bool bRefraction = params[REFRACTTEXTURE]->IsTexture();
  776. bool bReflection = params[REFLECTTEXTURE]->IsTexture();
  777. bool bEnvMap = params[ENVMAP]->IsTexture() && ( params[FORCEENVMAP]->GetIntValue() == 1 );
  778. bool bForceCheap = ( params[FORCECHEAP]->GetIntValue() != 0 );
  779. if ( ( bReflection || bRefraction || bEnvMap ) && !UsingEditor( params ) && !bForceCheap )
  780. {
  781. #ifdef _GAMECONSOLE
  782. {
  783. if ( IS_FLAG_SET( MATERIAL_VAR_PSEUDO_TRANSLUCENT ) )
  784. {
  785. // Do not render pseudo translucent water during the auto Z pass on Xbox 360
  786. if ( pShaderAPI )
  787. {
  788. pShaderAPI->EnablePredication( false, true );
  789. }
  790. }
  791. }
  792. #endif // _GAMECONSOLE
  793. DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction );
  794. #ifdef _GAMECONSOLE
  795. {
  796. if ( IS_FLAG_SET( MATERIAL_VAR_PSEUDO_TRANSLUCENT ) )
  797. {
  798. if ( pShaderAPI )
  799. {
  800. pShaderAPI->DisablePredication();
  801. }
  802. }
  803. }
  804. #endif // _GAMECONSOLE
  805. }
  806. else
  807. {
  808. bool bBlend = false;
  809. DrawCheapWater( params, pShaderShadow, pShaderAPI, bBlend, bRefraction );
  810. }
  811. }
  812. END_SHADER
  813. //-----------------------------------------------------------------------------
  814. // This allows us to use a block labelled 'Water_DX9_HDR' in the water materials
  815. //-----------------------------------------------------------------------------
  816. BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90,
  817. "Help for Water_DX9_HDR" )
  818. SHADER_FALLBACK
  819. {
  820. if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
  821. {
  822. return "WATER_DX90";
  823. }
  824. return 0;
  825. }
  826. END_INHERITED_SHADER