Chilling undersea

Part of a WIP fishing game I’m working on (so far it’s just a handful of playgrounds with various needed features) I need cute underwater environments, since most of the game happens underwater (player will be swimming to collect fish).

So I need nice water in the game. Thankfully @Evgeni_Popov has done all of the hard work already for creating gorgeous FFT ocean in Babylon. It’s actually one of the first demos I saw of BabylonJS when looking for a WebGPU compatible engine! So thanks for that project, very inspiring and well organized to take apart :slight_smile: :heart:

Anyway, since in my game we will be underwater a lot, I needed to flip things upside down a little, thinking how light would travel from the underside of water. There are lots of tricks involved like Snell’s window, wavelength falloff in water, and scattering of light. Some of them are simple to fake, others not so much. I learned a lot so far along the way!

Here’s my WIP for now! It includes:

  • volumetric god rays
  • Snell’s window (turn up FOV on camera and look upwards to really see this),
  • reacting automatically to lighting changes (change the Inclination and Azimuth of the sun for example)
  • ‘sort of’ physically based light falloff and ‘fog’
  • caustics on underwater surfaces that are sampled with a scatter radius proportional to the depth (so deeper caustics look blurrier)

Some shots:

A lot of things can be improved of course, especially around the underside of the water mesh itself.
I had trouble with that the Custom PBR of the original ocean material uses GLSL but my material plugin uses WGSL, because I frequently need to use the same logic in both, so thus far I just ChatGPT-translated some chunks between.
The material plugin also needs to pull in more uniforms from the ocean shaders, for example to more accurately (than y < 0) understand if a fragment is underwater.

But it already looks good enough to share I think. Enjoy!

14 Likes

Some tips from the omniscient chatbot in the name of reality… :slight_smile:

When viewed underwater, the water surface often appears silvery or reflective in daylight, as the light is reflected by the surface. Depending on the viewing angle and water conditions, it can also have a bluish or greenish shimmer.

Shallow angle: If you look up at a shallow angle, you can see a bright, almost white or silver reflection.
Steep angle: If you look up vertically, the surface may appear slightly bluish as the light from the sky passes through the water.
Rippled water: Waves or movement can distort the surface, causing the light to be refracted and the colors to vary.
There is also the so-called Snell window, a circular area through which you can see the sky directly from underwater - the water surface appears transparent and shows the sky in its natural color.

1 Like

@Evgeni_Popov is there a way to extract the (transpiled) WGSL version of your GLSL Ocean material’s custom PBR shader? I’d like to be able to share code between my material plugin for rendering the underwater surfaces, which use WGSL, so I can bridge the two materials better visually.

You can set BABYLON.WebGPUTintWASM.ShowWGSLShaderCode = true;. The WGSL shader code will be dumped to the console. You will have to do a bit of searching, however, as the Ocean demo generates quite a lot of code:

1 Like