Открыть на GitHub

Введение в численное моделирование

Лабораторная работа: Визуализация водной поверхности в OpenGL

Задание

Требуется написмать программу, отображающую в реальном масштабе времени водную поверхность в качестве как можно более близком к фотореалистичному.

Исходные данные: Водная поверхность задается функцией высот $h(x,y;t)$ точек над неким нулевым уровнем в момент времени $t$, т.е. точки поверхности имеют координаты $(x,y,h(x,y;z))$. Координаты $(x,y)$ пробегают прямоугольную решетку,

\[x_K=2\frac{k}{N_x}-1,y_j=2\frac{j}{N_y}-1,\]

где $N_x$ и $N_y$ - число точек решетки по каждой из осей, диапазон изменения координат $-1\leq x,y,\leq 1$. Программа получает на вход массив значений высоты $h_{jk}=h(x_k,h_j;t)$ для каждого момента времени. Для тестирования кода можно предположить, что колебания поверхности образуются суммой плоских волн со случайными параметрами $A_n$ - амплитуда, $k_n$ - волновой вектор, $\omega$ - частота, $\phi$ - фаза:

\[h(x,y;t)=\sum_n A_n\cos(k_{n,x}x+k_{n,y}y+\omega t+\phi).\]

В следующей лабораторной мы будем генерировать высоты более реалистично, но для отрисовки будем использовать код из этой лабораторной.

Результатом выполнения программы должно быть анимированное изображение водной поверхности на экране. Время построения одного кадра не должно превосходить 0.1 секунды для решетки размера $100\times 100$. Качество изображения должно быть приближено к фотореалистическому.

Ход выполнения работы. Выполнение работы разбито на этапы, для минимального выполнения работы неообходимо выполнить 8 этапов. Для получения максимального числа баллов необходимо выполнить 11 этапов, бальная стоимость всех этапов одинакова.

1 этап, Python. Создать окно приложения, контекст OpenGL. Очистить фон и отрисовать одну точку.

2 этап, Python. Подготовить массив данных для отрисовки, обновлять массив по таймеру. Отрисовать точки решетки на водной поверхности. Сделать анимацию. Положение камеры считать фиксированным: камера смотрит на воду сверху, перпендикулярно поверхности.

3 этап, Python. Отрисовать отрезки, соединяющие соседние узлы решетки (wireframe). Убедиться в корректности изображения перспективы.

4 этап, Python. Построить триангуляцию поверхности, отрисовать треугольники. Реализовать вычисление цвета отдельных точек треугольинка. Отрисовать тепловую карту высот.

5 этап, Python. Вычислить нормали к водной поверхности. Реализовать затенение по Фонгу с одним направленным источником света (Солнце) и рассеянным светом.

6 этап, Python. Загрузить текстуру неба. Отрисовать отражение неба от водной поверхности.

7 этап, Python. Загрузить текстуру дна. Вычислить преломленные лучи, найти точки пересечения со дном и соответствующие координаты на текстуре. Отрисовать дно, как его видно сквозь водную поверхность. Дно считать плоским, расположенным параллельно спокойной водно поверхности.

8 этап, Python. Реализовать вращение камеры. Отрисовать сцену для произвольного положения камеры. Получить изображение солнечной дорожки.

9 этап, WebGL. Учесть изменение цвета воды с увеличением глубины.

10 этап, WebGL. Реализовать корректную отрисовку сцены для положения камеры под водой.

11 этап, WebGL. Реализовать отрисовку неба, использовать его как фон для водной глади. Согласовать изображение неба и его отражение.

12 этап, WebGL. Динамически вычислять и отрисовывать каустики в реальном масштабе времени.

13 этап. Не передавать нормали к поверхности, а рассчитывать их в OpenGL через положения вершин.

14 этап. Реализовать ночной режим с отрисовкой отражения звезд.

15 этап. Отрисовать сцену для неровного дна, форма которого задана массивом высот точек дна.

Рекомендуемые программные средства

Использование Python с библиотекой VisPy позволит вам избежать решение множества технических сложностей и сосредоточиться на сути работы. Также вам будет полезна библиотека для работы с многомерными массивами NumPy.

Литература

Книги

  1. OpenGL SuperBible. Если вы пользуйтесь VisPy, то вам потребуется четвертая редакция, описывающая OpenGL 2.1.

  2. 3D Computer Graphics: A Mathematical Introduction with OpenGL

  3. Real-Time Rendering

  4. Computer Graphics: Principles and Practice

Примеры кода

  1. Комментарии к примерам выполнения первых 5 этапов лабораторной, см. ссылки выше.

  2. Исходнинки примеров программ с использованием VisPy.