In Emil's Godot ocean, foam appears where waves bunch together and fades after they spread. He shares how he built the effect.
Emil took inspiration from the foam in
Sea of Thieves while building an ocean in Godot. He was still fairly new to shaders, but liked working through the math and seeing an idea actually work.
His first version used wave normals to put foam on steep sections. It looked good with some settings, but became less convincing when he changed the waves' direction or amplitude.
He had heard about the
Jacobian determinant in
The Technical Art of Sea of Thieves, then spent days learning what it measured. For his ocean, the useful question was whether a small patch of water gets squeezed as the wave moves sideways.
The wave displacements are stored in a texture. Emil samples nearby points along its U and V directions and looks at where they land after moving horizontally across X and Z. The Jacobian determinant measures the change in area between those points. Where the area shrinks, the shader adds foam.
The samples can be much closer together than the ocean mesh's vertices, so the foam can pick up smaller changes in the waves.
White patches still looked flat, so Emil gave the compressed areas a foam texture. He also made the foam fade after the compression eases, rather than disappear at once.
The waves already had fine noise that changed their height. Since the foam calculation only looked at horizontal movement, that noise did not affect it. Emil added a little of the same noise to the horizontal movement too, giving the foam smaller streaks.
Since sharing the foam, Emil has added refraction and depth fading to the ocean and published a separate tutorial on those effects.
You can see the tutorials, shader and original post here:
Want to learn more about shaders?