diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index c47699067c..1e7fdd291e 100644
--- a/binaries/data/config/default.cfg
+++ b/binaries/data/config/default.cfg
@@ -52,13 +52,12 @@ bpp = 0
; if false, actors won't be rendered but anything entity will be.
renderactors = true
-waternormals = true
+waterugly=false; Force usage of the fixed pipeline water. This is faster, but really, really ugly.
+waterfancyeffects = false
waterrealdepth = true
-waterfoam = false
-watercoastalwaves = false
waterrefraction = true
waterreflection = true
-watershadows = false
+shadowsonwater = false
shadows = true
shadowpcf = true
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0001.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0001.png
new file mode 100644
index 0000000000..c8ceff62ba
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0001.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:700c9f9bb902ad9ebd312b677d469ccd7428ba0b45e85b84a19224deb4994b8f
+size 133549
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0002.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0002.png
new file mode 100644
index 0000000000..0e8f950d7d
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0002.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:648aa9d384ce9940eacf8a15e2a3178426f359e2048f6faaf1dcaad93c8d8ee8
+size 133841
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0003.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0003.png
new file mode 100644
index 0000000000..3fda7dd03b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0003.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:95bc70b56e1515ba79e8c7fffada4059044a7d843df1821c0eae4383bad55d73
+size 133865
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0004.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0004.png
new file mode 100644
index 0000000000..cc671b770b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0004.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c7c953293bcfa771d4913ad92703296103c63b15d7b2d6f6d47bc067c7c1795
+size 133725
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0005.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0005.png
new file mode 100644
index 0000000000..5d48db45e0
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0005.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:71ff3baedcbee953ae0e84fb28d317fcd272b9dd507c53c9944b88e1b8eefdbd
+size 133281
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0006.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0006.png
new file mode 100644
index 0000000000..d9c452237e
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0006.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:457e27d5fa9cba41901add9b6ac1efcb670a9246e963a9c1b2a3efe7c63115dc
+size 132947
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0007.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0007.png
new file mode 100644
index 0000000000..60ca9cd7a3
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0007.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f3d91217613a2492d0ae2fceea766cc47bd5d462a504146f129e1183e528b795
+size 132690
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0008.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0008.png
new file mode 100644
index 0000000000..121d08a845
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0008.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dff254c330c1abb9c7b4dfa4b7d36e238889016beb9a812dd824cb3865f07b8f
+size 132079
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0009.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0009.png
new file mode 100644
index 0000000000..cb98334a51
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0009.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d87cecee12e037a18b5e060a7f2e7adbf3e4df113e7b27658800b724d8ff5d2
+size 131590
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0010.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0010.png
new file mode 100644
index 0000000000..d51947fd8d
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0010.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5af5ab5ec1322c8374e2eb1f3c240d928e3d02edb2bd26aae9b2a4fad22580d6
+size 131082
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0011.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0011.png
new file mode 100644
index 0000000000..45eeaa027e
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0011.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:25316348629268593e33d3389b6e4dd9ad8608322682cc8f0cb02b30abb30e15
+size 130532
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0012.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0012.png
new file mode 100644
index 0000000000..094f43e346
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0012.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c9a5235a15cfe15acba1f5b52d51a9bcbdad65a966138b360e8a8abf45681dd
+size 129997
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0013.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0013.png
new file mode 100644
index 0000000000..880eab0408
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0013.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a153c65f80cd59f1accf7bd9e379f29c87de9cca0e5d90af40bce74591616e22
+size 129613
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0014.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0014.png
new file mode 100644
index 0000000000..d7b4ae8b7e
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0014.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ec8b586cc3f632e1945533b39af36f78075118aa4b451fc49e56b296cf4a7cf0
+size 129151
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0015.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0015.png
new file mode 100644
index 0000000000..0c493bdc93
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0015.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0bdc29669f39cf9495bccb7be55d61e53eece4cbd20b82b76be52220537ed0c
+size 128666
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0016.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0016.png
new file mode 100644
index 0000000000..83b3258bd4
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0016.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8bf176acd29891d7e51f963eb5096260e640dfe3565c3f0d441841cbea0eb5f3
+size 128316
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0017.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0017.png
new file mode 100644
index 0000000000..5f819c0aa7
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0017.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:556c9bd9e22e7735d2309ca654a6eaa51431988adbd51d7072833614d824178a
+size 127820
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0018.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0018.png
new file mode 100644
index 0000000000..e16c87ded0
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0018.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fdc699f62accaa85af3db147c1c216aaaf98cb185d8f5bc4df010014417c8b00
+size 127542
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0019.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0019.png
new file mode 100644
index 0000000000..52573af42f
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0019.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d778dbab2d245996df80a7692b2f281b6e1208a29e4011917d381b64442eda9e
+size 127019
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0020.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0020.png
new file mode 100644
index 0000000000..8553c47b98
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0020.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1ff4f420d62cc57081f9e0470ba20650197d1b519f85f757fa5caa6d9df6d7fc
+size 126495
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0021.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0021.png
new file mode 100644
index 0000000000..45a899c8f9
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0021.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:31541bfd8d10ef3a31d28b3dbb84339b35453672f5cd9e67f9c84727a931b218
+size 126295
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0022.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0022.png
new file mode 100644
index 0000000000..5230b1c893
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0022.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6342914a1716652106002cb0fa882987a4fd8aa3bd14fdf34d785a6b5b75de2d
+size 125836
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0023.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0023.png
new file mode 100644
index 0000000000..ac4c055200
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0023.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f64c59ea4ec278b60b4a951d4b1633ade10b9f7f7d760e93b9d1fa0a1eea78a
+size 125477
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0024.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0024.png
new file mode 100644
index 0000000000..0dd4e4b6a5
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0024.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9374ac12a24939220c7143bddfa4755cec228f70e6c0580daa4ca058205fcd4e
+size 125126
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0025.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0025.png
new file mode 100644
index 0000000000..8f2bd26bd3
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0025.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:964ae7a9b0d1cbb269c8f6f723d8fe0f1899a888b144cb245ca7587230556e25
+size 124735
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0026.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0026.png
new file mode 100644
index 0000000000..8f251bd67e
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0026.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a22a2b830c5ece9c0147501518b617a7ecb0eb803b60225092f7499faa880fe7
+size 124469
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0027.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0027.png
new file mode 100644
index 0000000000..cd4a984cf1
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0027.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:64e20b2bbc7d200a07a83d54f7680fdef5379c2178c2cea725b426bb8d02c0e2
+size 124148
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0028.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0028.png
new file mode 100644
index 0000000000..454da4a0fd
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0028.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:28e4f10ca364565b86af61b903a0d5a19fd899a4f4a6e7c44696cd3d2863a2dd
+size 123847
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0029.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0029.png
new file mode 100644
index 0000000000..8748cc412c
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0029.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a7ae0673a85477a8198cf644ff3832c986f3846231d1e4a28daf1adcdbf3eef
+size 123577
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0030.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0030.png
new file mode 100644
index 0000000000..53810f77e7
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0030.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:566ece6fc8aa1a7fbce783eaec21e1feaaf909617535edabb8eef4ff044990bd
+size 123470
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0031.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0031.png
new file mode 100644
index 0000000000..0ba89b6d39
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0031.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f5bcd8c353e515236d9398a44ad9f8dc354789ff74df97d5fd4ba755ad30d037
+size 123393
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0032.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0032.png
new file mode 100644
index 0000000000..83fdcadc72
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0032.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2cc5e95b9102dc24f7212dddc91262e9e6ce9538da5e9aa06913842ccbf5d719
+size 123255
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0033.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0033.png
new file mode 100644
index 0000000000..d9d618f79d
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0033.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dc027509fff17940b056912e5095cb06609da6e2e41dabe94beccdf6cceefeb6
+size 123150
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0034.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0034.png
new file mode 100644
index 0000000000..6fb57eb76b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0034.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0df3ea840898ab6e1871c49af353d63bcd2d137f987229416ac48a73b7851b82
+size 123165
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0035.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0035.png
new file mode 100644
index 0000000000..e6caf0d091
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0035.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f609ed6b89253a2f26f02f8bc440b91674b4667d0d8629c479f0bf7a0cd430f9
+size 123374
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0036.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0036.png
new file mode 100644
index 0000000000..4661457011
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0036.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4499894b2219ed539052827128157e57d05a3be00817143019f6d7579db4d198
+size 123299
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0037.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0037.png
new file mode 100644
index 0000000000..4d21589cee
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0037.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ec31ea24489b54f2ba18739e63701b46ca3b533cbbbbe96593b3b2e77c030eb9
+size 123517
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0038.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0038.png
new file mode 100644
index 0000000000..a7df599408
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0038.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:78d1c9fcb8d50a69c8fdb02e31ba46f33594ba31cb6e6a63245934f05789b5d2
+size 123542
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0039.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0039.png
new file mode 100644
index 0000000000..664edde174
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0039.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:617365d3a13e92dbfca863ef1e3391535277ffa0347e2d40196317fa28b4b9f1
+size 123720
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0040.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0040.png
new file mode 100644
index 0000000000..342a52d819
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0040.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a44be3d1c907fc4ff1943ea1ab56b5c17c540ef98c71722d254dfae08a670b61
+size 123949
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0041.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0041.png
new file mode 100644
index 0000000000..39be4c5394
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0041.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:55beb430a413ad6a5de0a037bdaf67e8272fa7411cbd168c50f945289f575fd5
+size 124141
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0042.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0042.png
new file mode 100644
index 0000000000..64378c3802
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0042.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6b5efc9a2ddafc56aa18a6b6e42eb48ec765d2f80611fe602b7af22e0643da94
+size 124638
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0043.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0043.png
new file mode 100644
index 0000000000..e810d71e80
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0043.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6f34b0592c923549d90b17319e3bba893a32836a2d817cde480e464edcc4469f
+size 124857
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0044.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0044.png
new file mode 100644
index 0000000000..54b91a06bc
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0044.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0a75c533a3b234eb82f71e52513cb0aa81e6a68852190d599eebf4baaaf95a4e
+size 125207
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0045.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0045.png
new file mode 100644
index 0000000000..269282f738
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0045.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f28b57c4519d7aa69dbbdd61b679b6838643c70a659d545e0a52a8fed9daa766
+size 125558
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0046.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0046.png
new file mode 100644
index 0000000000..fb127826a4
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0046.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5aa4204095f1c810ae4f5d2b72b5c6e53f58b3faaf0630f694100c19ea6338d7
+size 125780
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0047.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0047.png
new file mode 100644
index 0000000000..a949555ed2
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0047.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1fb7f4a8018d52ee68123d845b61fe7f713c5f5cb40d817ea35aca428ddd85a1
+size 126299
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0048.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0048.png
new file mode 100644
index 0000000000..1c0279e1c5
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0048.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2df68b1601d052422efc6b65d3505f1305e567a758514ffc8ebf8c7c08ffeed2
+size 126545
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0049.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0049.png
new file mode 100644
index 0000000000..97dd1ebfc2
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0049.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:023653d3e5017bddbaf03e4f2114c4bd6140f5543a6d14d38436ea61a6764704
+size 127080
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0050.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0050.png
new file mode 100644
index 0000000000..1e8410d41b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0050.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:141698d3543e05b1b3877ecb27906b9ae0d8a59c9266fc13f15e66066b9d7ed3
+size 127596
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0051.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0051.png
new file mode 100644
index 0000000000..04eb771429
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0051.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:622fcab2239636da35c425ccd9ee0c03c15c497d935f853158a9becd61bc6332
+size 128035
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0052.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0052.png
new file mode 100644
index 0000000000..a5f3b6cc34
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0052.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:56aea8fac6ea600f35b8978db3cbc1e6fcc54a3fe595e17420dce83cc4244471
+size 128627
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0053.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0053.png
new file mode 100644
index 0000000000..7dd3938493
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0053.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c80278c38888b26c3e78046f2b26311663cdc77d9ef9af3bd68798921fbfdcd7
+size 129131
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0054.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0054.png
new file mode 100644
index 0000000000..ce532de36b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0054.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fd41eacb2cfea08e62da694489484bd599ebb87836c037f7af898d89d0fa946a
+size 129822
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0055.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0055.png
new file mode 100644
index 0000000000..ffe2ca1266
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0055.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7d500b9990051e0819167f7bb0ac8f316d1119ca9a97ed59c0cbf2c74dad4acb
+size 130572
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0056.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0056.png
new file mode 100644
index 0000000000..70f0352b6c
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0056.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6670d3084efd0262398db459fbf537609bcfe39ed34b249e34ad87fc0923d071
+size 131103
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0057.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0057.png
new file mode 100644
index 0000000000..7ff7b417af
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0057.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2ffb43052f90db2d43ad8fbb4051fbc9e6c1e82752ba7018062f173b8d36057f
+size 131728
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0058.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0058.png
new file mode 100644
index 0000000000..4277d73fc6
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0058.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7142860ee826dd5daabd8958a658a7d18bc61345c17a9d5e28f4ea84a19079df
+size 132325
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0059.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0059.png
new file mode 100644
index 0000000000..6ab7086b7b
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0059.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b3832abd0da0d98c98601012f8c8125a6d8acd169ed2b7385d36d8ac9e8523da
+size 133176
diff --git a/binaries/data/mods/public/art/textures/animated/water/ocean/normal0060.png b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0060.png
new file mode 100644
index 0000000000..6fea8222fd
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/animated/water/ocean/normal0060.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05f85ebc5ad515d208eb7c18a3bb9e067a468d563bb4407f25261721c8f94731
+size 133792
diff --git a/binaries/data/mods/public/art/textures/animated/water/textures.xml b/binaries/data/mods/public/art/textures/animated/water/textures.xml
index ac9a62697c..78f80be81e 100644
--- a/binaries/data/mods/public/art/textures/animated/water/textures.xml
+++ b/binaries/data/mods/public/art/textures/animated/water/textures.xml
@@ -1,4 +1,5 @@
+
diff --git a/binaries/data/mods/public/gui/options/options.js b/binaries/data/mods/public/gui/options/options.js
index fea8357ef7..6cc730e947 100644
--- a/binaries/data/mods/public/gui/options/options.js
+++ b/binaries/data/mods/public/gui/options/options.js
@@ -21,13 +21,12 @@ var options = {
[translate("Smooth LOS"), translate("Lift darkness and fog-of-war smoothly (Requires Prefer GLSL)"), {"renderer":"SmoothLOS", "config":"smoothlos"}, "boolean"],
[translate("Unit Silhouettes"), translate("Show outlines of units behind buildings"), {"renderer":"Silhouettes", "config":"silhouettes"}, "boolean"],
[translate("Shadow Filtering"), translate("Smooth shadows"), {"renderer":"ShadowPCF", "config":"shadowpcf"}, "boolean"],
- [translate("HQ Waviness"), translate("Use real normals for ocean-wave rendering, instead of applying them as a flat texture"), {"renderer":"WaterNormal", "config":"waternormals"}, "boolean"],
+ [translate("Fast & Ugly Water"), translate("Use the lowest settings possible to render water. This makes other settings irrelevant."), {"renderer":"WaterUgly", "config":"waterugly"}, "boolean"],
+ [translate("HQ Water Effects"), translate("Use higher-quality effects for water, rendering coastal waves, shore foam, and ships trails."), {"renderer":"WaterFancyEffects", "config":"waterfancyeffects"}, "boolean"],
[translate("Real Water Depth"), translate("Use actual water depth in rendering calculations"), {"renderer":"WaterRealDepth", "config":"waterrealdepth"}, "boolean"],
[translate("Water Reflections"), translate("Allow water to reflect a mirror image"), {"renderer":"WaterReflection", "config":"waterreflection"}, "boolean"],
[translate("Water Refraction"), translate("Use a real water refraction map and not transparency"), {"renderer":"WaterRefraction", "config":"waterrefraction"}, "boolean"],
- [translate("Shore Foam"), translate("Show foam on water near shore depending on water waviness"), {"renderer":"WaterFoam", "config":"waterfoam"}, "boolean"],
- [translate("Shore Waves"), translate("Show breaking waves on water near shore (Requires HQ Waviness)"), {"renderer":"WaterCoastalWaves", "config":"watercoastalwaves"}, "boolean"],
- [translate("Water Shadows"), translate("Cast shadows on water"), {"renderer":"WaterShadow", "config":"watershadows"}, "boolean"],
+ [translate("Shadows on Water"), translate("Cast shadows on water"), {"renderer":"WaterShadows", "config":"watershadows"}, "boolean"],
[translate("VSync"), translate("Run vertical sync to fix screen tearing. REQUIRES GAME RESTART"), {"config":"vsync"}, "boolean"],
],
"soundSetting":
diff --git a/binaries/data/mods/public/hwdetect/hwdetect.js b/binaries/data/mods/public/hwdetect/hwdetect.js
index 4328ca1cda..9ac22bf6bb 100644
--- a/binaries/data/mods/public/hwdetect/hwdetect.js
+++ b/binaries/data/mods/public/hwdetect/hwdetect.js
@@ -180,7 +180,6 @@ function RunDetection(settings)
var disable_shadowpcf = undefined;
var disable_allwater = undefined;
var disable_fancywater = undefined;
- var disable_fbowater = undefined;
var override_renderpath = undefined;
// TODO: add some mechanism for setting config values
@@ -257,7 +256,6 @@ function RunDetection(settings)
{
disable_allwater = false;
disable_fancywater = true;
- //disable_fbowater = true;
disable_shadowpcf = true;
}
@@ -295,7 +293,6 @@ function RunDetection(settings)
"disable_shadowpcf": disable_shadowpcf,
"disable_allwater": disable_allwater,
"disable_fancywater": disable_fancywater,
- "disable_fbowater": disable_fbowater,
"override_renderpath": override_renderpath,
};
}
@@ -334,9 +331,6 @@ global.RunHardwareDetection = function(settings)
if (output.disable_fancywater !== undefined)
Engine.SetDisableFancyWater(output.disable_fancywater);
-
- if (output.disable_fbowater !== undefined)
- Engine.SetDisableFancyWater(output.disable_fbowater);
if (output.override_renderpath !== undefined)
Engine.SetRenderPath(output.override_renderpath);
diff --git a/binaries/data/mods/public/hwdetect/test.js b/binaries/data/mods/public/hwdetect/test.js
index a3967e03b8..c55e3700bf 100644
--- a/binaries/data/mods/public/hwdetect/test.js
+++ b/binaries/data/mods/public/hwdetect/test.js
@@ -29,7 +29,7 @@ for each (var settings in hwdetectTestData)
var os = (settings.os_linux ? "linux" : settings.os_macosx ? "macosx" : settings.os_win ? "win" : "???");
var disabled = [];
- for each (var d in ["disable_audio", "disable_s3tc", "disable_shadows", "disable_shadowpcf", "disable_allwater", "disable_fbowater", "disable_fancywater", "override_renderpath"])
+ for each (var d in ["disable_audio", "disable_s3tc", "disable_shadows", "disable_shadowpcf", "disable_allwater", "disable_fancywater", "override_renderpath"])
if (output[d] !== undefined)
disabled.push(d+"="+output[d])
diff --git a/binaries/data/mods/public/shaders/glsl/model_common.fs b/binaries/data/mods/public/shaders/glsl/model_common.fs
index 0e2273dca4..8ee4011e3f 100644
--- a/binaries/data/mods/public/shaders/glsl/model_common.fs
+++ b/binaries/data/mods/public/shaders/glsl/model_common.fs
@@ -35,6 +35,7 @@ uniform vec3 fogColor;
uniform vec2 fogParams;
varying vec4 v_lighting;
+varying vec4 v_lighting2;
varying vec2 v_tex;
varying vec2 v_los;
@@ -249,9 +250,12 @@ void main()
specular.rgb = sunColor * specCol * pow(max(0.0, dot(normalize(normal), v_half)), specPow);
#endif
- vec3 color = (texdiffuse * sundiffuse + specular.rgb) * get_shadow();
- vec3 ambColor = texdiffuse * ambient;
-
+ float shadow = get_shadow();
+
+ vec3 color = (texdiffuse * sundiffuse + specular.rgb) * shadow;
+ vec3 ambColor = texdiffuse * (ambient + v_lighting2.rgb*(shadow+0.8)*0.5);
+ //ambColor = texdiffuse * ambient;
+
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
vec3 ao = texture2D(aoTex, v_tex2).rrr;
ao = mix(vec3(1.0), ao * 2.0, effectSettings.w);
@@ -273,6 +277,8 @@ void main()
#endif
color *= shadingColor;
-
+
+ //color = v_lighting2.rgb;
+
gl_FragColor.rgb = color;
}
diff --git a/binaries/data/mods/public/shaders/glsl/model_common.vs b/binaries/data/mods/public/shaders/glsl/model_common.vs
index f18d58a671..29f519a3b9 100644
--- a/binaries/data/mods/public/shaders/glsl/model_common.vs
+++ b/binaries/data/mods/public/shaders/glsl/model_common.vs
@@ -23,6 +23,7 @@ uniform mat4 instancingTransform;
#endif
varying vec4 v_lighting;
+varying vec4 v_lighting2;
varying vec2 v_tex;
varying vec2 v_los;
@@ -74,6 +75,8 @@ vec4 fakeCos(vec4 x)
void main()
{
+ // Compute position, normal and tangent vertices.
+ // GPU skinning does the animation live on the GPU.
#if USE_GPU_SKINNING
vec3 p = vec3(0.0);
vec3 n = vec3(0.0);
@@ -105,7 +108,7 @@ void main()
#endif
#endif
-
+ // Calculate swaying of trees dynamically
#if USE_WIND
vec2 wind = windData.xy;
@@ -139,7 +142,6 @@ void main()
position.xz += diff + diff2 * wind;
#endif
-
gl_Position = transform * position;
#if USE_SPECULAR || USE_NORMAL_MAP || USE_SPECULAR_MAP || USE_PARALLAX_MAP
@@ -165,7 +167,12 @@ void main()
#endif
#endif
- v_lighting.xyz = max(0.0, dot(normal, -sunDir)) * sunColor;
+ float firstDot = dot(normal, -sunDir);
+ v_lighting2.xyz = max(0.0, (dot(normal, vec3(-sunDir.r,sunDir.g,-sunDir.b)) + 1.0) - abs(firstDot)*0.8 - max(0.0,firstDot)*1.9) * 0.4 * sunColor;
+ v_lighting2 -= a_vertex.y*0.1;
+ v_lighting2 = clamp(vec4(0.3), vec4(0.0), v_lighting2);
+
+ v_lighting.xyz = max(0.0, firstDot) * sunColor;
v_tex = a_uv0;
@@ -177,7 +184,7 @@ void main()
v_shadow = shadowTransform * position;
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
v_shadow.xy *= shadowScale.xy;
- #endif
+ #endif
#endif
v_los = position.xz * losTransform.x + losTransform.y;
diff --git a/binaries/data/mods/public/shaders/glsl/water_effects.fs b/binaries/data/mods/public/shaders/glsl/water_effects.fs
new file mode 100644
index 0000000000..bc4bb3a366
--- /dev/null
+++ b/binaries/data/mods/public/shaders/glsl/water_effects.fs
@@ -0,0 +1,52 @@
+#version 110
+
+// This is a lightened version of water_high.fs that generates only the "n" vector (ie the normal) and the foam coverage.
+// It's thus uncommented.
+
+uniform float waviness;
+uniform vec2 screenSize;
+uniform float time;
+varying vec3 worldPos;
+
+uniform float mapSize;
+
+uniform sampler2D normalMap;
+uniform sampler2D normalMap2;
+
+/*#if USE_FOAM || USE_WAVES
+ uniform sampler2D Foam;
+ uniform sampler2D waveTex;
+#endif*/
+
+void main()
+{
+ float wavyFactor = waviness * 0.125;
+
+ vec3 ww1 = texture2D(normalMap, (gl_TexCoord[0].st) * (0.7 - waviness/20.0)).xzy;
+ vec3 ww2 = texture2D(normalMap2, (gl_TexCoord[0].st) * (0.7 - waviness/20.0)).xzy;
+
+ //vec3 smallWW = texture2D(normalMap, (gl_TexCoord[0].st - gl_TexCoord[0].wz*6.0) * 1.2).xzy;
+ //vec3 smallWW2 = texture2D(normalMap2, (gl_TexCoord[0].st - gl_TexCoord[0].wz*6.0) * 1.2).xzy;
+
+ ww1 = mix(ww1, ww2, mod(time * 60.0, 8.0) / 8.0);
+ //smallWW = mix(smallWW, smallWW2, mod(time * 60.0, 8.0) / 8.0) - vec3(0.5);
+ //ww += vec3(smallWW.x,0.0,smallWW.z)*0.5;
+
+ /*#if USE_WAVES
+ vec3 waves = texture2D(waveTex, gl_FragCoord.xy/screenSize).rbg - vec3(0.5,0.5,0.5);
+ float waveFoam = 0.0;//texture2D(waveTex, gl_FragCoord.xy/screenSize).a;
+ n = normalize(mix(waves, ww - vec3(0.5, 0.5, 0.5) , clamp(distToShore*3.0,0.4,1.0)));
+ #else*/
+ vec3 n = normalize(ww1 - vec3(0.5, 0.5, 0.5));
+ n = mix(vec3(0.0,1.0,0.0),n,waviness/10.0);
+
+ float foamFact1 = texture2D(normalMap, (gl_TexCoord[0].st) * 0.3).a;
+ float foamFact2 = texture2D(normalMap2, (gl_TexCoord[0].st) * 0.3).a;
+ float foamFact = mix(foamFact1, foamFact2, mod(time * 60.0, 8.0) / 8.0);
+
+ float foamUniversal1 = texture2D(normalMap, (gl_TexCoord[0].st) * 0.05).a;
+ float foamUniversal2 = texture2D(normalMap2, (gl_TexCoord[0].st) * 0.05).a;
+ float foamUniversal = mix(foamUniversal1, foamUniversal2, mod(time * 60.0, 8.0) / 8.0);
+
+ gl_FragColor.rgba = vec4(n,foamFact*foamUniversal*30.0);
+}
diff --git a/binaries/data/mods/public/shaders/glsl/water_effects.vs b/binaries/data/mods/public/shaders/glsl/water_effects.vs
new file mode 100644
index 0000000000..39a442a113
--- /dev/null
+++ b/binaries/data/mods/public/shaders/glsl/water_effects.vs
@@ -0,0 +1,22 @@
+#version 110
+
+// This is a lightened version of water_high.vs
+uniform float repeatScale;
+uniform vec2 translation;
+
+uniform float time;
+uniform float mapSize;
+
+varying vec3 worldPos;
+
+attribute vec3 a_vertex;
+
+void main()
+{
+ worldPos = a_vertex;
+
+ gl_TexCoord[0] = vec4(a_vertex.xz*repeatScale,translation);
+ gl_TexCoord[3].zw = vec2(a_vertex.xz)/mapSize;
+
+ gl_Position = gl_ModelViewProjectionMatrix * vec4(a_vertex, 1.0);
+}
diff --git a/binaries/data/mods/public/shaders/glsl/waves.xml b/binaries/data/mods/public/shaders/glsl/water_effects.xml
similarity index 51%
rename from binaries/data/mods/public/shaders/glsl/waves.xml
rename to binaries/data/mods/public/shaders/glsl/water_effects.xml
index 8f063cf98b..b7105bb527 100644
--- a/binaries/data/mods/public/shaders/glsl/waves.xml
+++ b/binaries/data/mods/public/shaders/glsl/water_effects.xml
@@ -1,13 +1,12 @@
-
+
-
+
-
-
+
diff --git a/binaries/data/mods/public/shaders/glsl/water_high.fs b/binaries/data/mods/public/shaders/glsl/water_high.fs
index 830f17d998..d4bdedc895 100644
--- a/binaries/data/mods/public/shaders/glsl/water_high.fs
+++ b/binaries/data/mods/public/shaders/glsl/water_high.fs
@@ -23,11 +23,17 @@ varying vec3 worldPos;
varying float waterDepth;
varying vec4 waterInfo;
+uniform float mapSize;
+
uniform samplerCube skyCube;
uniform sampler2D normalMap;
uniform sampler2D normalMap2;
+#if USE_FANCY_EFFECTS
+ uniform sampler2D waterEffectsTex;
+#endif
+
#if USE_REFLECTION
uniform sampler2D reflectionMap;
#endif
@@ -37,11 +43,13 @@ uniform sampler2D normalMap2;
#if USE_REAL_DEPTH
uniform sampler2D depthTex;
#endif
-#if USE_FOAM || USE_WAVES
+
+/*#if USE_FOAM || USE_WAVES
uniform sampler2D Foam;
uniform sampler2D waveTex;
-#endif
-#if USE_SHADOWS && USE_SHADOW
+#endif*/
+
+#if USE_SHADOWS_ON_WATER && USE_SHADOW
varying vec4 v_shadow;
#if USE_SHADOW_SAMPLER
uniform sampler2DShadow shadowTex;
@@ -53,7 +61,7 @@ uniform sampler2D normalMap2;
#endif
float get_shadow(vec4 coords)
{
- #if USE_SHADOWS && !DISABLE_RECEIVE_SHADOWS
+ #if USE_SHADOWS_ON_WATER && !DISABLE_RECEIVE_SHADOWS
#if USE_SHADOW_SAMPLER
#if USE_SHADOW_PCF
vec2 offset = fract(coords.xy - 0.5);
@@ -78,6 +86,31 @@ uniform sampler2D normalMap2;
}
#endif
+// TODO: convert this to something not only for AABBs
+struct Ray {
+ vec3 Origin;
+ vec3 Direction;
+};
+
+float IntersectBox (in Ray ray, in vec3 minimum, in vec3 maximum)
+{
+ vec3 OMIN = ( minimum - ray.Origin ) / ray.Direction;
+ vec3 OMAX = ( maximum - ray.Origin ) / ray.Direction;
+ vec3 MAX = max ( OMAX, OMIN );
+ return min ( MAX.x, min ( MAX.y, MAX.z ) );
+}
+// This is sorta useless since it's hardcoded for 45°. Change it to sun orientation too.
+mat3 rotationMatrix()
+{
+ vec3 axis = vec3(0.0,1.0,0.0);
+ float s = sin(1.12);
+ float c = cos(1.12);
+
+ return mat3(c, 0.0, s,
+ 0.0, 1.0, 0.0,
+ -s, 0.0, c);
+}
+
vec3 get_fog(vec3 color)
{
float density = fogParams.x;
@@ -96,50 +129,63 @@ vec3 get_fog(vec3 color)
void main()
{
- #if USE_FOAM || USE_WAVES
- vec4 heightmapval = waterInfo;
- vec2 beachOrientation = heightmapval.rg;
- float distToShore = heightmapval.b;
- #endif
-
- vec3 n, l, h, v; // Normal, light vector, half-vector and view vector (vector to eye)
- float ndotl, ndoth, ndotv;
+ //float fwaviness = 1;
+
float fresnel;
float t; // Temporary variable
vec2 reflCoords, refrCoords;
vec3 reflColor, refrColor, specular;
float losMod;
+ // Correct the waviness (range [0,10]) to something slightly more convenient (range [0,1.2] so you can treat it like [0.1] with overdraft).
float wavyFactor = waviness * 0.125;
- l = -sunDir;
- v = normalize(cameraPos - worldPos);
- h = normalize(l + v);
-
- // always done cause this is also used, even when not using normals, by the refraction.
- vec3 ww = texture2D(normalMap, (gl_TexCoord[0].st) * mix(2.0,0.8,waviness/10.0) +gl_TexCoord[0].zw).xzy;
-
- #if USE_NORMALS
- vec3 ww2 = texture2D(normalMap2, (gl_TexCoord[0].st) * mix(2.0,0.8,waviness/10.0) +gl_TexCoord[0].zw).xzy;
- ww = mix(ww, ww2, mod(time * 60.0, 8.0) / 8.0);
+ vec3 l = -sunDir;
+ vec3 v = normalize(cameraPos - worldPos);
+ vec3 h = normalize(l + v);
- #if USE_WAVES
- vec3 waves = texture2D(waveTex, gl_FragCoord.xy/screenSize).rbg - vec3(0.5,0.5,0.5);
- float waveFoam = 0.0;//texture2D(waveTex, gl_FragCoord.xy/screenSize).a;
- n = normalize(mix(waves, ww - vec3(0.5, 0.5, 0.5) , clamp(distToShore*3.0,0.4,1.0)));
- #else
- n = normalize(ww - vec3(0.5, 0.5, 0.5));
- #endif
- ndoth = dot( mix(vec3(0.0,1.0,0.0),n,clamp(wavyFactor * v.y * 8.0,0.05,1.0)) ,h);
- n = mix(vec3(0.0,1.0,0.0),n,wavyFactor);
- #else
- ndoth = dot(vec3(0.0,1.0,0.0), h);
- n = vec3(0.0,1.0,0.0);
- #endif
+ // Calculate water normals.
- ndotl = (dot(n, l) + 1.0)/2.0;
- ndotv = clamp(dot(n, v),0.0,1.0);
+#if USE_FANCY_EFFECTS
+ vec4 fancyeffects = texture2D(waterEffectsTex, gl_FragCoord.xy/screenSize);
+ vec3 n = fancyeffects.rgb;
+#else
+ // This method uses 60 animated water frames. We're blending between each two frames
+ // TODO: could probably have fewer frames thanks to this blending.
+ // Scale the normal textures by waviness so that big waviness means bigger waves.
+ vec3 ww1 = texture2D(normalMap, (gl_TexCoord[0].st) * (0.7 - waviness/20.0)).xzy;
+ vec3 ww2 = texture2D(normalMap2, (gl_TexCoord[0].st) * (0.7 - waviness/20.0)).xzy;
+
+ //vec3 smallWW = texture2D(normalMap, (gl_TexCoord[0].st - gl_TexCoord[0].wz*6.0) * 1.2).xzy;
+ //vec3 smallWW2 = texture2D(normalMap2, (gl_TexCoord[0].st - gl_TexCoord[0].wz*6.0) * 1.2).xzy;
+ ww1 = mix(ww1, ww2, mod(time * 60.0, 8.0) / 8.0);
+ //smallWW = mix(smallWW, smallWW2, mod(time * 60.0, 8.0) / 8.0) - vec3(0.5);
+ //ww += vec3(smallWW.x,0.0,smallWW.z)*0.5;
+
+ /*#if USE_WAVES
+ vec3 waves = texture2D(waveTex, gl_FragCoord.xy/screenSize).rbg - vec3(0.5,0.5,0.5);
+ float waveFoam = 0.0;//texture2D(waveTex, gl_FragCoord.xy/screenSize).a;
+ n = normalize(mix(waves, ww - vec3(0.5, 0.5, 0.5) , clamp(distToShore*3.0,0.4,1.0)));
+ #else*/
+ // Fix our normals.
+ vec3 n = normalize(ww1 - vec3(0.5, 0.5, 0.5));
+
+ // Flatten them based on waviness.
+ n = mix(vec3(0.0,1.0,0.0),n,waviness/10.0);
+
+#endif
+
+ // simulates how parallel the "point->sun", "view->point" vectors are.
+ // To always have a bit of that, we don't use the "n" we calculated above.
+ float ndoth = dot( mix(vec3(0.0,1.0,0.0),n,0.1 + min(0.8,waviness*waviness/70.0)) , h);
+ // how perpendicular to the normal our view is. Used for fresnel.
+ float ndotv = clamp(dot(n, v),0.0,1.0);
+
+ // diffuse lighting-like. used for shadows?
+ float ndotl = (dot(n, l) + 1.0)/2.0;
+
+ float depth;
#if USE_REAL_DEPTH
// Don't change these two. They should match the values in the config (TODO: dec uniforms).
float zNear = 2.0;
@@ -167,17 +213,25 @@ void main()
if (z_b < undisto_z_b)
z_b = undisto_z_b;
float z_n = 2.0 * z_b - 1.0;
- float waterDepth2 = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer);
- float distoFactor = clamp(waterDepth2/3.0,0.0,7.0);
+ depth = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer);
#else
- float perceivedDepth = waterDepth / (v.y*v.y);
- float distoFactor = clamp(perceivedDepth/4.0,0.0,7.0);
+ depth = waterDepth / (min(0.5,v.y)*1.5*min(0.5,v.y)*2.0);
#endif
- fresnel = pow(1.05 - ndotv, 1.3333); // approximation. I'm using 1.05 and not 1.0 because it causes artifacts, see #1714
+ // Fresnel for "how much reflection vs how much refraction".
+ // Since we're not trying to simulate a realistic ocean 100%, aim for something that gives a little too much reflection
+ // because we're not used to seeing the see from above.
+ fresnel = clamp(pow(1.05 - ndotv, 1.3),0.0,0.8); // approximation. I'm using 1.05 and not 1.0 because it causes artifacts, see #1714
+ // multiply by v.y so that in the distance refraction wins.
+ // TODO: this is a hack because reflections don't work in the distance.
+ fresnel *= min(1.0,log(1.0 + v.y*5.0));
+ fresnel = 0.2 + fresnel * 0.8;
- #if USE_FOAM
+ //gl_FragColor = vec4(fresnel,fresnel,fresnel,1.0);
+ //return;
+
+ /*#if USE_FOAM
// texture is rotated 90°, moves slowly.
vec2 foam1RC = vec2(-gl_TexCoord[0].t,gl_TexCoord[0].s)*1.3 - 0.012*n.xz + vec2(time*0.004,time*0.003);
// texture is not rotated, moves twice faster in the opposite direction, translated.
@@ -196,120 +250,115 @@ void main()
finalFoam += min( max(0.0,-waves.b) * texture2D(Foam, foam1RC).r, 1.0)*3.0 * max(0.0,wavyFactor-0.1);
#endif
finalFoam *= sunColor;
- #endif
+ #endif*/
- #if USE_SHADOWS && USE_SHADOW
+ #if USE_SHADOWS_ON_WATER && USE_SHADOW
float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw));
#endif
+ // for refraction, we want to adjust the value by v.y slightly otherwise it gets too different between "from above" and "from the sides".
+ // And it looks weird (again, we are not used to seeing water from above).
+ float fixedVy = clamp(v.y,0.1,1.0);
+
+ float distoFactor = clamp(depth/2.0,0.0,7.0);
+
+ float murky = mix(200.0,0.1,pow(murkiness,0.25));
+
#if USE_REFRACTION
- #if USE_REAL_DEPTH
- refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords
- vec3 refColor = texture2D(refractionMap, refrCoords).rgb;
- float luminance = (1.0 - clamp((waterDepth2/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0));
- float colorExtinction = clamp(waterDepth2*murkiness/5.0,0.0,1.0);
- #if USE_SHADOWS && USE_SHADOW
- refrColor = (0.5 + 0.5*ndotl) * mix(color * (0.5 + shadow/2.0),mix(refColor,refColor*tint,colorExtinction),luminance*luminance);
- #else
- refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance);
- #endif
+ refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor*10.0) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords
+ vec3 refColor = texture2D(refractionMap, refrCoords).rgb;
+
+ // TODO: make murkiness (both types rematter on that.
+ // linearly extinct the water. This is how quickly we see nothing but the pure water color
+ float extFact = max(0.0,1.0 - (depth*fixedVy/murky));
+ // This is how tinted the water is, ie how quickly the refracted floor takes the tint of the water
+ float ColextFact = max(0.0,1.0 - (depth*fixedVy/murky));
+ vec3 colll = mix(refColor*tint,refColor,ColextFact);
+
+ #if USE_SHADOWS_ON_WATER && USE_SHADOW
+ // TODO:
+ refrColor = mix(color, colll, extFact);
#else
- refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords
- // cleverly get the perceived depth based on camera tilting (if horizontal, it's likely we will have more water to look at).
- vec3 refColor = texture2D(refractionMap, refrCoords).rgb;
- float luminance = (1.0 - clamp((perceivedDepth/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0));
- float colorExtinction = clamp(perceivedDepth*murkiness/5.0,0.0,1.0);
- #if USE_SHADOWS && USE_SHADOW
- refrColor = (0.5 + 0.5*ndotl) * mix(color * (0.5 + shadow/2.0),mix(refColor,refColor*tint,colorExtinction),luminance*luminance);
- #else
- refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance);
- #endif
+ refrColor = mix(color, colll, extFact);
#endif
#else
- float alphaCoeff = 0.0;
- #if USE_REAL_DEPTH
- float luminance = clamp((waterDepth2/mix(150.0,2.0, pow(murkiness,0.2) )), 0.0, 1.0);
- alphaCoeff = mix(mix(0.0,3.0 - (tint.r + tint.g + tint.b),clamp(waterDepth2*murkiness/5.0,0.0,1.0)),1.0,luminance*luminance);
- #else
- float luminance = clamp(((waterDepth / v.y)/mix(150.0,2.0, pow(murkiness,0.2) )), 0.0, 1.0);
- alphaCoeff = mix(mix(0.0,3.0 - (tint.r + tint.g + tint.b),clamp(perceivedDepth*murkiness/5.0,0.0,1.0)),1.0,luminance*luminance);
- #endif
+ // linearly extinct the water. This is how quickly we see nothing but the pure water color
+ float extFact = max(0.0,1.0 - (depth*fixedVy/20.0));
+ // using both those factors, get our transparency.
+ // This will be our base transparency on top.
+ float base = 0.4 + depth*fixedVy/15.0; // TODO: murkiness.
+ float alphaCoeff = mix(1.0, base, extFact);
refrColor = color;
#endif
-
- #if !USE_NORMALS
- // we're not using normals. Simulate by applying a B&W effect.
- refrColor *= (ww*2.0).x;
- #endif
-
+
#if USE_REFLECTION
- reflCoords = clamp( (0.5*gl_TexCoord[1].xy + distoFactor*1.5*n.xz) / gl_TexCoord[1].w + 0.5,0.0,1.0); // Unbias texture coords
+ reflCoords = clamp( (0.5*gl_TexCoord[1].xy - waviness * 2.0 * n.xz) / gl_TexCoord[1].w + 0.5,0.0,1.0); // Unbias texture coords
reflColor = mix(texture2D(reflectionMap, reflCoords).rgb, sunColor * reflectionTint, reflectionTintStrength);
+ // TODO: At very low angles the reflection stuff doesn't really work any more:
+ // IRL you would get a blur of the sky, but we don't have that precision (would require mad oversampling)
+ // So tend towards a predefined color (per-map) which looks like what the skybox would look like if you really blurred it.
+ // The TODO here would be to precompute a band (1x32?) that represents the average color around the map.
+ // TODO: another issue is that at high distances (half map) the texture blurs into flatness. Using better mipmaps won't really solve it
+ // So we'll need to stop showing reflections and default to sky color there too.
+ // Unless maybe waviness is so low that you would see like in a mirror anyways.
+ //float disttt = distance(worldPos,cameraPos);
+ //reflColor = mix(vec3(0.5,0.5,0.55), reflColor, clamp(1.0-disttt/600.0*disttt/600.0,0.0,1.0));//clamp(-0.05 + v.y*20.0,0.0,1.0));
#else
- vec3 eye = reflect(v, mix(vec3(0.0,1.0,0.0),n,0.2));
- vec3 tex = textureCube(skyCube, eye).rgb;
+ vec3 eye = reflect(v,n);
+ eye.y = min(-0.1,eye.y);
+ // let's calculate where we intersect with the skycube.
+ Ray myRay = Ray(vec3(worldPos.x/4.0,worldPos.y,worldPos.z/4.0),eye);
+ vec3 start = vec3(-1500.0 + mapSize/2.0,-100.0,-1500.0 + mapSize/2.0);
+ vec3 end = vec3(1500.0 + mapSize/2.0,500.0,1500.0 + mapSize/2.0);
+ float tmin = IntersectBox(myRay,start,end);
+ vec3 newpos = vec3(-worldPos.x/4.0,worldPos.y,-worldPos.z/4.0) + eye * tmin - vec3(-mapSize/2.0,worldPos.y,-mapSize/2.0);
+ //newpos = normalize(newpos);
+ newpos.y *= 6.0;
+ newpos *= rotationMatrix();
+ vec3 tex = textureCube(skyCube, newpos).rgb;
+ //float disttt = distance(worldPos,cameraPos);
+ //tex = mix(tex,vec3(0.7,0.7,0.9),clamp(disttt/300.0*disttt/300.0*disttt/300.0,0.0,0.9));
+ //gl_FragColor = vec4(clamp(disttt/300.0*disttt/300.0,0.0,1.0),clamp(disttt/300.0*disttt/300.0,0.0,1.0),clamp(disttt/300.0*disttt/300.0,0.0,1.0),1.0);
+ //return;
reflColor = mix(tex, sunColor * reflectionTint, reflectionTintStrength);
#endif
- #if USE_NORMALS
- specular = pow(ndoth, mix(100.0,450.0, v.y*2.0)) * sunColor * 1.5;
- #else
- specular = pow(ndoth, mix(100.0,450.0, v.y*2.0)) * sunColor * 1.5 * ww.r;
- #endif
-
+ // Specular.
+ specular = pow(ndoth, mix(100.0,450.0, v.y*2.0))*sunColor * 1.5;// * sunColor * 1.5 * ww.r;
+
losMod = texture2D(losMap, gl_TexCoord[3].st).a;
losMod = losMod < 0.03 ? 0.0 : losMod;
vec3 colour;
- #if USE_SHADOWS && USE_SHADOW
+ #if USE_SHADOWS_ON_WATER && USE_SHADOW
float fresShadow = mix(fresnel, fresnel*shadow, 0.05 + murkiness*0.2);
- #if USE_FOAM
+ /* #if USE_FOAM
colour = mix(refrColor, reflColor, fresShadow) + max(ndotl,0.4)*(finalFoam)*(shadow/2.0 + 0.5);
- #else
- colour = mix(refrColor, reflColor, fresShadow);
- #endif
+ #else*/
+ colour = mix(refrColor, reflColor, fresShadow);
#else
- #if USE_FOAM
+ /*#if USE_FOAM
colour = mix(refrColor, reflColor, fresnel) + max(ndotl,0.4)*(finalFoam);
- #else
- colour = mix(refrColor, reflColor, fresnel);
- #endif
+ #else*/
+ colour = mix(refrColor, reflColor, fresnel);
#endif
- #if USE_REFRACTION
- #if USE_REAL_DEPTH
- colour = mix(texture2D(refractionMap, (0.5*gl_TexCoord[2].xy) / gl_TexCoord[2].w + 0.5).rgb ,colour, clamp(waterDepth2,0.0,1.0));
- #else
- colour = mix(texture2D(refractionMap, (0.5*gl_TexCoord[2].xy) / gl_TexCoord[2].w + 0.5).rgb ,colour, clamp(perceivedDepth,0.0,1.0));
- #endif
- #endif
-
- #if USE_SHADOWS && USE_SHADOW
+ #if USE_SHADOWS_ON_WATER && USE_SHADOW
colour += shadow*specular;
#else
colour += specular;
#endif
-
- gl_FragColor.rgb = get_fog(colour) * losMod;
-
- #if USE_REAL_DEPTH
- float alpha = clamp(waterDepth2*(5.0*murkiness),0.0,1.0);
- #if !USE_REFRACTION
- alpha *= alphaCoeff;
- #endif
- #if USE_FOAM
- alpha += finalFoam.r * losMod;
- #endif
- gl_FragColor.a = alpha;
+
+ // TODO: work the foam in somewhere else.
+ #if USE_FANCY_EFFECTS
+ gl_FragColor.rgb = get_fog(colour) * losMod + fancyeffects.a * losMod;
#else
- // Make alpha vary based on both depth (so it blends with the shore) and view angle (make it
- // become opaque faster at lower view angles so we can't look "underneath" the water plane)
- t = 30.0 * max(0.0, 0.9 - v.y);
- float alpha = clamp(0.15 * waterDepth * (1.2 + t + fresnel),0.0,1.0);
- #if !USE_REFRACTION
- gl_FragColor.a = alpha * alphaCoeff;
- #else
- gl_FragColor.a = alpha;
- #endif
+ gl_FragColor.rgb = get_fog(colour) * losMod;
+ #endif
+
+ #if !USE_REFRACTION
+ gl_FragColor.a = clamp(depth*2.0,0.0,1.0) * alphaCoeff;
+ #else
+ gl_FragColor.a = clamp(depth*2.0,0.0,1.0);
#endif
}
diff --git a/binaries/data/mods/public/shaders/glsl/water_high.vs b/binaries/data/mods/public/shaders/glsl/water_high.vs
index b884934ddb..0d0fa1c28b 100644
--- a/binaries/data/mods/public/shaders/glsl/water_high.vs
+++ b/binaries/data/mods/public/shaders/glsl/water_high.vs
@@ -18,7 +18,8 @@ uniform float mapSize;
varying vec3 worldPos;
varying float waterDepth;
varying vec4 waterInfo;
-#if USE_SHADOW && USE_SHADOWS
+
+#if USE_SHADOW && USE_SHADOWS_ON_WATER
varying vec4 v_shadow;
#endif
attribute vec3 a_vertex;
@@ -37,7 +38,7 @@ void main()
gl_TexCoord[3].zw = vec2(a_vertex.xz)/mapSize;
- #if USE_SHADOW && USE_SHADOWS
+ #if USE_SHADOW && USE_SHADOWS_ON_WATER
v_shadow = shadowTransform * vec4(a_vertex, 1.0);
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
v_shadow.xy *= shadowScale.xy;
diff --git a/binaries/data/mods/public/shaders/glsl/waves.fs b/binaries/data/mods/public/shaders/glsl/waves.fs
deleted file mode 100644
index b2e5a1a833..0000000000
--- a/binaries/data/mods/public/shaders/glsl/waves.fs
+++ /dev/null
@@ -1,24 +0,0 @@
-#version 110
-
-uniform sampler2D waveTex;
-uniform sampler2D infoTex;
-
-uniform float time;
-uniform float waviness;
-
-void main()
-{
- vec3 color = texture2D(waveTex, gl_TexCoord[0].st * vec2(2.0,4.0) - vec2(0.0,0.5 + time/5.0)).rgb;
- float split = abs(gl_TexCoord[0].x - 0.5);
- split = 0.48 - split;
- split *= 3.0;
- split = min(1.0,split);
-
- float opac = split*min(1.0, gl_TexCoord[0].y);
- opac *= 1.0 - max(0.0,gl_TexCoord[0].y-0.9)*10.0;
- color = mix(vec3(0.5,0.5,1.0),color, opac);
-
- gl_FragColor.rgb = mix(vec3(0.5,0.5,1.0), color, clamp(texture2D(infoTex,gl_TexCoord[0].zw).r,0.4,1.0));
-
- gl_FragColor.a = 1.0;
-}
diff --git a/binaries/data/mods/public/shaders/glsl/waves.vs b/binaries/data/mods/public/shaders/glsl/waves.vs
deleted file mode 100644
index ff15e236a5..0000000000
--- a/binaries/data/mods/public/shaders/glsl/waves.vs
+++ /dev/null
@@ -1,13 +0,0 @@
-#version 110
-
-attribute vec3 a_vertex;
-attribute vec2 a_uv0;
-
-uniform float mapSize;
-
-void main()
-{
- gl_Position = gl_ModelViewProjectionMatrix * vec4(a_vertex, 1.0);
- gl_TexCoord[0].st = a_uv0;
- gl_TexCoord[0].zw = vec2(a_vertex.xz)/mapSize;
-}
diff --git a/build/svn_revision/svn_revision.txt b/build/svn_revision/svn_revision.txt
index a5498269c0..30db31e829 100644
--- a/build/svn_revision/svn_revision.txt
+++ b/build/svn_revision/svn_revision.txt
@@ -1 +1 @@
-L"custom build"
+L"-release"
diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h
index a7e8f2cedd..5cac414734 100644
--- a/source/ps/CStrInternStatic.h
+++ b/source/ps/CStrInternStatic.h
@@ -50,7 +50,7 @@ X(MODE_WIREFRAME)
X(SYS_HAS_ARB)
X(SYS_HAS_GLSL)
X(SYS_PREFER_GLSL)
-X(USE_FOAM)
+X(USE_FANCY_EFFECTS)
X(USE_FP_SHADOW)
X(USE_GPU_SKINNING)
X(USE_INSTANCING)
@@ -60,10 +60,9 @@ X(USE_REAL_DEPTH)
X(USE_REFLECTION)
X(USE_REFRACTION)
X(USE_SHADOW)
-X(USE_SHADOWS)
+X(USE_SHADOWS_ON_WATER)
X(USE_SHADOW_PCF)
X(USE_SHADOW_SAMPLER)
-X(USE_WAVES)
X2(_emptystring, "")
X(a_skinJoints)
X(a_skinWeights)
@@ -142,7 +141,7 @@ X(tint)
X(transform)
X(translation)
X(waterTex)
-X(waveTex)
+X(waterEffectsTex)
X(waviness)
X(width)
X(zFar)
diff --git a/source/ps/GameSetup/Config.cpp b/source/ps/GameSetup/Config.cpp
index 6b9e99b62d..2389e02cdd 100644
--- a/source/ps/GameSetup/Config.cpp
+++ b/source/ps/GameSetup/Config.cpp
@@ -41,10 +41,9 @@ bool g_RenderActors = true;
bool g_Shadows = false;
bool g_ShadowPCF = false;
-bool g_WaterNormal = false;
+bool g_WaterUgly = false;
+bool g_WaterFancyEffects = false;
bool g_WaterRealDepth = false;
-bool g_WaterFoam = false;
-bool g_WaterCoastalWaves = false;
bool g_WaterRefraction = false;
bool g_WaterReflection = false;
bool g_WaterShadows = false;
@@ -94,15 +93,12 @@ static void LoadGlobals()
CFG_GET_VAL("shadows", Bool, g_Shadows);
CFG_GET_VAL("shadowpcf", Bool, g_ShadowPCF);
- CFG_GET_VAL("waternormals",Bool, g_WaterNormal);
+ CFG_GET_VAL("waterugly",Bool, g_WaterUgly);
+ CFG_GET_VAL("waterfancyeffects",Bool, g_WaterFancyEffects);
CFG_GET_VAL("waterrealdepth",Bool, g_WaterRealDepth);
- CFG_GET_VAL("waterfoam",Bool, g_WaterFoam);
- CFG_GET_VAL("watercoastalwaves",Bool, g_WaterCoastalWaves);
- if (g_WaterCoastalWaves && !g_WaterNormal)
- g_WaterCoastalWaves = false;
CFG_GET_VAL("waterrefraction",Bool, g_WaterRefraction);
CFG_GET_VAL("waterreflection",Bool, g_WaterReflection);
- CFG_GET_VAL("watershadows",Bool, g_WaterShadows);
+ CFG_GET_VAL("shadowsonwater",Bool, g_WaterShadows);
CFG_GET_VAL("renderpath", String, g_RenderPath);
CFG_GET_VAL("particles", Bool, g_Particles);
diff --git a/source/ps/GameSetup/Config.h b/source/ps/GameSetup/Config.h
index 586c869fd3..34d41baf29 100644
--- a/source/ps/GameSetup/Config.h
+++ b/source/ps/GameSetup/Config.h
@@ -50,14 +50,12 @@ extern bool g_RenderActors;
// flag to switch on shadows
extern bool g_Shadows;
-// Use real normals for ocean-wave rendering, instead of applying them as a flat texture.
-extern bool g_WaterNormal;
+// Force the use of the fixed function for rendering water.
+extern bool g_WaterUgly;
+// Add foam and waves near the shores, trails following ships, and other HQ things.
+extern bool g_WaterFancyEffects;
// Use real depth for water rendering.
extern bool g_WaterRealDepth;
-// Show foam near the shores depending on waviness.
-extern bool g_WaterFoam;
-// Show coastal breaking waves.
-extern bool g_WaterCoastalWaves;
// Use a real refraction map and not transparency.
extern bool g_WaterRefraction;
// Use a real reflection map and not a skybox texture.
diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp
index 8ccbaa399d..4807bc7f4d 100644
--- a/source/ps/GameSetup/GameSetup.cpp
+++ b/source/ps/GameSetup/GameSetup.cpp
@@ -591,13 +591,12 @@ static void InitRenderer()
g_Renderer.SetOptionBool(CRenderer::OPT_NOVBO, g_NoGLVBO);
g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS, g_Shadows);
- g_Renderer.SetOptionBool(CRenderer::OPT_WATERNORMAL, g_WaterNormal);
+ g_Renderer.SetOptionBool(CRenderer::OPT_WATERUGLY, g_WaterUgly);
+ g_Renderer.SetOptionBool(CRenderer::OPT_WATERFANCYEFFECTS, g_WaterFancyEffects);
g_Renderer.SetOptionBool(CRenderer::OPT_WATERREALDEPTH, g_WaterRealDepth);
- g_Renderer.SetOptionBool(CRenderer::OPT_WATERFOAM, g_WaterFoam);
- g_Renderer.SetOptionBool(CRenderer::OPT_WATERCOASTALWAVES, g_WaterCoastalWaves);
g_Renderer.SetOptionBool(CRenderer::OPT_WATERREFLECTION, g_WaterReflection);
g_Renderer.SetOptionBool(CRenderer::OPT_WATERREFRACTION, g_WaterRefraction);
- g_Renderer.SetOptionBool(CRenderer::OPT_WATERSHADOW, g_WaterShadows);
+ g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWSONWATER, g_WaterShadows);
g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_RenderPath));
g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWPCF, g_ShadowPCF);
diff --git a/source/ps/GameSetup/HWDetect.cpp b/source/ps/GameSetup/HWDetect.cpp
index 6a94f6da87..47aa57a184 100644
--- a/source/ps/GameSetup/HWDetect.cpp
+++ b/source/ps/GameSetup/HWDetect.cpp
@@ -147,39 +147,28 @@ void SetDisableShadowPCF(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool di
void SetDisableAllWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
{
- if (!IsOverridden("waternormals"))
- g_WaterNormal = !disabled;
+ g_WaterUgly = true;
+ if (!IsOverridden("waterfancyeffects"))
+ g_WaterFancyEffects = !disabled;
if (!IsOverridden("waterrealdepth"))
g_WaterRealDepth = !disabled;
- if (!IsOverridden("waterfoam"))
- g_WaterFoam = !disabled;
- if (!IsOverridden("watercoastalwaves"))
- g_WaterCoastalWaves = !disabled;
if (!IsOverridden("waterrefraction"))
g_WaterRefraction = !disabled;
if (!IsOverridden("waterreflection"))
g_WaterReflection = !disabled;
- if (!IsOverridden("watershadows"))
+ if (!IsOverridden("shadowsonwater"))
g_WaterShadows = !disabled;
}
+
void SetDisableFancyWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
{
+ if (!IsOverridden("waterfancyeffects"))
+ g_WaterFancyEffects = !disabled;
if (!IsOverridden("waterrealdepth"))
g_WaterRealDepth = !disabled;
- if (!IsOverridden("waterfoam"))
- g_WaterFoam = !disabled;
- if (!IsOverridden("watercoastalwaves"))
- g_WaterCoastalWaves = !disabled;
- if (!IsOverridden("watershadows"))
+ if (!IsOverridden("shadowsonwater"))
g_WaterShadows = !disabled;
}
-void SetDisableFBOWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
-{
- if (!IsOverridden("waterfoam"))
- g_WaterFoam = !disabled;
- if (!IsOverridden("watercoastalwaves"))
- g_WaterCoastalWaves = !disabled;
-}
void SetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string renderpath)
{
@@ -198,7 +187,6 @@ void RunHardwareDetection()
scriptInterface.RegisterFunction("SetDisableShadowPCF");
scriptInterface.RegisterFunction("SetDisableAllWater");
scriptInterface.RegisterFunction("SetDisableFancyWater");
- scriptInterface.RegisterFunction("SetDisableFBOWater");
scriptInterface.RegisterFunction("SetRenderPath");
// Load the detection script:
diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp
index 0bb55f3efc..3e22f6ea59 100644
--- a/source/renderer/PatchRData.cpp
+++ b/source/renderer/PatchRData.cpp
@@ -1305,31 +1305,168 @@ void CPatchRData::BuildWater()
// TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
- if (WaterMgr->m_NeedInfoUpdate)
+ /*if (WaterMgr->m_NeedInfoUpdate)
{
WaterMgr->m_NeedInfoUpdate = false;
WaterMgr->CreateSuperfancyInfo(m_Simulation);
- }
+ }*/
CPatch* patch = m_Patch;
CTerrain* terrain = patch->m_Parent;
ssize_t mapSize = (size_t)terrain->GetVerticesPerSide();
-
+
+ //Top-left coordinates of our patch.
ssize_t x1 = m_Patch->m_X*PATCH_SIZE;
ssize_t z1 = m_Patch->m_Z*PATCH_SIZE;
+ // to whoever implements different water heights, this is a TODO: water height)
+ float waterHeight = cmpWaterManager->GetExactWaterLevel(0.0f,0.0f);
+
+ int moves[4][2] = { {0,0}, {water_cell_size,0}, {0,water_cell_size}, {water_cell_size,water_cell_size} };
+
// build vertices, uv, and shader varying
for (ssize_t z = 0; z < PATCH_SIZE; z += water_cell_size)
{
- for (ssize_t x = 0; x <= PATCH_SIZE; x += water_cell_size)
+ for (ssize_t x = 0; x < PATCH_SIZE; x += water_cell_size)
{
- // Check that the edge at x is partially underwater
- float startTerrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) };
- float startWaterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) };
- if (startTerrainHeight[0] >= startWaterHeight[0] && startTerrainHeight[1] >= startWaterHeight[1])
+
+ // Check that this tile has at least one vertice underwater.
+ if (terrain->GetVertexGroundLevel(x+x1, z+z1) >= waterHeight
+ && terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) >= waterHeight
+ && terrain->GetVertexGroundLevel(x+x1 + water_cell_size, z+z1) >= waterHeight
+ && terrain->GetVertexGroundLevel(x+x1 + water_cell_size, z+z1 + water_cell_size) >= waterHeight)
continue;
+
+ // This is actually lying and I should call CcmpTerrain
+ /*if (!terrain->IsOnMap(x+x1, z+z1)
+ && !terrain->IsOnMap(x+x1, z+z1 + water_cell_size)
+ && !terrain->IsOnMap(x+x1 + water_cell_size, z+z1)
+ && !terrain->IsOnMap(x+x1 + water_cell_size, z+z1 + water_cell_size))
+ continue;*/
+
+ // Figure out our points. We might want to draw only one of two triangles per tile.
+ // In order: the one on the diagonal on top, the one of the diagonal on bottom, other on top, other on bottom.
+ // The numbers refer to "moves" above. -1 means "not rendering".
+ // by default the diagonal is the "x,z->x+1,z+1" one.
+ int points[4] = { 0, 3, 1, 2 };
+
+ // If the other diagonal is over water completely, that means we have the wrong diagonal.
+ if (terrain->GetVertexGroundLevel(x+x1 + water_cell_size, z+z1) >= waterHeight
+ && terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) >= waterHeight)
+ {
+ points[0] = 1; points[1] = 2; points[2] = 0; points[3] = 3;
+ }
+
+ // check if the diagonal is completely out of the water, and if so, check which triangles we want to render (1 or 2)
+ if (terrain->GetVertexGroundLevel(x+x1 + moves[points[0]][0], z+z1 + moves[points[0]][1]) >= waterHeight
+ && terrain->GetVertexGroundLevel(x+x1 + moves[points[1]][0], z+z1 + moves[points[1]][1]) >= waterHeight)
+ {
+ if (terrain->GetVertexGroundLevel(x+x1 + moves[points[2]][0], z+z1 + moves[points[2]][1]) >= waterHeight)
+ points[2] = -1;
+ else if (terrain->GetVertexGroundLevel(x+x1 + moves[points[3]][0], z+z1 + moves[points[3]][1]) >= waterHeight)
+ points[3] = -1;
+ }
+
+ // Compute data.
+ for (int i = 0; i < 4; ++i)
+ {
+ if (points[i] == -1)
+ continue;
+ // Check if we already computed this vertex from an earlier strip
+ if (water_index_map[z+moves[points[i]][1]][x+moves[points[i]][0]] != 0xFFFF)
+ continue;
+
+ ssize_t zz = z+z1+moves[points[i]][1];
+ ssize_t xx = x+x1+moves[points[i]][0];
+
+ SWaterVertex vertex;
+
+ terrain->CalcPosition(xx,zz, vertex.m_Position);
+ float depth = waterHeight - vertex.m_Position.Y;
+ // Try and get the point on the shore if it's over water.
+ // In some cases this won't be possible.
+ if (depth < 0.0f)
+ {
+ float temp = 0.0f;
+ float left_t = 0.0f,right_t = 0.0f,top_t = 0.0f,bottom_t = 0.0f;
+ if (xx > 0)
+ {
+ temp = terrain->GetVertexGroundLevel(xx-1,zz);
+ if (temp < waterHeight)
+ left_t = 1.0f-(temp-waterHeight)/(temp-vertex.m_Position.Y);
+ }
+ if (xx < mapSize - 1)
+ {
+ temp = terrain->GetVertexGroundLevel(xx+1,zz);
+ if (temp < waterHeight)
+ right_t = 1.0f-(temp-waterHeight)/(temp-vertex.m_Position.Y);
+ }
+ if (zz > 0)
+ {
+ temp = terrain->GetVertexGroundLevel(xx,zz-1);
+ if (temp < waterHeight)
+ top_t = 1.0f-(temp-waterHeight)/(temp-vertex.m_Position.Y);
+ }
+ if (zz < mapSize - 1)
+ {
+ temp = terrain->GetVertexGroundLevel(xx,zz-1);
+ if (temp < waterHeight)
+ bottom_t = 1.0f-(temp-waterHeight)/(temp-vertex.m_Position.Y);
+ }
+ vertex.m_Position.X = vertex.m_Position.X + 4.0 * (right_t - left_t);
+ vertex.m_Position.Z = vertex.m_Position.Z + 4.0 * (bottom_t - top_t);
+ }
+ vertex.m_Position.Y = waterHeight;
+
+ m_WaterBounds += vertex.m_Position;
+
+ // faking fresnel for simplest water.
+ float alpha = clamp(depth / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha);
+
+ // Split the depth data across 24 bits, so the fancy-water shader can reconstruct
+ // the depth value while the simple-water can just use the precomputed alpha
+ float depthInt = floor(depth);
+ float depthFrac = depth - depthInt;
+ vertex.m_DepthData = SColor4ub(u8(clamp(depthInt, 0.0f, 255.0f)),
+ u8(clamp(-depthInt, 0.0f, 255.0f)),
+ u8(clamp(depthFrac*255.0f, 0.0f, 255.0f)),
+ u8(clamp(alpha*255.0f, 0.0f, 255.0f)));
- // Move x back one cell (unless at start of patch), then scan rightwards
+ vertex.m_WaterData = CVector4D(WaterMgr->m_BlurredNormalMap[xx + zz*mapSize].X,
+ WaterMgr->m_BlurredNormalMap[xx + zz*mapSize].Z,
+ WaterMgr->m_DistanceHeightmap[xx + zz*mapSize],
+ 0.0f);
+
+ water_index_map[z+moves[points[i]][1]][x+moves[points[i]][0]] = water_vertex_data.size();
+ water_vertex_data.push_back(vertex);
+ }
+ // Render them.
+ if (points[2] == 0) // Top point is wanted, render corresponding triangle
+ {
+ water_indices.push_back(water_index_map[z + moves[points[1]][1]][x + moves[points[1]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[2]][1]][x + moves[points[2]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[0]][1]][x + moves[points[0]][0]]);
+ }
+ else if (points[2] == 1)
+ {
+ water_indices.push_back(water_index_map[z + moves[points[1]][1]][x + moves[points[1]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[0]][1]][x + moves[points[0]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[2]][1]][x + moves[points[2]][0]]);
+ }
+ if (points[3] == 3) // Bottom point is wanted, render corresponding triangle.
+ {
+ water_indices.push_back(water_index_map[z + moves[points[1]][1]][x + moves[points[1]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[0]][1]][x + moves[points[0]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[3]][1]][x + moves[points[3]][0]]);
+ }
+ else if (points[3] == 2)
+ {
+ water_indices.push_back(water_index_map[z + moves[points[1]][1]][x + moves[points[1]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[3]][1]][x + moves[points[3]][0]]);
+ water_indices.push_back(water_index_map[z + moves[points[0]][1]][x + moves[points[0]][0]]);
+ }
+
+ /*// Move x back one cell (unless at start of patch), then scan rightwards.
bool belowWater = true;
ssize_t stripStart;
for (stripStart = x = std::max(x-water_cell_size, (ssize_t)0); x <= PATCH_SIZE; x += water_cell_size)
@@ -1337,9 +1474,7 @@ void CPatchRData::BuildWater()
// If this edge is not underwater, and neither is the previous edge
// (i.e. belowWater == false), then stop this strip since we've reached
// a cell that's entirely above water
- float terrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) };
- float waterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) };
- if (terrainHeight[0] >= waterHeight[0] && terrainHeight[1] >= waterHeight[1])
+ if (terrain->GetVertexGroundLevel(x+x1, z+z1) >= waterHeight && terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) >= waterHeight)
{
if (!belowWater)
break;
@@ -1404,7 +1539,7 @@ void CPatchRData::BuildWater()
water_indices.push_back(water_index_map[z + water_cell_size][x]);
water_indices.push_back(water_index_map[z][x - water_cell_size]);
water_indices.push_back(water_index_map[z][x]);
- }
+ }*/
}
}
@@ -1430,6 +1565,8 @@ void CPatchRData::RenderWater(CShaderProgramPtr& shader)
SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind();
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
// setup data pointers
GLsizei stride = sizeof(SWaterVertex);
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, &base[m_VBWater->m_Index].m_DepthData);
@@ -1445,6 +1582,8 @@ void CPatchRData::RenderWater(CShaderProgramPtr& shader)
glDrawElements(GL_TRIANGLES, (GLsizei) m_VBWaterIndices->m_Count,
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndices->m_Index));
}
+
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// bump stats
g_Renderer.m_Stats.m_DrawCalls++;
diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp
index 4c1aa4f303..717df2c741 100644
--- a/source/renderer/Renderer.cpp
+++ b/source/renderer/Renderer.cpp
@@ -667,26 +667,23 @@ void CRenderer::SetOptionBool(enum Option opt,bool value)
m_Options.m_Shadows = value;
MakeShadersDirty();
break;
- case OPT_WATERNORMAL:
- m_Options.m_WaterNormal = value;
+ case OPT_WATERUGLY:
+ m_Options.m_WaterUgly = value;
+ break;
+ case OPT_WATERFANCYEFFECTS:
+ m_Options.m_WaterFancyEffects = value;
break;
case OPT_WATERREALDEPTH:
m_Options.m_WaterRealDepth = value;
break;
- case OPT_WATERFOAM:
- m_Options.m_WaterFoam = value;
- break;
- case OPT_WATERCOASTALWAVES:
- m_Options.m_WaterCoastalWaves = value;
- break;
case OPT_WATERREFLECTION:
m_Options.m_WaterReflection = value;
break;
case OPT_WATERREFRACTION:
m_Options.m_WaterRefraction = value;
break;
- case OPT_WATERSHADOW:
- m_Options.m_WaterShadow = value;
+ case OPT_SHADOWSONWATER:
+ m_Options.m_WaterShadows = value;
break;
case OPT_SHADOWPCF:
m_Options.m_ShadowPCF = value;
@@ -733,20 +730,18 @@ bool CRenderer::GetOptionBool(enum Option opt) const
return m_Options.m_NoVBO;
case OPT_SHADOWS:
return m_Options.m_Shadows;
- case OPT_WATERNORMAL:
- return m_Options.m_WaterNormal;
+ case OPT_WATERUGLY:
+ return m_Options.m_WaterUgly;
+ case OPT_WATERFANCYEFFECTS:
+ return m_Options.m_WaterFancyEffects;
case OPT_WATERREALDEPTH:
return m_Options.m_WaterRealDepth;
- case OPT_WATERFOAM:
- return m_Options.m_WaterFoam;
- case OPT_WATERCOASTALWAVES:
- return m_Options.m_WaterCoastalWaves;
case OPT_WATERREFLECTION:
return m_Options.m_WaterReflection;
case OPT_WATERREFRACTION:
return m_Options.m_WaterRefraction;
- case OPT_WATERSHADOW:
- return m_Options.m_WaterShadow;
+ case OPT_SHADOWSONWATER:
+ return m_Options.m_WaterShadows;
case OPT_SHADOWPCF:
return m_Options.m_ShadowPCF;
case OPT_PARTICLES:
diff --git a/source/renderer/Renderer.h b/source/renderer/Renderer.h
index cd35db0bfc..21e8b440c9 100644
--- a/source/renderer/Renderer.h
+++ b/source/renderer/Renderer.h
@@ -80,13 +80,12 @@ public:
enum Option {
OPT_NOVBO,
OPT_SHADOWS,
- OPT_WATERNORMAL,
+ OPT_WATERUGLY,
+ OPT_WATERFANCYEFFECTS,
OPT_WATERREALDEPTH,
- OPT_WATERFOAM,
- OPT_WATERCOASTALWAVES,
OPT_WATERREFLECTION,
OPT_WATERREFRACTION,
- OPT_WATERSHADOW,
+ OPT_SHADOWSONWATER,
OPT_SHADOWPCF,
OPT_PARTICLES,
OPT_GENTANGENTS,
@@ -143,13 +142,12 @@ public:
bool m_NoVBO;
bool m_Shadows;
- bool m_WaterNormal;
+ bool m_WaterUgly;
+ bool m_WaterFancyEffects;
bool m_WaterRealDepth;
- bool m_WaterFoam;
- bool m_WaterCoastalWaves;
bool m_WaterRefraction;
bool m_WaterReflection;
- bool m_WaterShadow;
+ bool m_WaterShadows;
RenderPath m_RenderPath;
bool m_ShadowAlphaFix;
diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp
index 26eb8abb36..45e7325c8f 100644
--- a/source/renderer/TerrainRenderer.cpp
+++ b/source/renderer/TerrainRenderer.cpp
@@ -85,7 +85,7 @@ struct TerrainRendererInternals
/// Fancy water shader
CShaderProgramPtr fancyWaterShader;
- CShaderProgramPtr wavesShader;
+ CShaderProgramPtr fancyEffectsShader;
CSimulation2* simulation;
};
@@ -632,32 +632,26 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
CShaderDefines defines = context;
- WaterMgr->UpdateQuality();
-
// If we're using fancy water, make sure its shader is loaded
if (!m->fancyWaterShader || WaterMgr->m_NeedsReloading)
{
- if (WaterMgr->m_WaterNormal)
- defines.Add(str_USE_NORMALS, str_1);
if (WaterMgr->m_WaterRealDepth)
defines.Add(str_USE_REAL_DEPTH, str_1);
- if (WaterMgr->m_WaterFoam)
- defines.Add(str_USE_FOAM, str_1);
- if (WaterMgr->m_WaterCoastalWaves && false)
- defines.Add(str_USE_WAVES, str_1);
+ if (WaterMgr->m_WaterFancyEffects)
+ defines.Add(str_USE_FANCY_EFFECTS, str_1);
if (WaterMgr->m_WaterRefraction)
defines.Add(str_USE_REFRACTION, str_1);
if (WaterMgr->m_WaterReflection)
defines.Add(str_USE_REFLECTION, str_1);
if (shadow && WaterMgr->m_WaterShadows)
- defines.Add(str_USE_SHADOWS, str_1);
+ defines.Add(str_USE_SHADOWS_ON_WATER, str_1);
- m->wavesShader = g_Renderer.GetShaderManager().LoadProgram("glsl/waves", defines);
- if (!m->wavesShader)
+ m->fancyEffectsShader = g_Renderer.GetShaderManager().LoadProgram("glsl/water_effects", defines);
+ if (!m->fancyEffectsShader)
{
- LOGERROR(L"Failed to load waves shader. Deactivating waves.\n");
- g_Renderer.SetOptionBool(CRenderer::OPT_WATERCOASTALWAVES, false);
- defines.Add(str_USE_WAVES, str_0);
+ LOGERROR(L"Failed to load Fancy effects shader. Deactivating fancy effects.\n");
+ g_Renderer.SetOptionBool(CRenderer::OPT_WATERFANCYEFFECTS, false);
+ defines.Add(str_USE_FANCY_EFFECTS, str_0);
}
// haven't updated the ARB shader yet so I'll always load the GLSL
@@ -668,7 +662,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
if (!m->fancyWaterShader)
{
- LOGERROR(L"Failed to load water shader. Falling back to non-fancy water.\n");
+ LOGERROR(L"Failed to load water shader. Falling back to fixed pipeline water.\n");
WaterMgr->m_RenderWater = false;
return false;
}
@@ -717,104 +711,94 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
WaterMgr->CreateSuperfancyInfo();
}*/
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
-
double time = WaterMgr->m_WaterTexTimer;
double period = 8;
int curTex = (int)(time*60/period) % 60;
int nexTex = (curTex + 1) % 60;
- GLuint FramebufferName = 0;
-
- // rendering waves to a framebuffer
- // TODO: reactivate this with something that looks good.
- if (false && WaterMgr->m_WaterCoastalWaves && WaterMgr->m_VBWaves && !g_AtlasGameLoop->running)
- {
- // Save the post-processing framebuffer.
- GLint fbo;
- glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
-
- pglGenFramebuffersEXT(1, &FramebufferName);
- pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferName);
-
- GLuint renderedTexture;
- if (WaterMgr->m_waveTT == 0)
- {
- glGenTextures(1, &renderedTexture);
- WaterMgr->m_waveTT = renderedTexture;
-
- glBindTexture(GL_TEXTURE_2D, WaterMgr->m_waveTT);
- // TODO: use POT texture
- glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- }
- glBindTexture(GL_TEXTURE_2D, WaterMgr->m_waveTT);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, WaterMgr->m_waveTT, 0);
-
- glClearColor(0.5f,0.5f,1.0f,0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // rendering
- m->wavesShader->Bind();
- m->wavesShader->BindTexture(str_waveTex, WaterMgr->m_Wave);
- m->wavesShader->Uniform(str_time, (float)time);
- m->wavesShader->Uniform(str_waviness, WaterMgr->m_Waviness);
- m->wavesShader->Uniform(str_mapSize, (float)(WaterMgr->m_MapSize));
-
- SWavesVertex *base=(SWavesVertex *)WaterMgr->m_VBWaves->m_Owner->Bind();
- GLsizei stride = sizeof(SWavesVertex);
- m->wavesShader->VertexPointer(3, GL_FLOAT, stride, &base[WaterMgr->m_VBWaves->m_Index].m_Position);
- m->wavesShader->TexCoordPointer(GL_TEXTURE0,2,GL_BYTE, stride,&base[WaterMgr->m_VBWaves->m_Index].m_UV);
- m->wavesShader->AssertPointersBound();
-
- u8* indexBase = WaterMgr->m_VBWavesIndices->m_Owner->Bind();
- glDrawElements(GL_TRIANGLES, (GLsizei) WaterMgr->m_VBWavesIndices->m_Count, GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(WaterMgr->m_VBWavesIndices->m_Index));
-
- g_Renderer.m_Stats.m_DrawCalls++;
- CVertexBuffer::Unbind();
- m->wavesShader->Unbind();
-
- // rebind post-processing frambuffer.
- pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- }
-
- m->fancyWaterShader->Bind();
-
-
// Shift the texture coordinates by these amounts to make the water "flow"
float tx = -fmod(time, 81.0 / (WaterMgr->m_Waviness/20.0 + 0.8) )/(81.0/ (WaterMgr->m_Waviness/20.0 + 0.8) );
float ty = -fmod(time, 34.0 / (WaterMgr->m_Waviness/20.0 + 0.8) )/(34.0/ (WaterMgr->m_Waviness/20.0 + 0.8) );
float repeatPeriod = WaterMgr->m_RepeatPeriod;
+
+ GLuint FramebufferName = 0;
+
+ // Render normals and foam to a framebuffer if we're in fancy effects
+ if (WaterMgr->m_WaterFancyEffects)
+ {
+ // Save the post-processing framebuffer.
+ GLint fbo;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
+
+ // Generate our framebuffer
+ pglGenFramebuffersEXT(1, &FramebufferName);
+ pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferName);
+
+ GLuint renderedTexture;
+ if (WaterMgr->m_FancyTexture == 0)
+ {
+ glGenTextures(1, &renderedTexture);
+ WaterMgr->m_FancyTexture = renderedTexture;
+
+ glBindTexture(GL_TEXTURE_2D, WaterMgr->m_FancyTexture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0,GL_RGBA, GL_FLOAT, 0);
+ } else
+ glBindTexture(GL_TEXTURE_2D, WaterMgr->m_FancyTexture);
+
+ pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, WaterMgr->m_FancyTexture, 0);
+
+ // rendering
+ m->fancyEffectsShader->Bind();
+ m->fancyEffectsShader->BindTexture(str_normalMap, WaterMgr->m_NormalMap[curTex]);
+ m->fancyEffectsShader->BindTexture(str_normalMap2, WaterMgr->m_NormalMap[nexTex]);
+ m->fancyEffectsShader->Uniform(str_waviness, WaterMgr->m_Waviness);
+ m->fancyEffectsShader->Uniform(str_translation, tx, ty);
+ m->fancyEffectsShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
+ m->fancyEffectsShader->Uniform(str_time, (float)time);
+ m->fancyEffectsShader->Uniform(str_screenSize, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0.0f, 0.0f);
+ m->fancyEffectsShader->Uniform(str_mapSize, (float)(WaterMgr->m_MapSize));
+
+ std::vector& visiblePatches = m->visiblePatches[cullGroup];
+ for (size_t i = 0; i < visiblePatches.size(); ++i)
+ {
+ CPatchRData* data = visiblePatches[i];
+ data->RenderWater(m->fancyEffectsShader);
+ }
+
+ m->fancyEffectsShader->Unbind();
+
+ // rebind post-processing frambuffer.
+ pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+
+ m->fancyWaterShader->Bind();
+
const CCamera& camera = g_Renderer.GetViewCamera();
CVector3D camPos = camera.m_Orientation.GetTranslation();
m->fancyWaterShader->BindTexture(str_normalMap, WaterMgr->m_NormalMap[curTex]);
m->fancyWaterShader->BindTexture(str_normalMap2, WaterMgr->m_NormalMap[nexTex]);
- if (WaterMgr->m_WaterFoam || WaterMgr->m_WaterCoastalWaves)
- {
- m->fancyWaterShader->BindTexture(str_Foam, WaterMgr->m_Foam);
- m->fancyWaterShader->Uniform(str_mapSize, (float)(WaterMgr->m_MapSize));
- }
+ if (WaterMgr->m_WaterFancyEffects)
+ m->fancyWaterShader->BindTexture(str_waterEffectsTex, WaterMgr->m_FancyTexture);
if (WaterMgr->m_WaterRealDepth)
m->fancyWaterShader->BindTexture(str_depthTex, WaterMgr->m_depthTT);
- if (WaterMgr->m_WaterCoastalWaves)
- m->fancyWaterShader->BindTexture(str_waveTex, WaterMgr->m_waveTT);
if (WaterMgr->m_WaterReflection)
- m->fancyWaterShader->BindTexture(str_reflectionMap, WaterMgr->m_ReflectionTexture);
+ m->fancyWaterShader->BindTexture(str_reflectionMap, WaterMgr->m_ReflectionTexture);
if (WaterMgr->m_WaterRefraction)
- m->fancyWaterShader->BindTexture(str_refractionMap, WaterMgr->m_RefractionTexture);
+ m->fancyWaterShader->BindTexture(str_refractionMap, WaterMgr->m_RefractionTexture);
m->fancyWaterShader->BindTexture(str_losMap, losTexture.GetTextureSmooth());
@@ -981,6 +965,8 @@ void TerrainRenderer::RenderWater(const CShaderDefines& context, int cullGroup,
{
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
+ WaterMgr->UpdateQuality();
+
if (!WaterMgr->WillRenderFancyWater())
RenderSimpleWater(cullGroup);
else
diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp
index 6bc124f4c2..5779123da5 100644
--- a/source/renderer/WaterManager.cpp
+++ b/source/renderer/WaterManager.cpp
@@ -82,10 +82,12 @@ WaterManager::WaterManager()
m_DistanceToShore = NULL;
m_FoamFactor = NULL;
- m_WaterNormal = false;
+ m_DistanceHeightmap = NULL;
+ m_BlurredNormalMap = NULL;
+
+ m_WaterUgly = false;
+ m_WaterFancyEffects = false;
m_WaterRealDepth = false;
- m_WaterFoam = false;
- m_WaterCoastalWaves = false;
m_WaterRefraction = false;
m_WaterReflection = false;
m_WaterShadows = false;
@@ -97,7 +99,7 @@ WaterManager::WaterManager()
m_VBWavesIndices = NULL;
m_depthTT = 0;
- m_waveTT = 0;
+ m_FancyTexture = 0;
m_MapSize = 0;
@@ -117,7 +119,7 @@ WaterManager::~WaterManager()
delete[] m_FoamFactor;
glDeleteTextures(1, &m_depthTT);
- glDeleteTextures(1, &m_waveTT);
+ glDeleteTextures(1, &m_FancyTexture);
if (m_VBWaves) g_VBMan.Release(m_VBWaves);
if (m_VBWavesIndices) g_VBMan.Release(m_VBWavesIndices);
@@ -134,14 +136,14 @@ int WaterManager::LoadWaterTextures()
// TODO: add a member variable and setter for this. (can't make this
// a parameter because this function is called via delay-load code)
- static const wchar_t* const water_type = L"default";
+ static const wchar_t* const water_type = L"ocean";
wchar_t pathname[PATH_MAX];
// Load diffuse grayscale images (for non-fancy water)
for (size_t i = 0; i < ARRAY_SIZE(m_WaterTexture); ++i)
{
- swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/diffuse%02d.dds", water_type, (int)i+1);
+ swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/default/diffuse%02d.dds", (int)i+1);
CTextureProperties textureProps(pathname);
textureProps.SetWrap(GL_REPEAT);
@@ -153,7 +155,7 @@ int WaterManager::LoadWaterTextures()
// Load normalmaps (for fancy water)
for (size_t i = 0; i < ARRAY_SIZE(m_NormalMap); ++i)
{
- swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal%02d.dds", water_type, (int)i+1);
+ swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal00%02d.png", water_type, (int)i+1);
CTextureProperties textureProps(pathname);
textureProps.SetWrap(GL_REPEAT);
textureProps.SetMaxAnisotropy(4);
@@ -162,6 +164,7 @@ int WaterManager::LoadWaterTextures()
texture->Prefetch();
m_NormalMap[i] = texture;
}
+
// Load foam (for fancy water)
{
CTextureProperties textureProps("art/textures/terrain/types/water/foam.png");
@@ -234,6 +237,128 @@ void WaterManager::UnloadWaterTextures()
}
}
+///////////////////////////////////////////////////////////////////
+// Calculate our binary heightmap from the terrain heightmap.
+void WaterManager::RecomputeDistanceHeightmap()
+{
+ if (m_DistanceHeightmap == NULL)
+ m_DistanceHeightmap = new u8[m_MapSize*m_MapSize];
+
+ // Custom copy the heightmap.
+ CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
+
+ u16 waterLevel = m_WaterHeight/HEIGHT_SCALE;
+
+ u16* heightmap = terrain->GetHeightMap();
+
+ // We will "expand" the heightmap. That is we'll set each vertex on land as "3", and "bleed" that onto neighboring pixels.
+ // So 3 is "on land", 2 is "close", 1 "somewhat close" and 0 is "water".
+ // This gives a basic manhattan approximation of how close to the coast we are.
+ // I have a heathen fondness for ternary operators so there are some below.
+ u8 level = 0;
+ for (size_t z = 0; z < m_MapSize; ++z)
+ {
+ level = 0;
+ for (size_t x = 0; x < m_MapSize; ++x)
+ m_DistanceHeightmap[z*m_MapSize + x] = heightmap[z*m_MapSize + x] >= waterLevel ? level = 3
+ : level > 0 ? --level : 0;
+ level = 0;
+ for (size_t x = m_MapSize-1; x != (size_t)-1; --x)
+ {
+ if (heightmap[z*m_MapSize + x] >= waterLevel)
+ level = 3; // no need to set m_distanceHeightmap, it's already been done by the other loop.
+ else
+ {
+ level > 0 ? --level : 0;
+ if (level > m_DistanceHeightmap[z*m_MapSize + x])
+ m_DistanceHeightmap[z*m_MapSize + x] = level;
+ }
+ }
+ }
+ for (size_t x = 0; x < m_MapSize; ++x)
+ {
+ level = 0;
+ for (size_t z = 0; z < m_MapSize; ++z)
+ {
+ if (heightmap[z*m_MapSize + x] >= waterLevel)
+ level = 3;
+ else
+ {
+ level > 0 ? --level : 0;
+ if (level > m_DistanceHeightmap[z*m_MapSize + x])
+ m_DistanceHeightmap[z*m_MapSize + x] = level;
+ }
+ }
+ level = 0;
+ for (size_t z = m_MapSize-1; z != (size_t)-1; --z)
+ {
+ if (heightmap[z*m_MapSize + x] >= waterLevel)
+ level = 3;
+ else
+ {
+ level > 0 ? --level : 0;
+ if (level > m_DistanceHeightmap[z*m_MapSize + x])
+ m_DistanceHeightmap[z*m_MapSize + x] = level;
+ }
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+// Calculate The blurred normal map to get an idea of where water ought to go.
+void WaterManager::RecomputeBlurredNormalMap()
+{
+ // used to cache terrain normals since otherwise we'd recalculate them a lot (I'm blurring the "normal" map).
+ // this might be updated to actually cache in the terrain manager but that's not for now.
+ if (m_BlurredNormalMap == NULL)
+ m_BlurredNormalMap = new CVector3D[m_MapSize*m_MapSize];
+
+ CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
+
+ // It's really slow to calculate normals so cache them first.
+ CVector3D* normals = new CVector3D[m_MapSize*m_MapSize];
+
+ // Not the edges, we won't care about them.
+ float ii = 8.0f, jj = 8.0f;
+ for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f)
+ for (size_t i = 2; i < m_MapSize-2; ++i, ii += 4.0f)
+ {
+ CVector3D norm;
+ terrain->CalcNormal(i,j,norm);
+ normals[j*m_MapSize + i] = norm;
+ }
+
+ // We could be way fancier (and faster) for our blur but we probably don't need the complexity.
+ // Two pass filter, nothing complicated here.
+ CVector3D blurValue;
+ ii = 8.0f; jj = 8.0f;
+ size_t idx = 2;
+ for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f)
+ for (size_t i = 2; i < m_MapSize-2; ++i, ii += 4.0f,++idx)
+ {
+ blurValue = normals[idx-2];
+ blurValue += normals[idx-1];
+ blurValue += normals[idx];
+ blurValue += normals[idx+1];
+ blurValue += normals[idx+2];
+ m_BlurredNormalMap[idx] = blurValue * 0.2f;
+ }
+ // y direction, probably slower because of cache misses but I don't see an easy way around that.
+ ii = 8.0f; jj = 8.0f;
+ for (size_t i = 2; i < m_MapSize-2; ++i, ii += 4.0f)
+ {
+ for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f)
+ {
+ blurValue = normals[(j-2)*m_MapSize + i];
+ blurValue += normals[(j-1)*m_MapSize + i];
+ blurValue += normals[j*m_MapSize + i];
+ blurValue += normals[(j+1)*m_MapSize + i];
+ blurValue += normals[(j+2)*m_MapSize + i];
+ m_BlurredNormalMap[j*m_MapSize + i] = blurValue * 0.2f;
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////
// Create information about the terrain and wave vertices.
void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
@@ -248,7 +373,7 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
g_VBMan.Release(m_VBWavesIndices);
m_VBWavesIndices = NULL;
}
-
+
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
CmpPtr cmpWaterManager(*simulation, SYSTEM_ENTITY);
@@ -608,7 +733,7 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
}
////////////////////////////////////////////////////////////////////////
-// This will always recalculate for now
+// TODO: This will always recalculate for now
void WaterManager::SetMapSize(size_t size)
{
// TODO: Im' blindly trusting the user here.
@@ -619,6 +744,8 @@ void WaterManager::SetMapSize(size_t size)
m_updatej0 = 0;
m_updatej1 = size;
+ SAFE_ARRAY_DELETE(m_DistanceHeightmap);
+ SAFE_ARRAY_DELETE(m_BlurredNormalMap);
SAFE_ARRAY_DELETE(m_WaveX);
SAFE_ARRAY_DELETE(m_WaveZ);
SAFE_ARRAY_DELETE(m_DistanceToShore);
@@ -629,24 +756,18 @@ void WaterManager::SetMapSize(size_t size)
// This will set the bools properly
void WaterManager::UpdateQuality()
{
- if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERNORMAL) != m_WaterNormal) {
- m_WaterNormal = g_Renderer.GetOptionBool(CRenderer::OPT_WATERNORMAL);
+ if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERUGLY) != m_WaterUgly) {
+ m_WaterUgly = g_Renderer.GetOptionBool(CRenderer::OPT_WATERUGLY);
+ m_NeedsReloading = true;
+ }
+ if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERFANCYEFFECTS) != m_WaterFancyEffects) {
+ m_WaterFancyEffects = g_Renderer.GetOptionBool(CRenderer::OPT_WATERFANCYEFFECTS);
m_NeedsReloading = true;
}
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERREALDEPTH) != m_WaterRealDepth) {
m_WaterRealDepth = g_Renderer.GetOptionBool(CRenderer::OPT_WATERREALDEPTH);
m_NeedsReloading = true;
}
- if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERFOAM) != m_WaterFoam) {
- m_WaterFoam = g_Renderer.GetOptionBool(CRenderer::OPT_WATERFOAM);
- m_NeedsReloading = true;
- m_NeedInfoUpdate = true;
- }
- if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERCOASTALWAVES) != m_WaterCoastalWaves) {
- m_WaterCoastalWaves = g_Renderer.GetOptionBool(CRenderer::OPT_WATERCOASTALWAVES);
- m_NeedsReloading = true;
- m_NeedInfoUpdate = true;
- }
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERREFRACTION) != m_WaterRefraction) {
m_WaterRefraction = g_Renderer.GetOptionBool(CRenderer::OPT_WATERREFRACTION);
m_NeedsReloading = true;
@@ -655,8 +776,8 @@ void WaterManager::UpdateQuality()
m_WaterReflection = g_Renderer.GetOptionBool(CRenderer::OPT_WATERREFLECTION);
m_NeedsReloading = true;
}
- if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERSHADOW) != m_WaterShadows) {
- m_WaterShadows = g_Renderer.GetOptionBool(CRenderer::OPT_WATERSHADOW);
+ if (g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWSONWATER) != m_WaterShadows) {
+ m_WaterShadows = g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWSONWATER);
m_NeedsReloading = true;
}
}
@@ -665,7 +786,7 @@ bool WaterManager::WillRenderFancyWater()
{
if (!g_Renderer.GetCapabilities().m_FragmentShader)
return false;
- if (!m_RenderWater)
+ if (!m_RenderWater || m_WaterUgly)
return false;
return true;
}
diff --git a/source/renderer/WaterManager.h b/source/renderer/WaterManager.h
index ba780c7911..a0d65f1cad 100644
--- a/source/renderer/WaterManager.h
+++ b/source/renderer/WaterManager.h
@@ -58,11 +58,14 @@ public:
float* m_DistanceToShore;
float* m_FoamFactor;
+ u8* m_DistanceHeightmap; // Returns how far from the shore a point is. 3-2-1-0 where 3 is "on land"
+ CVector3D* m_BlurredNormalMap; // Returns how far from the shore a point is. 3-2-1-0 where 3 is "on land"
+
size_t m_MapSize;
ssize_t m_TexSize;
GLuint m_depthTT;
- GLuint m_waveTT;
+ GLuint m_FancyTexture;
// used to know what to update when updating parts of the terrain only.
u32 m_updatei0;
@@ -74,13 +77,18 @@ public:
CColor m_WaterColor;
bool m_RenderWater;
+ // Force the use of the fixed function for rendering.
+ bool m_WaterUgly;
// Those variables register the current quality level. If there is a change, I have to recompile the shader.
- bool m_WaterNormal;
+ // Use real depth or use the fake precomputed one.
bool m_WaterRealDepth;
- bool m_WaterFoam;
- bool m_WaterCoastalWaves;
+ // Use fancy shore effects and show trails behind ships
+ bool m_WaterFancyEffects;
+ // Use refractions instead of simply making the water more or less transparent.
bool m_WaterRefraction;
+ // Use complete reflections instead of showing merely the sky.
bool m_WaterReflection;
+ // Show shadows on the water.
bool m_WaterShadows;
bool m_NeedsReloading;
@@ -145,6 +153,17 @@ public:
*/
void UnloadWaterTextures();
+
+ /**
+ * RecomputeDistanceHeightmap: recalculates (or calculates) the distance heightmap.
+ */
+ void RecomputeDistanceHeightmap();
+
+ /**
+ * RecomputeBlurredNormalMap: calculates the blurred normal map of the terrain. Slow.
+ */
+ void RecomputeBlurredNormalMap();
+
/**
* CreateSuperfancyInfo: creates textures and wave vertices for superfancy water
*/
diff --git a/source/renderer/scripting/JSInterface_Renderer.cpp b/source/renderer/scripting/JSInterface_Renderer.cpp
index fb93ea7efc..28f12fa5b0 100644
--- a/source/renderer/scripting/JSInterface_Renderer.cpp
+++ b/source/renderer/scripting/JSInterface_Renderer.cpp
@@ -34,15 +34,14 @@ void JSI_Renderer::Set##SCRIPTNAME##Enabled(ScriptInterface::CxPrivate* UNUSED(p
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(PARTICLES, Particles);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(GENTANGENTS, GenTangents);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(PREFERGLSL, PreferGLSL);
-IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERNORMAL, WaterNormal);
+IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERUGLY, WaterUgly);
+IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERFANCYEFFECTS, WaterFancyEffects);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SHADOWPCF, ShadowPCF);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SHADOWS, Shadows);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERREALDEPTH, WaterRealDepth);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERREFLECTION, WaterReflection);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERREFRACTION, WaterRefraction);
-IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERFOAM, WaterFoam);
-IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERCOASTALWAVES, WaterCoastalWaves);
-IMPLEMENT_BOOLEAN_SCRIPT_SETTING(WATERSHADOW, WaterShadow);
+IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SHADOWSONWATER, WaterShadows);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SILHOUETTES, Silhouettes);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SHOWSKY, ShowSky);
IMPLEMENT_BOOLEAN_SCRIPT_SETTING(SMOOTHLOS, SmoothLOS);
@@ -75,13 +74,12 @@ void JSI_Renderer::RegisterScriptFunctions(ScriptInterface& scriptInterface)
REGISTER_BOOLEAN_SCRIPT_SETTING(Particles);
REGISTER_BOOLEAN_SCRIPT_SETTING(GenTangents);
REGISTER_BOOLEAN_SCRIPT_SETTING(PreferGLSL);
- REGISTER_BOOLEAN_SCRIPT_SETTING(WaterNormal);
+ REGISTER_BOOLEAN_SCRIPT_SETTING(WaterUgly);
+ REGISTER_BOOLEAN_SCRIPT_SETTING(WaterFancyEffects);
REGISTER_BOOLEAN_SCRIPT_SETTING(WaterRealDepth);
REGISTER_BOOLEAN_SCRIPT_SETTING(WaterReflection);
REGISTER_BOOLEAN_SCRIPT_SETTING(WaterRefraction);
- REGISTER_BOOLEAN_SCRIPT_SETTING(WaterFoam);
- REGISTER_BOOLEAN_SCRIPT_SETTING(WaterCoastalWaves);
- REGISTER_BOOLEAN_SCRIPT_SETTING(WaterShadow);
+ REGISTER_BOOLEAN_SCRIPT_SETTING(WaterShadows);
REGISTER_BOOLEAN_SCRIPT_SETTING(Silhouettes);
REGISTER_BOOLEAN_SCRIPT_SETTING(ShowSky);
REGISTER_BOOLEAN_SCRIPT_SETTING(SmoothLOS);
diff --git a/source/renderer/scripting/JSInterface_Renderer.h b/source/renderer/scripting/JSInterface_Renderer.h
index 88235370d8..9b07dd62b0 100644
--- a/source/renderer/scripting/JSInterface_Renderer.h
+++ b/source/renderer/scripting/JSInterface_Renderer.h
@@ -35,13 +35,12 @@ namespace JSI_Renderer
DECLARE_BOOLEAN_SCRIPT_SETTING(Particles);
DECLARE_BOOLEAN_SCRIPT_SETTING(GenTangents);
DECLARE_BOOLEAN_SCRIPT_SETTING(PreferGLSL);
- DECLARE_BOOLEAN_SCRIPT_SETTING(WaterNormal);
+ DECLARE_BOOLEAN_SCRIPT_SETTING(WaterUgly);
+ DECLARE_BOOLEAN_SCRIPT_SETTING(WaterFancyEffects);
DECLARE_BOOLEAN_SCRIPT_SETTING(WaterRealDepth);
DECLARE_BOOLEAN_SCRIPT_SETTING(WaterReflection);
DECLARE_BOOLEAN_SCRIPT_SETTING(WaterRefraction);
- DECLARE_BOOLEAN_SCRIPT_SETTING(WaterFoam);
- DECLARE_BOOLEAN_SCRIPT_SETTING(WaterCoastalWaves);
- DECLARE_BOOLEAN_SCRIPT_SETTING(WaterShadow);
+ DECLARE_BOOLEAN_SCRIPT_SETTING(WaterShadows);
DECLARE_BOOLEAN_SCRIPT_SETTING(Silhouettes);
DECLARE_BOOLEAN_SCRIPT_SETTING(ShowSky);
DECLARE_BOOLEAN_SCRIPT_SETTING(SmoothLOS);
diff --git a/source/simulation2/components/CCmpTerrain.cpp b/source/simulation2/components/CCmpTerrain.cpp
index 4b81bfe844..e60ef573aa 100644
--- a/source/simulation2/components/CCmpTerrain.cpp
+++ b/source/simulation2/components/CCmpTerrain.cpp
@@ -136,8 +136,11 @@ public:
}
if (ReloadWater && CRenderer::IsInitialised())
+ {
g_Renderer.GetWaterManager()->SetMapSize(vertices);
-
+ g_Renderer.GetWaterManager()->RecomputeDistanceHeightmap();
+ g_Renderer.GetWaterManager()->RecomputeBlurredNormalMap();
+ }
MakeDirty(0, 0, tiles+1, tiles+1);
}
diff --git a/source/simulation2/components/CCmpWaterManager.cpp b/source/simulation2/components/CCmpWaterManager.cpp
index 61d617d040..ade4174eb2 100644
--- a/source/simulation2/components/CCmpWaterManager.cpp
+++ b/source/simulation2/components/CCmpWaterManager.cpp
@@ -33,6 +33,7 @@ class CCmpWaterManager : public ICmpWaterManager
public:
static void ClassInit(CComponentManager& componentManager)
{
+ // No need to subscribe to WaterChanged since we're actually the one sending those.
componentManager.SubscribeToMessageType(MT_Interpolate);
componentManager.SubscribeToMessageType(MT_TerrainChanged);
}
@@ -50,7 +51,6 @@ public:
virtual void Init(const CParamNode& UNUSED(paramNode))
{
- SetWaterLevel(entity_pos_t::FromInt(5));
}
virtual void Deinit()
@@ -119,6 +119,8 @@ public:
// Tell the terrain it'll need to recompute its cached render data
GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES);
+ g_Renderer.GetWaterManager()->m_WaterHeight = h.ToFloat();
+
CMessageWaterChanged msg;
GetSimContext().GetComponentManager().BroadcastMessage(msg);
}