Это очень просто.
Вам просто нужно сделать 2D карту высот (2D массив высоты воды в этом конкретном месте). С помощью карты высот вы можете рассчитать (приблизить, интерполировать) нормаль в каждом месте в зависимости от ближайших точек высоты.
Затем вы выполняете «простую трассировку лучей». Вы «преломляете каждый луч» в зависимости от нормы, пересекаете его с плоскостью (снизу) и получаете цвет от текстуры в этом месте.
Практически: вы делаете треугольную сетку из карты высот и визуализируете эти треугольники. Вы можете отправлять нормали в Vertex Buffer или вычислять их в Vertex Shader. Трассировка лучей выполняется в Fragment Shader. Направление каждого луча может быть (0, 0, 1). Вы преломляете его по текущей нормали и масштабируете результат, поэтому координата Z равна глубине воды. Новые координаты X и Y являются текстурными координатами.
Чтобы сделать анимацию, просто обновите карту высот во времени.