Convincing water needs two things layered together: geometry that actually rises and falls (the waves), and shading whose highlights shift with viewing angle (the reflection). This demo’s vertex shader blends three sin() waves at different frequencies and phases into a height (z), then recomputes each vertex’s normal by taking the cross product of two tangent vectors derived from that height function’s x/y derivatives — reuse the flat plane’s original normal, as in vertex-displacement, and the bumps read as flat no matter how much they move.
In the fragment shader, fresnel = pow(1 - dot(normal, viewDir), n) stays small when looking straight down (reads as seeing into the water) and climbs toward 1 at a grazing angle (reads as reflected sky) — that angle-dependent shift is what makes water look like water. Add a specular highlight from raising the angle between the half-vector (halfway between light and view direction) and the normal to a high power, and you get sunlight glinting off the ripples.
In production, the Water/Water2 addons provide a far more capable version with real normal-map textures and reflection/refraction render targets. This demo substitutes procedural sine waves because the site can’t load external images — the tradeoff is that the wave pattern visibly repeats.
When to use
Faking water quickly without external textures, or learning the principle before reaching for the fuller Water addon.