Hey, everyone! As you have surely noticed, SEUS PTGI has thus far been hideous in underwater scenes. I figured it's quite time to change that (especially now that Minecraft 1.13 compatibility is here), so this is mostly what I've been focusing on for E8
In the past, I've just relied on a thick application of fog for underwater rendering, since I could never really get clear water looking right. Since I wanted to match vanilla Minecraft's (1.13+) underwater visibility this time, there was no more avoiding it, so I decided to do some research.
Watching videos of people diving in clear waters, I was amazed at just how much water absorbs longer wavelengths of light (giving anything but shallow, close-up surfaces a blue/cyan tint). I mean sure, I was aware of it before, but I definitely underestimated it. Previously I used hand-picked absorption values, but this time I've decided to use physically accurate values.
Here, you can see the effects of the physically-based light absorption in water.
And of course, what is an underwater scene without caustics? I experimented with several approaches, but with so little resources left to work with (since PTGI is so complex already), I couldn't use several shader stages with intermediate textures to render caustics dynamically like I have with previous versions of SEUS. Plus, if I came up with a really cheap method, it would allow for volumetric caustic light shafts (god rays) under water, which I really wanted.
So, I've decided to use a pre-rendered caustics animation texture for caustics. I wrote a custom tool to render this texture for me that ensures it tiles and loops seamlessly. I also made sure to use the same water height function so that the rendered caustics match the look of the surface of the water.
Caustics appear differently at different water depths, which I considered important enough to include as a feature as well. So, the rendered caustics texture has 4 separate layers (packed in RGBA channels) for varying depth ranges, from shallow to deep. Then, in the shader, I simply crossfade between these layers based on water depth.
To keep it relatively lightweight yet still crisp, the texture has a one second loop, is 60 frames per second, and tiles across a width of 2 blocks. Unfortunately, the tiling is definitely noticeable, but is less apparent when blending between the 4 depth layers.
Here, you can see the difference between only having one depth layer for caustics (top), and having four (bottom).
Now that caustics were in, it was time to do volumetric light shafts from caustics! This part was pretty easy to get working, since I've done stuff like this in the past (though, caustics never contributed before).
Without (top) and with (bottom) volumetric light shafts from caustics
This is all still a work-in-progress of course! Unfortunately, I had to use a feature of OptiFine that was introduced in 1.13 to get the caustics working, and it totally breaks in Minecraft 1.12.2. I'm not really sure what to do about this. Perhaps the developer of OptiFine can port this feature back for 1.12.2.
UPDATE: The developer of OptiFine has informed me that this feature and others will indeed be backported to 1.12.2.