Автор: Пользователь скрыл имя, 12 Декабря 2011 в 11:48, курсовая работа
Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются.
Санкт-Петербургский Государственный
Электротехнический
Университет
ФКТИ
Кафедра
МОЭВМ
Дисциплина
«Компьютерная графика»
Пояснительная записка
к
курсовой работе по
теме
"
Визуализация воды "
Санкт-Петербург
2008 г.
Постановка
и анализ задачи
Моделирование водных поверхностей является сложной, но интересной задачей. Здесь можно выделить такие подзадачи, как моделирование небольших водоемов (с видимыми границами), для которых характерны небольшие изменения поверхности, то есть небольшие колебания, а также интерференция колебаний от нескольких всплесков и отраженных колебаний от границ; большие водные поверхности: здесь рассматривают небольшие поверхностные колебания (как правило, в этом случае можно обойтись изменениями лишь текстуры или нескольких текстур поверхности (Bump Mapping и др., см. далее) не деформируя непосредственно саму поверхность), небольшие колебания: в этом случае поверхность разбивается на треугольники, но достаточно большого размера и над поверхностью производят небольшие колебания, которые соответствуют, например, небольшим волнам, большие колебания: этот большие волны, брызги и др., здесь происходят значительные деформации водных поверхностей, которые достаточно сложно физически описываются, поэтому большие волны практически никогда не визуализируются. Брызги можно визуализировать, например, используя массив частиц (маленьких плоскостей, ориентированных по нормали на наблюдателя), для которых устанавливаются начальные скорости, а дальнейший их полет происходит по гравитационному закону.
Моделирование
небольших колебаний и
Предположим, что водная поверхность представляет собой квадратную сетку размером NxN. Водная поверхность обладает связностью (в физическом смысле), то есть внешнее воздействие на какой-то один узел влечет также изменение, как минимум, в соседних узлах. Физически описать такое взаимодействие можно описать с достаточной степенью точности, если предположить, что соседние узла связаны между собой линейно-упругой пружиной.
Для каждого узла вводятся следующие характеристики:
mi - масса узла;
- декартовы координаты узла;
- скорость узла;
- ускорение узла;
- сумма всех сил, действующих на узел;
Выводить на экран такую поверхность можно следующим образом: для каждых четырех узлов: pij pi+1j pi+1j+1 pij+1 на экран выводятся 2 треугольника: pijpi+1jpij+1 и pij+1pi+1jpi+1j+1.
Выражение для силы пружины Sk, действующей на узел pi, следует из закона Гука:
(1) |
где , - длина покоя и текущая длина пружины соответственно; - единичный вектор в направлении пружины.
Или, если расписать:
(1)' |
Уравнения движения всей такой системы легко выводятся из общего курса физики:
- масса узла;
- сумма сил пружин, прикрепленных к узлу;
- сумма внешних сил, приложенных к узлу;
- коэффициент демпфирования, характеризующий
сопротивление среды, в которой движется
узел.
Неплохие результаты дают следующие характеристики системы:
Шаг сетки,
H |
Масса узла,
mij |
Коэффициент упругости,
ск |
Демпфирование, | Шаг интегрирования, |
1.0 | 4.0 | 7.0 | 0.05 | 0.4 |
Управлять возмущением такой системы достаточно просто: необходимо лишь изменять вектор внешних сил на некоторые узлы решетки (то есть непосредственно осуществлять внешнее воздействие). Достаточно интересным (может быть, даже более более красивым с точки зрения графики) является подход, когда мы изменяем непосредственно координаты и скорости в некоторых узлах, то есть сразу указываем результат воздействия. Также возможны гибридные подходы этих двух методов.
Задавая различные условия на узлах мы можем моделировать различные водные поверхности с различными граничными и поверхностными условиями. Например, если мы хотим моделировать бассейн или некоторую другую емкость с водой, то необходимо разрешить лишь вертикальные перемещения граничных узлов, то есть положить их горизонтальные перемещения равными нулю. Также, здесь будет хорошо заметна интерференция волн и отражение волн от границы. Если нам необходимо получить небольшой водоем, для которого характерна неизменная береговая линия, то необходимо полностью запретить перемещения граничных узлов.
Если запретить горизонтальные перемещения на все узлы, то это подчеркнет эффект прохождения волн друг сквозь друга. Также если запретить перемещения некоторых внутренних узлов, то можно смоделировать, например, островок, от которого волны будут также еще и отражаться. В данном случае узлы должны повторять контур островка.
Чтобы задать точечное возмущение можно воспользоваться следующими способами: изменить скорость в данном узле и в некоторой его окрестности, или сделать тоже самое с координатами. Характер возмущения описывается с помощью гауссовского распределения с некоторым радиусом. Также, чтобы данный процесс не замедлял основной цикл программы, данные значения просчитываются заранее, заносятся в массив, а затем во время работы программы прибавляются к текущим координатам или скоростям узлов.
Вода является очень хорошим отражателем, и реалистичность отображаемой водной поверхности существенно зависит от реализации отражения объектов, находящихся над водой и у поверхности воды. Но, так как вода является динамически изменяемым объектом (в данной задаче), то отражения тоже должны, по возможности, повторять форму движения водной поверхности.
Сложность моделирования отражений состоит в том, что отражения являются зависимыми от вектора наблюдения и положения наблюдателя: если наблюдатель сдвинется или повернется, то отражения изменятся. То есть при статическом положении наблюдателя можно заранее просчитать отражение, но если существует возможность изменения положения наблюдателя или вектора наблюдения, то отражения заранее просчитаны быть не могут, поскольку дискретность изменения положения наблюдателя и вектора наблюдения должна быть произвольной.
Обычно, водные поверхности моделируются на открытом пространстве. И здесь необходимо учитывать эффект отражения неба от поверхности воды. Для этого берется текстура неба и накладывается на поверхность воды, но координаты текстуры не изменяются в зависимости от изменения водной поверхности. В OpenGL это достигается следующим образом:
Вода также является в достаточно прозрачной. Но коэффициент преломления воды не совпадает с аналогичным коэффициента для воздуха, отсюда, объекты выглядят в воде искаженными. Это также необходимо учитывать при моделировании.
Для дна необходимо
подобрать соответствующую
Для водных поверхностей также характерны каустики - эффект прохождения света сквозь водную поверхность, подверженную колебаниям. В этом случае на дне возникают некоторые световые пятна, которые также можно визуализировать. Для этого над поверхностью дна делается еще один полупрозрачный слой из плоскостей, с наложенными на них текстурами каустиков. Также нельзя забывать, что так как поверхность динамична, то и текстура с каустиками должна динамически изменяться. Обычно поступают следующим образом: берется некий заранее просчитанный набор текстур с каустиками (10-15) и попеременно сменяют одну другой в соответствие с изменением соответствующей водной поверхности, в конце данный процесс зацикливают.
Bump mapping используется для передачи неровностей поверхности. Реально в природе не существует абсолютно плоских объектов, и большинство объектов, которые мы видим в реальной жизни обладают различными шероховатостями. В моделировании при передаче общей формы объекта мы разбиваем его на полигоны. Но для передачи таких "мелких" свойств, как неровности необходимо модифицировать текстуру объекта или накладывать на одну плоскость несколько текстур (делать несколько полупрозрачных плоскостей, параллельных данной, но находящихся "немного выше" нее или использовать мультитекстурирование, входящие в расширение OpenGL).
Условно говоря, нам необходимо лишь менять направление нормали в каждой точке плоскости для передачи неровностей, и это возможно, используя расширения OpenGL. Но мы будем рассматривать лишь стандарт OpenGL. Здесь подобного можно добиться, если выводить вместо каждой плоскости, для которой мы хотим произвести bump mapping, три плоскости, параллельные друг другу и находящиеся на небольшом отдалении друг от друга (чтобы визуально этого было не заметно).
Здесь используются две текстуры: исходная текстура воды (как уже отмечалось, в этой текстуре также можно передать отражение неба, то есть исходная текстура, есть комбинация текстур непосредственно воды и зеркально отраженной текстуры неба, а так как небо, будем считать, статично, то такая текстура создается до работы приложения и в течении всего времени работы не меняется) и текстура, отражающая неровности поверхности (черно белая), которая условно говоря, задает карту высот (будем называть ее картой поверхности).
Сначала мы загружаем исходную текстуру воды (1), а из карты поверхности создаем две текстуры: первая (2)- точно такая же, но в каждой точке значение делиться на два (так как текстура черно-белая, то будем считать что мы уменьшаем яркость в два раза); вторая (3)- это инвертированная (по значению яркости) карта поверхности, для которой также значение яркости делится на 2, то есть здесь: <source_pixel> = (255 - <map_pixel>) / 2.
Вывод на экран
происходит в следующей
Перед выводом
следующей плоскости
Сама плоскость выводится выводится на том же месте, что и предыдущая, но "чуть-чуть" приподнята относительно вектора наблюдения (чтобы не было перекрытий) и наложенной текстурой (3). Для нее изменяются координаты текстурами, чтобы отобразить эффект неровности поверхности. Пересчет текстурных координат происходит относительно вектора наблюдения. То есть вызывается команда glTexCoord2f(old_tex_x + tex_dx, old_tex_y + tex_dy), tex_dx и tex_dy берутся при подсчете вектора свига: tex_d = {tex_dx, tex_dy, tex_dz}. Вычисляется он следующим образом: tex_d = man_pos - plane_center, где man_pos - вектор координат месторасположения наблюдателя, plane_center - центральная точка текущей плоскости (вместо нее, для ускорения, можно взять одну из вершин рассматриваемой плоскости). Далее tex_d нормируется (представляется в единичный вектор) и далее все координаты домножаются на некоторое небольшое число (в зависимости от глобальной метрики сцены), которое и будет характеризовать расхождение, а значит и высоту шероховатости. Если указать это число достаточно большим, то будут видны просто две плоскости и никакого эффекта шероховатости создаваться не будет. В этом особенность этого метода: можно передать лишь небольшие ("невысокие") неровности, для других необходимо производить дополнительную триангуляцию.