OceanDisplacement.fx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. //////////////////////////////////////////////////////////////////////////////
  2. // ©2007 Electronic Arts Inc
  3. //
  4. // Shader for ocean displacement waves
  5. //////////////////////////////////////////////////////////////////////////////
  6. #include "Common.fxh"
  7. SAMPLER_2D_BEGIN( DisplacementTexture,
  8. string SasBindAddress = "Water.DisplacementTexture";
  9. )
  10. MinFilter = Linear;
  11. MagFilter = Linear;
  12. MipFilter = Point;
  13. AddressU = Clamp;
  14. AddressV = Clamp;
  15. SAMPLER_2D_END
  16. float DisplacementTextureSize
  17. <
  18. string SasBindAddress = "Water.DisplacementTextureSize";
  19. > = 0;
  20. SAMPLER_2D_BEGIN( StaticDisplacementTexture,
  21. string SasBindAddress = "Water.StaticDisplacementTexture";
  22. )
  23. MinFilter = Linear;
  24. MagFilter = Linear;
  25. MipFilter = Linear;
  26. AddressU = Wrap;
  27. AddressV = Wrap;
  28. SAMPLER_2D_END
  29. // ----------------------------------------------------------------------------
  30. // Transformations
  31. // ----------------------------------------------------------------------------
  32. float4x4 ViewI : ViewInverse;
  33. float4x4 ProjectionI : ProjectionInverse;
  34. #if defined(_WW3D_)
  35. #if !defined(USE_INDIRECT_CONSTANT)
  36. float4x4 ViewProjection
  37. <
  38. string UIWidget = "None";
  39. string SasBindAddress = "Sas.Camera.WorldToProjection";
  40. >;
  41. #endif // #if !defined(USE_INDIRECT_CONSTANT)
  42. float4x4 GetViewProjection()
  43. {
  44. return ViewProjection;
  45. }
  46. #else
  47. float4x4 View : View;
  48. float4x4 Projection : Projection;
  49. float4x4 GetViewProjection()
  50. {
  51. return mul(View, Projection);
  52. }
  53. #endif
  54. float Time : Time;
  55. // ----------------------------------------------------------------------------
  56. struct VSOutput_RenderWaveParticles
  57. {
  58. float4 Position : POSITION;
  59. float Amplitude : TEXCOORD0;
  60. };
  61. // ----------------------------------------------------------------------------
  62. VSOutput_RenderWaveParticles VS_RenderWaveParticles(float4 StartPosition_Velocity : POSITION, float2 StartAmplitude_CreationTime : TEXCOORD0)
  63. {
  64. float2 startPosition = StartPosition_Velocity.xy;
  65. float2 velocity = StartPosition_Velocity.zw;
  66. float startAmplitude = StartAmplitude_CreationTime.x;
  67. float creationTime = StartAmplitude_CreationTime.y;
  68. float age = Time - creationTime;
  69. float2 position = startPosition + age * velocity;
  70. float amplitude = startAmplitude;
  71. // Wave particles that should be explicitly faded in and out, are uploaded with a negative amplitude.
  72. if (startAmplitude < 0.0f)
  73. {
  74. amplitude = abs(amplitude);
  75. float fadeInTime = 2.0; // Number of seconds to linearly fade in
  76. float fadeOutFactor = 4.0; // "Steepness" of the curve for fade out falloff
  77. // Note: If this formula or the fadeOutFactor changes, external code should be changed as well, so that the actual particle deletion occurs at the correct time.
  78. amplitude *= exp(-age / fadeOutFactor);
  79. // amplitude /= (age + 1); // Alternative to try out
  80. amplitude *= saturate(age / fadeInTime);
  81. }
  82. // Transform position from world space into the render target's space
  83. float2 positionXY = mul(float4(position, 0, 1), GetViewProjection()).xy;
  84. VSOutput_RenderWaveParticles Out;
  85. Out.Position = float4(positionXY, 0, 1);
  86. Out.Amplitude = min(amplitude,1);
  87. return Out;
  88. }
  89. // ----------------------------------------------------------------------------
  90. float4 PS_RenderWaveParticles(VSOutput_RenderWaveParticles In) : COLOR
  91. {
  92. #if defined(EA_PLATFORM_XENON) // scale range on xenon
  93. float4 color = float4(In.Amplitude * 0.5, In.Amplitude * 0.5, In.Amplitude, 0);
  94. #else
  95. float4 color = float4(In.Amplitude, In.Amplitude, In.Amplitude, 0);
  96. #endif
  97. #if defined(EA_PLATFORM_XENON) // divide by 4 since we divide the texture area by 4 on xenon
  98. color /= 4;
  99. #endif
  100. return color;
  101. }
  102. // ----------------------------------------------------------------------------
  103. technique RenderWaveParticles
  104. {
  105. pass P0
  106. {
  107. VertexShader = compile VS_2_0 VS_RenderWaveParticles();
  108. PixelShader = compile PS_2_0 PS_RenderWaveParticles();
  109. ZEnable = false;
  110. ZWriteEnable = false;
  111. CullMode = None;
  112. AlphaTestEnable = false;
  113. AlphaBlendEnable = true;
  114. SrcBlend = One;
  115. DestBlend = One;
  116. }
  117. }
  118. // ----------------------------------------------------------------------------
  119. struct VSOutput_Blur
  120. {
  121. float4 Position : POSITION;
  122. float2 TexCoord : TEXCOORD0;
  123. };
  124. // ----------------------------------------------------------------------------
  125. VSOutput_Blur VS_Blur(float3 Position : POSITION, float2 TexCoord : TEXCOORD0)
  126. {
  127. VSOutput_Blur Out;
  128. Out.Position = float4(Position, 1);
  129. Out.TexCoord = TexCoord;
  130. return Out;
  131. }
  132. // ----------------------------------------------------------------------------
  133. // Two dimensional version of the wave particle "blurring". More expensive, but can be used to prototype different wave shapes better
  134. float4 PS_Blur2D(VSOutput_Blur In, uniform float2 direction) : COLOR
  135. {
  136. //return tex2D(SAMPLER(DisplacementTexture), In.TexCoord + .2).xxxx;
  137. //return float4(0.5, 0, 0, 0);
  138. static const int kernelSize = 10;
  139. static const float textureSize = DisplacementTextureSize;
  140. float3 result = 0;
  141. for (int j = -kernelSize; j <= kernelSize; j++)
  142. for (int i = -kernelSize; i <= kernelSize; i++)
  143. {
  144. float2 texCoord = In.TexCoord + float2(i, j) /* * direction */ / textureSize;
  145. float radius = 10;
  146. const float pi = 3.14159265;
  147. float phase = pi * min(length(float2(i, j)) / radius, 1);
  148. float transversalFactor = 0.5 * (cos(phase) + 1);
  149. float2 longitudinalFactor = -sin(phase) * transversalFactor * normalize(float2(i, j)) * radius;
  150. //float2 longitudinalFactor = -sin(phase) * transversalFactor * float2(i, j);
  151. float3 factor = float3(longitudinalFactor, transversalFactor);
  152. result += tex2D(SAMPLER(DisplacementTexture), texCoord).zzz * factor;
  153. }
  154. result /= (kernelSize * 2 + 1) * (kernelSize * 2 + 1);
  155. //result *= 20;
  156. result /= 50;
  157. result.xy /= -2;
  158. result.y *= -1;
  159. return float4(result, 0);
  160. }
  161. #if defined(EA_PLATFORM_WINDOWS)
  162. static const int kernelSize = 10;
  163. #elif defined(EA_PLATFORM_XENON) || defined(EA_PLATFORM_PS3)
  164. static const int kernelSize = 5;
  165. #endif
  166. static const float radius = float(kernelSize);
  167. static const float pi = 3.14159265;
  168. float computeTransversalFactor( float index )
  169. {
  170. return 0.5 * (cos(pi * index / radius) + 1);
  171. }
  172. float computeLongitudinalFactor( float index )
  173. {
  174. return -sin(pi * index / radius) * radius;
  175. }
  176. float4 PS_Blur(VSOutput_Blur In, uniform float2 direction) : COLOR
  177. {
  178. STATICARRAY const float textureSize = DisplacementTextureSize;
  179. STATICARRAY const float transversalFactor[kernelSize * 2 + 1] = {
  180. #if defined(EA_PLATFORM_WINDOWS)
  181. computeTransversalFactor(-10),
  182. computeTransversalFactor(-9),
  183. computeTransversalFactor(-8),
  184. computeTransversalFactor(-7),
  185. computeTransversalFactor(-6),
  186. #endif
  187. computeTransversalFactor(-5),
  188. computeTransversalFactor(-4),
  189. computeTransversalFactor(-3),
  190. computeTransversalFactor(-2),
  191. computeTransversalFactor(-1),
  192. computeTransversalFactor(0),
  193. computeTransversalFactor(1),
  194. computeTransversalFactor(2),
  195. computeTransversalFactor(3),
  196. computeTransversalFactor(4),
  197. computeTransversalFactor(5),
  198. #if defined(EA_PLATFORM_WINDOWS)
  199. computeTransversalFactor(6),
  200. computeTransversalFactor(7),
  201. computeTransversalFactor(8),
  202. computeTransversalFactor(9),
  203. computeTransversalFactor(10),
  204. #endif
  205. };
  206. STATICARRAY const float longitudinalFactor[kernelSize * 2 + 1] = {
  207. #if defined(EA_PLATFORM_WINDOWS)
  208. computeLongitudinalFactor(-10),
  209. computeLongitudinalFactor(-9),
  210. computeLongitudinalFactor(-8),
  211. computeLongitudinalFactor(-7),
  212. computeLongitudinalFactor(-6),
  213. #endif
  214. computeLongitudinalFactor(-5),
  215. computeLongitudinalFactor(-4),
  216. computeLongitudinalFactor(-3),
  217. computeLongitudinalFactor(-2),
  218. computeLongitudinalFactor(-1),
  219. computeLongitudinalFactor(0),
  220. computeLongitudinalFactor(1),
  221. computeLongitudinalFactor(2),
  222. computeLongitudinalFactor(3),
  223. computeLongitudinalFactor(4),
  224. computeLongitudinalFactor(5),
  225. #if defined(EA_PLATFORM_WINDOWS)
  226. computeLongitudinalFactor(6),
  227. computeLongitudinalFactor(7),
  228. computeLongitudinalFactor(8),
  229. computeLongitudinalFactor(9),
  230. computeLongitudinalFactor(10),
  231. #endif
  232. };
  233. float3 result = 0;
  234. for (int i = -kernelSize; i <= kernelSize; i++)
  235. {
  236. float2 texCoord = In.TexCoord + i * direction / textureSize;
  237. // For the "separable blur" in two passes, we want to modulate always both x and y distortion
  238. // by the transversal wave factor (that causes the bell shape of the wave),
  239. // but also during the horizontal pass we want to apply the longitudinal factor to the x component,
  240. // and in the vertical pass to the y component.
  241. float3 factor = float3(lerp(1, longitudinalFactor[i+kernelSize], direction), 1) * transversalFactor[i+kernelSize];
  242. float3 val = tex2D(SAMPLER(DisplacementTexture), texCoord).xyz;
  243. #if defined(EA_PLATFORM_XENON) // scale range on xenon (scale up to full range float)
  244. val.xy = val.xy * 2 - 1;
  245. #endif
  246. result += val * factor;
  247. }
  248. result /= kernelSize * 2 + 1;
  249. result.xy /= 2;// decrease longitudinal wave strength by arbitrary amount
  250. #if defined(EA_PLATFORM_XENON) // scale range on xenon (reduce back to int)
  251. result.xy = result.xy * 0.5 + 0.5;
  252. #endif
  253. return float4(result,0);
  254. }
  255. technique BlurU
  256. {
  257. pass p0
  258. {
  259. VertexShader = compile VS_3_0 VS_Blur();
  260. PixelShader = compile PS_3_0 PS_Blur(float2(1.0, 0.0));
  261. ZEnable = false;
  262. ZWriteEnable = false;
  263. CullMode = None;
  264. AlphaBlendEnable = false;
  265. AlphaTestEnable = false;
  266. }
  267. }
  268. technique BlurV
  269. {
  270. pass p0
  271. {
  272. VertexShader = compile VS_3_0 VS_Blur();
  273. PixelShader = compile PS_3_0 PS_Blur(float2(0.0, 1.0));
  274. ZEnable = false;
  275. ZWriteEnable = false;
  276. CullMode = None;
  277. AlphaBlendEnable = false;
  278. AlphaTestEnable = false;
  279. }
  280. }
  281. // ----------------------------------------------------------------------------
  282. struct VSOutput_StaticDisplacement
  283. {
  284. float4 Position : POSITION;
  285. float2 TexCoord : TEXCOORD0;
  286. float2 StaticTexCoord : TEXCOORD1;
  287. };
  288. // ----------------------------------------------------------------------------
  289. VSOutput_StaticDisplacement VS_StaticDisplacement(float3 Position : POSITION, float2 TexCoord : TEXCOORD0)
  290. {
  291. VSOutput_StaticDisplacement Out;
  292. Out.Position = float4(Position, 1);
  293. Out.TexCoord = TexCoord;
  294. TexCoord.y = 1 - TexCoord.y;
  295. Out.StaticTexCoord = mul(float4(TexCoord * 2 - 1, 0, 1), mul(ProjectionI, ViewI)).xy;
  296. return Out;
  297. }
  298. // ----------------------------------------------------------------------------
  299. float4 PS_StaticDisplacement(VSOutput_StaticDisplacement In) : COLOR
  300. {
  301. //return float4(In.StaticTexCoord / 2000, 0, 0);
  302. // float3 dynamicDisplacement = tex2D(SAMPLER(DisplacementTexture), In.TexCoord).xyz;
  303. // -------------------------------------------------------------------------------
  304. // -- Static Displacment and Mapping ---------------------------------------------
  305. // -------------------------------------------------------------------------------
  306. // Build Static Tex coords ---------------------------------------------------
  307. float StaticDispDivergenceAngle = 75;
  308. float StaticDispScalar = 2; // create a more managable number in MAX sliders
  309. float StaticDispSpeed = Time * 45; // animate Octave 3 as a multiplier of Time
  310. float2 StaticDispTexCoords = In.StaticTexCoord * StaticDispScalar;
  311. // Build StaticDisp Texture Rotation Matrix And Convert Degrees to Radians --
  312. float cosAngle, sinAngle;
  313. cosAngle = 0;
  314. sinAngle = 0;
  315. sincos (StaticDispDivergenceAngle * .017453, sinAngle, cosAngle);
  316. float2x2 uvCoordRotate = { 1.0f, 0.0f, 1.0f, 0.0f };
  317. uvCoordRotate[0][0] = cosAngle;
  318. uvCoordRotate[0][1] = -sinAngle;
  319. uvCoordRotate[1][1] = uvCoordRotate[0][0];
  320. uvCoordRotate[1][0] = -uvCoordRotate[0][1];
  321. // Rotate and Animate StaticDisp Divergence Texture Coords --------------------
  322. float2 StaticDispTexCoordsDiverge = mul(StaticDispTexCoords, uvCoordRotate);
  323. StaticDispTexCoordsDiverge.x += StaticDispSpeed;
  324. float2 StaticDispTexCoordsDivergeInv = mul(StaticDispTexCoords, transpose(uvCoordRotate));
  325. StaticDispTexCoordsDivergeInv.x += StaticDispSpeed;
  326. float staticDisplacement = tex2D(SAMPLER(StaticDisplacementTexture), StaticDispTexCoordsDiverge / 2000).w * 2 - 1;
  327. staticDisplacement += tex2D(SAMPLER(StaticDisplacementTexture), StaticDispTexCoordsDivergeInv / 2000).w * 2 - 1;
  328. float displacement = staticDisplacement *.06;
  329. #if defined(EA_PLATFORM_XENON) // scale range on xenon
  330. return float4(displacement * 0.5, displacement * 0.5, displacement, 0);
  331. #else
  332. return float4(displacement, displacement, displacement, 0);
  333. #endif
  334. }
  335. technique StaticDisplacement
  336. {
  337. pass p0
  338. {
  339. VertexShader = compile VS_3_0 VS_StaticDisplacement();
  340. PixelShader = compile PS_3_0 PS_StaticDisplacement();
  341. ZEnable = false;
  342. ZWriteEnable = false;
  343. CullMode = None;
  344. AlphaTestEnable = false;
  345. AlphaBlendEnable = true;
  346. SrcBlend = One;
  347. DestBlend = One;
  348. }
  349. }
  350. // ----------------------------------------------------------------------------
  351. struct VSOutput_DebugDisplayDisplacement
  352. {
  353. float4 Position : POSITION;
  354. float2 TexCoord : TEXCOORD0;
  355. };
  356. // ----------------------------------------------------------------------------
  357. VSOutput_DebugDisplayDisplacement VS_DebugDisplayDisplacement(float3 Position : POSITION, float2 TexCoord : TEXCOORD0)
  358. {
  359. VSOutput_DebugDisplayDisplacement Out;
  360. Out.Position = float4(Position * float3(0.5, 2./3., 0), 1);
  361. Out.TexCoord = TexCoord;// / 3 + 0.5;
  362. return Out;
  363. }
  364. // ----------------------------------------------------------------------------
  365. float4 PS_DebugDisplayDisplacement(float2 TexCoord : TEXCOORD0) : COLOR
  366. {
  367. float4 color = tex2D( SAMPLER(DisplacementTexture), TexCoord);
  368. return float4(color.xyz * 0.5 + 0.5, 1);
  369. }
  370. // ----------------------------------------------------------------------------
  371. technique DebugDisplayDisplacement
  372. {
  373. pass P0
  374. {
  375. VertexShader = compile VS_3_0 VS_DebugDisplayDisplacement();
  376. PixelShader = compile PS_3_0 PS_DebugDisplayDisplacement();
  377. ZEnable = false;
  378. ZWriteEnable = false;
  379. CullMode = None;
  380. AlphaTestEnable = false;
  381. AlphaBlendEnable = false;
  382. SrcBlend = One;
  383. DestBlend = One;
  384. //ColorWriteEnable = 0;
  385. }
  386. }